// This program defines and exercises a robot that goes on "treasure hunts."
// Specifically, the robot follows clues in the form of tile colors that tell
// it where to go, as follows:
//   White tiles: move one tile forward
//   Blue tiles: Turn left and move one tile forward
//   Green Tiles: Turn right and move one tile forward
//   Red tiles: Pursue further treasure hunts to the left and right
//   Yellow tiles: Stop, you're at the end of a path.

// History:
//
//   September 2003 -- Written by Doug Baldwin, based on a long history
//     of similar exercises in other languages.




import java.io.*;
import java.awt.Color;
import geneseo.cs.sc.Robot;
import geneseo.cs.sc.RobotRoom;




class TreasureRobot extends Robot {




    // Initialize a treasure-hunting robot with its position, heading, and room.
    // This simply passes its parameters on to the analogous constructor for Robots.

    public TreasureRobot( int column, int row, int heading, RobotRoom room ) {
        super( column, row, heading, room );
    }




    // Carry out a treasure hunt. This is based on the general recursive insight
    // that to do a treasure hunt, you follow the first clue and then do a
    // treasure hunt that starts with the next clue you find. See the comments at
    // the top of this file for descriptions of the clues and their meanings.
    // Note that red tiles mark the end of (part of) a treasure hunt, and so
    // are base cases for the recursion. Green tiles generate two recursive hunts,
    // one to the left and one to the right.
    //   Preconditions: The robot is standing on the first clue, and facing into
    // the treasure hunt.
    //   Postconditions: The robot is standing back on the first clue, facing out
    // of the treasure hunt. The robot has visited all the yellow tiles in the
    // treasure hunt.
    //
    // Correctness proof, by strong induction on the number of tiles in the treasure
    // hunt:
    //
    // Base case: The treasure hunt contains only one tile. Since the only tiles that
    // don't imply that a treasure hunt contains more tiles adjacent to the first
    // are yellow, this tile must be yellow. The algorithm's "if ( tileColor == Color.yellow )"
    // test therefore succeeds, and the algorithm turns the robot around. The robot is
    // still on the first (and only) clue, but facing out of the treasure hunt. The robot
    // has visited all yellow tiles in the treasure hunt (namely the one tile it started on).
    //
    // Induction hypothesis: Assume that for any treasure hunt of fewer than k tiles
    // (k > 1), "hunt" leaves the robot standing back on the first clue, facing out
    // of the treasure hunt, and having visited all the yellow tiles in the treasure hunt.
    //
    // Show that for any treasure hunt of k tiles, "hunt" leaves the robot standing back
    // on the first clue, facing out of the treasure hunt, and having visited all the yellow
    // tiles in the treasure hunt. There are four ways the k-tile treasure hunt can begin:
    // with a white tile, with a blue tile, with a green tile, or with a red tile.
    //   White tile: The "if ( tileColor == Color.white )" test succeeds, so the robot
    // moves forward, landing on the second tile of the treasure hunt (henceforth called
    // "the second tile"). There are k-1 tiles left in the treasure hunt that begins on
    // the second tile, and the robot is facing into that treasure hunt. Thus the recursive
    // message causes the robot to visit all yellow tiles in that treasure hunt (and so
    // in the k-tile one), come back to the second tile, and face out, towards the first
    // tile. The final move therefore returns the robot to the first tile, and leaves it
    // facing out of the original treasure hunt.
    //   Blue tile: The "if ( tileColor == Color.blue )" test succeeds, so the robot
    // turns left and moves forward, landing on the second tile of the treasure hunt
    // (henceforth called "the second tile"). There are k-1 tiles left in the treasure
    // hunt that begins on the second tile, and the robot is facing into that treasure hunt.
    // Thus the recursive message causes the robot to visit all yellow tiles in that treasure
    // hunt (and so in the k-tile one), come back to the second tile, and face back towards
    // the first tile. The subsequent move therefore returns the robot to the first tile, and
    // the turnRight leaves it facing out of the original treasure hunt.
    //   Green tile: The "if ( tileColor == Color.green )" test succeeds, so the robot
    // turns right and moves forward, landing on the second tile of the treasure hunt
    // (henceforth called "the second tile"). There are k-1 tiles left in the treasure
    // hunt that begins on the second tile, and the robot is facing into that treasure hunt.
    // Thus the recursive message causes the robot to visit all yellow tiles in that treasure
    // hunt (and so in the k-tile one), come back to the second tile, and face back towards
    // the first tile. The subsequent move therefore returns the robot to the first tile, and
    // the turnLeft leaves it facing out of the original treasure hunt.
    //   Red tile: The "if ( tileColor == Color.red )" test succeeds, so the robot
    // turns left and moves forward, landing on the first tile of the treasure hunt
    // to the left of the red tile (henceforth called "the left tile"). There are fewer than
    // k tiles in the treasure hunt that begins on the left tile, and the robot is facing into
    // that treasure hunt. Thus the recursive message causes the robot to visit all yellow
    // tiles in the left-hand treasure hunt, come back to the left tile, and face back towards
    // the first tile. The next two move messages move the robot to the first tile
    // of the treasure hunt to the right of the red tile (henceforth called "the right tile").
    // There are fewer than k tiles in the treasure hunt that begins on the right tile, and
    // the robot is facing into that treasure hunt. Thus the second recursive message causes
    // the robot to visit all yellow tiles in the right-hand treasure hunt. Between these
    // yellow tiles and those in the left-hand treasure hunt, the robot has visited all yellow
    // tiles in the original treasure hunt. The recursive message also brings the robot
    // back to the right tile, and leaves it facing back towards the first tile. The final
    // move and turnLeft leave it on that first tile, facing out of the original treasure hunt.
    
    public void hunt() {

        Color tileColor = this.colorOfTile();

        if ( tileColor == Color.white ) {		// Next treasure hunt is in front of the robot

            this.move();
            this.hunt();
            this.move();
        }
        else if ( tileColor == Color.blue ) {		// Next treasure hunt is to the left
            
            this.turnLeft();
            this.move();
            this.hunt();
            this.move();
            this.turnRight();
        }
        else if ( tileColor == Color.green ) {		// Next treasure hunt is to the right

            this.turnRight();
            this.move();
            this.hunt();
            this.move();
            this.turnLeft();
        }
        else if ( tileColor == Color.red ) {		// Treasure hunts to both left and right

            this.turnLeft();
            this.move();
            this.hunt();
            this.move();
            this.move();
            this.hunt();
            this.move();
            this.turnLeft();
        }
        else if ( tileColor == Color.yellow ) {		// End of path, just turn around

            this.turnLeft();
            this.turnLeft();
        }
    }




    // The main method reads a description of a treasure hunt from a file, and creates
    // a room from that description. Then it creates a robot and sets it hunting in
    // that room.
        
    public static void main( String args[] ) {


        // Create the room:

        final String roomDirectory = "../";
        final String roomFile = "SimpleHunt.txt";
        String roomDescription = "17 17";

        try {
            BufferedReader in = new BufferedReader( new FileReader( roomDirectory + roomFile ) );
            roomDescription = in.readLine();
            in.close();
        }
        catch ( Exception err ) {
            System.err.println( "Error reading room description:" );
            System.err.println( "\t" + err );
        }

        RobotRoom treasureRoom = new RobotRoom( roomDescription );


        // Put a robot in the room, and have it do the treasure hunt:

        TreasureRobot hunter = new TreasureRobot( 8, 15, Robot.NORTH, treasureRoom );

        hunter.hunt();
    }
}