/**
 * Bunny class: bunnies have a 2D position, and each hop costs one
 * carrot. First people tried writing this out separately on paper,
 * then we created this synthesis class together. In several places, I
 * point out which alternatives are legal, and which are incorrect.
 * Lecture 18, Tue Mar 14 2006
 */

public class Bunny
{
    /* Several people proposed a class that had no fields at all! 
     * That's of course a problem because there's no place to keep
     * track of information. Tip: when you're doing class design, try
     * deciding on your fields first, before you launch into writing
     * methods.
     */
    private int x; /** x position */
    private int y; /** y position */
    private int numCarrots; /** number of carrots, need one per hop */
    
    /*
     * Bunny constuctor
     */
    public Bunny() 
    {
        // either this.x=10 or just plain x=10 would be legal here
        this.x = 10;
        this.y = 10;
        numCarrots = 5;
    }
    
    /*
     */

    //public hop(int xdirection, int ydirection) {
    /* Somebody proposed having hop take two parameters: xdirection
     * and ydirection. No, that's not legal. There was a specification
     * for the Bunny class that had explicit requirements for the hop
     * API. So although it would be possible to design a class with
     * this method, that's not what we were asked to do.
     */

    /**
     * hop moves the bunny by one unit in the indicated direction
     *
     * @param direction Like the hands on a clock face, 3 moves east,
     * 6 moves south, 9 moves west, and 12 moves north.
     */
    public void hop(int direction) {

        // while (numCarrots > 0) { // don't need a loop!
	/* Somebody proposed using a loop here. No, we don't need a
	 * loop here, the hop method only moves a single rabbit by a
	 * single unit. Make sure you understand when to use a
	 * conditional (make a decision once) vs. a loop (do something
	 * many times).
	 */

        //numCarrots = 5;
	/* Somebody proposed setting the numCarrots field here. No,
	 * because that would reset the bunny's energy level every
	 * time we hopped. The decrement below wouldn't have any
	 * effect. We want to have that value set just once, so it
	 * belongs in the constructor.
	 */

        if (numCarrots > 0)    {
            System.out.println("hop");
            if (direction == 12)
            {
                y++;
            } else if (direction == 3) 
	    {
		x++;
	    } else if (direction == 6) 
	    {
		y--;
	    //} else if (direction == 9) {
	    /* Some people chose to have an explicit test for the last
	     * case. That's legal, and it's a matter of style
	     * preference whether to have the plain else statement in
	     * as below, or have an explicit condition as above.
	     */
	    } else {
		x--;
	    }

	    /* There were a few alternatives. Each of these if
	     * statements has a body that's only one line long. Here's
	     * a more concise approach of leaving out the curly braces
	     * that's legal, although it can cause some confusion if
	     * you later need to add more statements to the statement
	     * body. 

	     *
            if (direction == 12)
                y++;
            else if (direction == 3) 
		x++;
	    else if (direction == 6) 
		y--;
	    else 
		x--;

	     * Finally, since the line is only a few characters long,
	     * a very concise way is to avoid even the line break
	     * between the if conditional and the statement. This is
	     * legal, although it's a different formatting style than
	     * the one normally used in this course.

            if (direction == 12) y++;
            else if (direction == 3) x++;
            else if (direction == 6) y--;
            else x--; 

	    */
            
            numCarrots--;
        } else {
            System.out.println("This bunny can't hop");
        }
    }
    
    /** prints out the x and y position, and the number of
     * carrots left, for this Bunny
     */
    public void displayInfo()
    {
        //return direction; 
	/* Somebody proposed returning the direction variable. Two
	 * problems: first, the specification for the displayInfo
	 * method is to print out information, not to return a value. 
	 * It's really important to remember the difference between
	 * printing something out, which presents information to the
	 * person running the program, and returning a value, which
	 * allows other parts of the program to manipulate the data.
	 * 
	 * Second, we cannot use the direction variable here because
	 * that was a parameter passed in to the hop method. When the
	 * hop method returns, that variable vanishes! So it's not
	 * available to us here, it's out of scope. 
	 */

        System.out.println("This bunny is at position "+x+","+y);
        System.out.println("This bunny has "+numCarrots+" carrots remaining");
        
    }
 
    /* This testing driver class was given to us, so no judgement used here */
    public static void main( String[] args )
    {
        System.out.println("Testing Peter");
        Bunny peter = new Bunny();
        peter.displayInfo();
        peter.hop(12);
        peter.hop(12);
        peter.hop(9);
        peter.displayInfo();
        System.out.println("Testing Emily");
        Bunny emily = new Bunny();
        emily.displayInfo();
        emily.hop(9);
        emily.hop(9);
        emily.hop(9);
        emily.hop(12);
        emily.hop(9);
        emily.hop(12);
        emily.displayInfo();
    }

}

