// This program defines and demonstrates a subclass of the Science // of Computing robots that provides ways of drawing various figures. // Unfortunately, the drawing methods contain bugs! Students are supposed // to locate and correct these bugs. // // The features provided to clients, and their intended behaviors, // are as follows: // // o A parameterless constructor, which initializes a buggy robot // with a default position and orientation in a default room. // // o A constructor that takes horizontal and vertical tile coordinates, // an orientation, and a room as its parameters, and initializes // a buggy robot with that position and orientation in that room. // // o plusSign, a parameterless message that causes a robot to draw // a red "plus" sign against a yellow background. The background // is a 5-by-5 tile area, the "plus" is a red cross through the // middle row and column of this area. This message has no // return value. // Preconditions: The robot is standing on the upper left tile of // the background region, facing to the right. There are no obstructions // in the 5-by-5 tile area that the figure will occupy. // Postconditions: The robot is standing on the lower right tile // of the figure (which looks as described above). // // o pointyShape, a message that takes an integer, n, as its only // parameter, and that draws a pair of blue lines, n tiles long, with // a one-tile gap between them. One tile beyond the end of the // lines, there is a single blue tile in the gap, so that the // overall shape looks something like this: // // ******* // * // ******* // // This message has no return value. // Preconditions: The robot is standing on what will be the first // tile (furthest from the point) of the upper or lefthand line, // facing in the direction that line should grow. There are no // obstructions on the tiles that will be colored, or the tiles // adjacent to the point. n >= 0. // Postconditions: The robot is standing on the tile furthest from // the point on the lower or righthand line, facing away from // the point. // // o tree, a message that causes a robot to draw a green "robot tree" // of size n, where n is an integer parameter to the message. A // "robot tree" is a shape defined as follows: // - A robot tree of size 1 is a single green tile. // - A robot tree of size n > 1 is a green line n tiles long, // with robot trees of size floor(n/2) touching and perpendicular to // one end (the "fork" end). // This message has no return value. // Preconditions: The robot is standing at the base of the future // trunk (i.e., the end of the trunk opposite the fork), facing // towards the fork. There are no obstructions on the tiles that // will be covered by or adjacent to the tree. n >= 1. // Postconditions: The robot is standing at the base of the trunk, // facing away from the fork. // // o freeSpace, a parameterless message that returns the total number of // unobstructed tiles reachable by a robot in its row or column. // Preconditions: None. // Postconditions: The returned value is the number of tiles the robot // can reach by moving forward or backward from its initial tile. // This count includes the initial tile. The robot is standing on // its original tile, facing in its original direction. // History: // March 2004 -- Created by Doug Baldwin. // Copyright (C) 2004. Charles River Media. import java.awt.Color; import geneseo.cs.sc.Robot; import geneseo.cs.sc.RobotRoom; class BuggyRobot extends Robot { // The constructors: public BuggyRobot() { super(); } public BuggyRobot( int col, int row, int orientation, RobotRoom room ) { super( col, row, orientation, room ); } // The plusSign method. This works by invoking some helper methods, // namely one that draws a horizontal strip of background with a // piece of the "plus" in the middle, and one that draws the horizontal // bar of the "plus". In between each of these strips, the robot uses // other helper methods to turn around and move to the next strip. public void plusSign() { this.drawBackgroundStrip(); // The top strip of background this.turnAndMoveRight(); this.drawBackgroundStrip(); // The second strip of background this.turnAndMoveRight(); this.drawLine( 5, Color.red ); // The bar of the plus this.turnAndMoveRight(); this.drawBackgroundStrip(); // The 2nd-from-bottom background strip this.turnAndMoveLeft(); this.drawBackgroundStrip(); // The bottom strip of background } // The pointyShape method. This is based on the recursive insight that // a pointy shape with 0-tile sides is just the central blue tile, while // a pointy shape with n>0 tiles per side is a blue tile, a pointy // shape of n-1 tiles per side, and a final blue tile. public void pointyShape( int n ) { if ( n > 0 ) { this.paint( Color.blue ); this.move(); this.pointyShape( n - 1 ); this.move(); this.paint( Color.blue ); } else { this.turnRight(); this.move(); this.paint( Color.blue ); this.turnRight(); this.move(); } } // The tree method. This is simply a translation of the definition of // "robot tree" into Java. Note that this uses a helper method to draw // the tree's trunk. public void tree( int n ) { if ( n > 1 ) { // Draw the trunk: this.drawLine( n, Color.green ); // Draw the left branch: this.turnLeft(); this.move(); this.tree( n / 2 ); // Draw the right branch: this.move(); this.tree( n / 2 ); // Return to the base of the trunk, per the postcondition: this.move(); this.turnLeft(); this.drawLine( n, Color.green ); } else { // Draw the one tile tree: this.drawLine( 1, Color.green ); // Turn around to face away from the "fork" end, per the postcondition: this.turnLeft(); this.turnLeft(); } } // The freeSpace method. This uses a helper method to count the empty tiles in // front of the robot and behind the robot, then uses those results to compute // the final total. public int freeSpace() { int spaceAhead = this.countToWall(); int spaceBehind = this.countToWall(); return spaceAhead + spaceBehind; } // Helper methods for the others: // drawBackgroundStrip draws a 5-tile strip consisting of 2 yellow // tiles, 1 red, and 2 more yellow. Preconditions are that the // robot is standing on the first tile of the strip, facing in // the direction the strip should grow, and there are no obstacles // on the 4 tiles in front of the robot. Postconditions are that // the robot is standing on the last tile of the strip, facing in // its original direction. // drawLine draws a line n tiles long, where n is a parameter to the // method. The second parameter is the color the line should have. // Preconditions are that the robot is standing on what should be // the first tile of the line, facing along the future line, and // there are no obstacles on the n-1 tiles in front of the robot. // Postconditions are that the robot is standing on the last tile // of the line, facing in its original direction. // turnAndMoveLeft turns a robot 180 degrees, and makes it move one // tile to its left in the process. Preconditions are that the tile // to the robot's left is unobstructed. Postconditions are that the // robot is standing on the tile to the left of its original position, // facing in the opposite of its original direction. // turnAndMoveRight turns a robot 180 degrees, and makes it move one // tile to its right in the process. Preconditions are that the tile // to the robot's right is unobstructed. Postconditions are that the // robot is standing on the tile to the right of its original position, // facing in the opposite of its original direction. // countToWall counts the number of tiles between a robot and the nearest // obstacle that robot is facing, not counting the tile the robot starts // on. There are no preconditions for this method. Postconditions are that // the robot is standing on its original tile, facing in the opposite of // its original direction. private void drawBackgroundStrip() { this.paint( Color.yellow ); this.move(); this.paint( Color.yellow ); this.move(); this.paint( Color.red ); this.move(); this.paint( Color.yellow ); this.move(); this.paint( Color.yellow ); } private void turnAndMoveLeft() { this.turnLeft(); this.move(); this.turnLeft(); } private void turnAndMoveRight() { this.turnRight(); this.move(); this.turnRight(); } private void drawLine( int n, Color c ) { if ( n > 1 ) { this.paint( c ); this.move(); this.drawLine( n - 1, c ); } else { this.paint( c ); } } private int countToWall() { if ( this.okToMove() ) { this.move(); int distance = this.countToWall(); this.move(); return 1 + distance; } else { this.turnLeft(); this.turnLeft(); return 0; } } // The main method creates and exercises some buggy robots. public static void main( String[] args ) { // Exercise the plusSign message: RobotRoom plusRoom = new RobotRoom(); BuggyRobot plus = new BuggyRobot( 2, 2, Robot.EAST, plusRoom ); plus.plusSign(); // Exercise the pointyShape message: RobotRoom pointRoom = new RobotRoom( "11 7" ); BuggyRobot nullPoint = new BuggyRobot( 2, 5, Robot.NORTH, pointRoom ); BuggyRobot bigPoint = new BuggyRobot( 6, 5, Robot.NORTH, pointRoom ); nullPoint.pointyShape( 0 ); bigPoint.pointyShape( 3 ); // Exercise the tree message: RobotRoom treeRoom = new RobotRoom( "19 11" ); BuggyRobot smallTree = new BuggyRobot( 2, 9, Robot.NORTH, treeRoom ); BuggyRobot simpleTree = new BuggyRobot( 6, 9, Robot.NORTH, treeRoom ); BuggyRobot oddTree = new BuggyRobot( 13, 9, Robot.NORTH, treeRoom ); smallTree.tree( 1 ); simpleTree.tree( 4 ); oddTree.tree( 7 ); RobotRoom bigTreeRoom = new RobotRoom( "15 13" ); BuggyRobot bigTree = new BuggyRobot( 7, 11, Robot.NORTH, bigTreeRoom ); bigTree.tree( 8 ); // Exercise the freeSpace message: RobotRoom spaceRoom = new RobotRoom( "6 7 1 2 * 2 4 * 3 1 *" ); BuggyRobot noSpace = new BuggyRobot( 1, 1, Robot.NORTH, spaceRoom ); BuggyRobot frontSpace = new BuggyRobot( 2, 3, Robot.NORTH, spaceRoom ); BuggyRobot backSpace = new BuggyRobot( 3, 2, Robot.NORTH, spaceRoom ); BuggyRobot muchSpace = new BuggyRobot( 4, 3, Robot.NORTH, spaceRoom ); System.out.println( "no-space robot has " + noSpace.freeSpace() + " tiles." ); System.out.println( "front-space robot has " + frontSpace.freeSpace() + " tiles." ); System.out.println( "back-space robot has " + backSpace.freeSpace() + " tiles." ); System.out.println( "much-space robot has " + muchSpace.freeSpace() + " tiles." ); } }