// This program defines and exercises a kind of robot that does various
// things with colors. Specifically, these robots provide the following
// to clients:
//
//   o A parameterless constructor, which initializes a coloring robot
//       in a default place in a default room.
//
//   o A constructor that takes a robot's column and row coordinates,
//       orientation, and room as parameters, and initializes the
//       robot accordingly.
//
//   o diagonal, a message that causes a robot to draw a diagonal blue
//       line n steps long, where n is the parameter to the message.
//     Preconditions: The robot is standing at the lower right end of
//       the line, facing up (i.e., so that the line will extend forward
//       and left from the robot's position).
//     Postconditions: The robot is standing one tile above and to the
//       right of the last tile in the line, facing up.
//
//   o countRed, a parameterless message that makes a robot move forward
//       until it reaches a wall, and that returns the number of red tiles
//       the robot encounters on its way (including the tile the robot
//       started on).
//
//   o stripedLine, a message that causes a robot to draw a striped line
//       n tiles long, where n is a parameter to the message. The resulting
//       line is "striped" in the sense that the odd-numbered tiles (where
//       the first tile painted is tile number 1) are blue, and the
//       even-numbered tiles are yellow.
//     Preconditions: The robot is standing where the first tile of the
//       line should be, facing in the direction the line should grow.
//     Postconditions: The robot is standing one tile after the end of
//       the line.
//
//   o colorfulLine, a message with an integer parameter, n, that makes
//       a robot draw a line consisting of n magenta tiles followed by
//       1 orange tile followed by n light blue tiles. This message has
//       no return value.
//     Preconditions: The robot is standing where the first magenta tile
//       should be, facing in the direction the line should grow. There
//       are no obstructions on the 2n+1 tiles in front of the robot.
//     Postconditions: The robot is standing on the last tile of the
//       line, facing in its original direction.

// History:
//
//   February 2004 -- Created by Doug Baldwin.




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




class ColorRobot extends Robot {




	// The constructors for coloring robots. Both simply pass their
	// parameters on to analogous constructors for regular robots.
	
	public ColorRobot() {
		super();
	}
	
	
	public ColorRobot( int col, int row, int heading, RobotRoom room ) {
		super( col, row, heading, room );
	}
	
	
	
	
	// The diagonal method. This is based on the recursive insight that
	// a diagonal line of 0 steps is nothing, while a diagonal line
	// of n > 0 steps is a blue tile with another diagonal line of n-1
	// steps above and to its left.
	
	public void diagonal( int n ) {
	
		if ( n > 0 ) {
		
			this.paint( Color.blue );
			this.move();
			this.turnLeft();
			this.move();
			this.turnRight();
			this.diagonal( n-1 );
		}
	}
	
	
	
	
	// The countRed method. This is based on the recursive insight
	// that if a robot is at a wall, then the number of red tiles
	// between it and that wall is either 1 or 0, depending on whether
	// the robot is standing on a red tile or not. If the robot is
	// not at a wall, then the number of red tiles is the number between
	// the next tile and the wall, plus 1 or 0 depending on whether
	// the initial tile is red.
	
	public int countRed() {
	
		if ( this.okToMove() ) {
		
			if ( this.colorOfTile() == Color.red ) {
				this.move();
				return 1 + this.countRed();
			}
			else {
				this.move();
				return this.countRed();
			}
		}
		else {				// Robot is at the wall
		
			if ( this.colorOfTile() == Color.red ) {
				return 1;
			}
			else {
				return 0;
			}
		}
	}
			
			
	
	
	// The stripedLine method. This algorithm is based on the
	// recursive insight that a line of 0 tiles is nothing, and
	// a line of 1 tile is a single blue tile. A line of n > 1 tiles
	// consists of a blue tile, a yellow one, and then a line of
	// n-2 tiles.
	
	public void stripedLine( int n ) {
	
		if ( n > 1 ) {
		
			this.paint( Color.blue );
			this.move();
			this.paint( Color.yellow );
			this.move();
			this.stripedLine( n-2 );
		}
		else if ( n == 1 ) {
		
			this.paint( Color.blue );
			this.move();
		}
	}




	// The colorfulLine method draws a line consisting of n magenta tiles,
	// 1 orange one, and n cyan tiles, in that order. The algorithm is
	// based on the recursive insight that if n = 0, all that's needed
	// is the one orange tile. A colorful line of n > 0 tiles consists
	// of a magenta tile followed by a colorful line of n-1 tiles followed
	// by a cyan tile.
	
	public void colorfulLine( int n ) {
	
		if ( n > 0 ) {
		
			this.paint( Color.magenta );
			this.move();
			this.colorfulLine( n-1 );
			this.move();
			this.paint( Color.cyan );
		}
		else {
			this.paint( Color.orange );
		}
	}
			



	// The main method creates some coloring robots and puts them through
	// their paces.

	public static void main( String[] args ) {


		// Test some diagonal lines:
		
		RobotRoom diagonalRoom = new RobotRoom();		
		ColorRobot diagonalMaker = new ColorRobot( 9, 9, Robot.NORTH, diagonalRoom );
		ColorRobot noDiagonal = new ColorRobot( 5, 9, Robot.NORTH, diagonalRoom );		
		diagonalMaker.diagonal( 4 );
		noDiagonal.diagonal( 0 );
		
		
		// Test counting red tiles. The tests include a case where
		// there are no red tiles, cases where the first tile is and
		// isn't red, and cases where the last tile is and isn't red:
		
		RobotRoom redRoom = new RobotRoom( "6 9  2 5 R  3 7 R  3 4 R  4 1 R  4 5 R  4 6 R" );
												 
		ColorRobot noRed = new ColorRobot( 1, 7, Robot.NORTH, redRoom );
		ColorRobot startWhite = new ColorRobot( 2, 7, Robot.NORTH, redRoom );
		ColorRobot startRed = new ColorRobot( 3, 7, Robot.NORTH, redRoom );
		ColorRobot endRed = new ColorRobot( 4, 7, Robot.NORTH, redRoom );
		
		System.out.println( "Red tile counts (should be 0, 1, 2, and 3):" );
		System.out.println( "\t" + noRed.countRed() );
		System.out.println( "\t" + startWhite.countRed() );
		System.out.println( "\t" + startRed.countRed() );
		System.out.println( "\t" + endRed.countRed() );
		
		
		// Test some striped lines. The tests include even- and odd-length
		// lines, and both of the algorithm's base cases (lengths of 0 and 1):
		
		RobotRoom stripeRoom = new RobotRoom();
		
		ColorRobot evenStripe = new ColorRobot( 2, 9, Robot.NORTH, stripeRoom );
		ColorRobot oddStripes = new ColorRobot( 4, 9, Robot.NORTH, stripeRoom );
		ColorRobot noStripe = new ColorRobot( 6, 9, Robot.NORTH, stripeRoom );
		ColorRobot oneStripe = new ColorRobot( 8, 9, Robot.NORTH, stripeRoom );
		evenStripe.stripedLine( 4 );
		oddStripes.stripedLine( 5 );
		noStripe.stripedLine( 0 );
		oneStripe.stripedLine( 1 );
		

		// Test some colorful lines:
		
		RobotRoom colorfulRoom = new RobotRoom();
		
		ColorRobot colorful = new ColorRobot( 3, 9, Robot.NORTH, colorfulRoom );
		ColorRobot uncolorful = new ColorRobot( 7, 9, Robot.NORTH, colorfulRoom );		
		colorful.colorfulLine( 4 );
		uncolorful.colorfulLine( 0 );
	}
	
}