
/**
 * A Robot that escapes from a maze with the help of clues left by a friend.
 * The robot moves forward, unless otherwise directed by a beeper, or blocked.
 * The robot is guaranteed to be able to escape in exactly 20 moves.
 * @author Russell C. Bjork 
 * @version January 9, 2006
 */
import kareltherobot.*;

public class AssistedEscaperRobot extends Robot
{
    /** Constructor
     *
     *  @param street the starting street for this robot
     *  @param avenue the starting avenue for this robot
     *  @param direction the direction this robot is initially facing
     *  @param beepers the number of beepers this robot has initially
     */
    public AssistedEscaperRobot(int street, int avenue, Direction direction, int beepers)
    {
        super(street, avenue, direction, beepers);
    }

    /** Escape from the maze
     */
    public void escape()
    {
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
        advanceOneBlock();
    }
    
    /** Advance one block - turning left if necessary before doing so
     */
    public void advanceOneBlock()
    { 
        // Decide whether to turn

        if (frontIsClear())
        {       
            // A single beeper signals turn left; two beeper signal turn right;
            // no beeper signals no turn
            
            if (nextToABeeper())
            {
                pickBeeper();
                if (nextToABeeper())
                {
                    pickBeeper();
                    turnRight();
                }
                else
                    turnLeft();
            }
              
            // Don't turn at all if no beepers
        }
          
        else
        {   
            // Front is blocked so has to turn.  If left is also blocked,
            // must turn right
            
            if (! leftIsClear())
            
                turnRight();

            else
            {
                // Left turn is an option - but not necessarily the right
                // thing to do. A single beeper signals turn right instead; 
                // no beeper signals turn left

                if (nextToABeeper())
                {
                    pickBeeper();
                    turnRight();
                }
                else
                    turnLeft();
            }
        }
                    
        // Now we can move
            
        move();
    }

    /** Test to see whether the robot's left is clear, without changing its
     *  orientation or position.  To do this, it must turn left, see if its
     *  front is clear, and then turn right again.
     *  
     *  @return true if the robot's left side is clear
     */
    public boolean leftIsClear()
    {
        turnLeft();
        if (frontIsClear())
        {
            turnRight();
            return true;
        }
        else
        {
            turnRight();
            return false;
        }
    } 
          
    /** Turn right 90 degrees
     */
    public void turnRight()
    {
        turnLeft();
        turnLeft();
        turnLeft();
    }
}
