Solution to the KnightCritter problem.

By Paley.

/* 
 * AP(r) Computer Science GridWorld Case Study:
 * Copyright(c) 2005-2006 Cay S. Horstmann (http://horstmann.com)
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * @author Chris Nevison
 * @author Barbara Cloud Wells
 * @author Cay Horstmann
 */

import info.gridworld.actor.Actor;
import info.gridworld.actor.Critter;
import info.gridworld.actor.Flower;
import info.gridworld.grid.Location;

import java.util.ArrayList;

/**
 * A KnightCritter moves like a knight in chess.
 * This one is allowed to move onto (and thus eat) a Flower.
 */
public class KnightCritter extends Critter
{    
    // Look!  No constructor!  A default constructor will be created
    // by Java, so no worries...
    
    public ArrayList<Location> getMoveLocations()
    {
        Location loc = getLocation();            // where we are
        ArrayList<Location> locs = new ArrayList<Location>();

        /*
         * -------  The knight is going to search for open squares
         * --2-2--  by looking at squares that are vertically or
         * -2-1-2-  horizontally adjacent to its current position
         * --1N1--  (indicated by 1s) and then looking at diagonals
         * -2-1-2-  +/- 45 degrees from those squares (as indicated
         * --2-2--  by 2s).
         * -------
         */

        // Make a point of looking over the Location class constants
        // Pet peeve: The constants really should be in a Direction interface
	//   since NORTH, RIGHT, etc., really are directions, not locations
        for (int i = Location.NORTH; i < Location.FULL_CIRCLE; i += Location.RIGHT) {
            Location adjacentLocation = loc.getAdjacentLocation(i);
            if (getGrid().isValid(adjacentLocation)) {
                Location[] diag = new Location[2];
                diag[0] = 
                    adjacentLocation.getAdjacentLocation((i+Location.HALF_LEFT+Location.FULL_CIRCLE) % 
                            Location.FULL_CIRCLE);
                diag[1] = 
                    adjacentLocation.getAdjacentLocation((i+Location.HALF_RIGHT+Location.FULL_CIRCLE) % 
                            Location.FULL_CIRCLE);
                for (Location d : diag) {
                    if (getGrid().isValid(d)) { 
                        Actor a = getGrid().get(d);
                        if (a == null || a instanceof Flower) {
                            locs.add(d);
                        }
                    }
                }
            }
        }
        return locs;
    }
}