/** A class of snakes that can think for themselves.
 *
 *  These are used for the robot player in the game of Slither.
 *  @author Jim Grundy
 *  @version $Revision: 1.11 $ */

import java.awt.Color;	// Colors

public class RobotSnake extends Snake 
{
    private static final Color ROBOT_COLOR = Color.red;
    private static final char ROBOT_LETTER = 'R';

    /** Create (and draw) a robot snake on a field of grass.
     *
     *  The initial position of the snake is supplied, as are the colors
     *  for its head and body. The snake should be of length 1, i.e.,
     *  just the head, and the snake should be heading straight up the
     *  field.
     *  
     *  PRE: The square selected should be empty, i.e., 
     *       field.getContent(col,row) == GrassField.CT_GRASS */
    public RobotSnake(ObjectField field, int col, int row)
    {
	super(field,col,row,ROBOT_COLOR,ROBOT_LETTER);
    }
    
    /** Ask the robot snake the think about its next move.
     *
     *  The think command has no visible effect, but it can turn the
     *  snake so that the next time the move method is called the snake
     *  moves in a different direction.
     *
     *  The robot snake will be driven by interleaving calls to the
     *  think and move methods.  This should cause the snake to head
     *  towards the closest bit of food on the playing field (if there
     *  is any).  As its second priority, the snake should try to avoid
     *  running into the edge of the field or into a snake (including
     *  itself), as that would kill it.  */
    public void think()
    {
	/* Set (targetCol,targetRow) to the be the location of the closest
	 * item of food on the field, or to be there centre of the field
	 * if there is no food. */
	int targetCol = getField().getWidth()/2;
	int targetRow = getField().getHeight()/2;
	/* Any food is closer than this. */
	int foodDist = getField().getWidth() + getField().getHeight();
	for (int col=0; col<getField().getWidth(); col=col+1) {
	    for (int row=0; row<getField().getWidth(); row=row+1) {
		/* INVARIANT: 
		 *   "If there is food before (col,row), then foodDist is the
		 *    distance to the closest such food,
		 *    and (targetCol,targetRow) is its location.
		 */
		if (Food.class.isInstance(getField().getObject(col,row)) 
		    && (movesTo(col,row) < foodDist)) {
		    foodDist = movesTo(col,row);
		    targetCol = col;
		    targetRow = row;
		}
	    }
	}
	
	/* Turn towards the target. */
	if (toLeft(targetCol,targetRow)) {
	    turnLeft();
	} else if (toRight(targetCol,targetRow)) {
	    turnRight();
	} else if (behind(targetCol,targetRow)) {
	    turnLeft();
	    if (blocked()) {
		turnRight();
	    }
	}
	
	/* Avoid collisions. */
	if (blocked()) {
	    straight();
	    if(blocked()) {
		turnLeft();
		if (blocked()) {
		    turnRight();
		}
	    }
	}
    }
}

