/* * 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 Cay Horstmann */ package info.gridworld.actor; import info.gridworld.grid.Location; import java.util.ArrayList; /** * A Critter is an actor that moves through its world, processing * other actors in some way and then picking a new location.
* The implementation of this class is testable on the AP CS A and AB exams. */ public class Critter extends Actor { /** * A critter acts by getting a list of its neighbors, processing them, * getting locations to move to, selecting one of them, and moving to the * selected location. */ public void act() { if (getGrid() == null) return; ArrayList actors = getActors(); processActors(actors); ArrayList moveLocs = getMoveLocations(); Location loc = selectMoveLocation(moveLocs); makeMove(loc); } /** * Gets the actors for processing. The actors must be contained in the same * grid as this critter. Implemented to return the actors that occupy * neighboring grid locations. Override this method in subclasses to look * elsewhere for actors to process. * @return a list of actors that are neighbors of this critter */ public ArrayList getActors() { return getGrid().getNeighbors(getLocation()); } /** * Processes the actors. Implemented to "eat" (i.e. remove) all actors that * are not rocks or critters. Override this method in subclasses to process * neighbors in a different way.
* Precondition: All objects in actors are contained in the * same grid as this critter. * @param actors the actors to be processed */ public void processActors(ArrayList actors) { for (Actor a : actors) { if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid(); } } /** * Gets the possible locations for the next move. Implemented to return the * empty neighboring locations. Override this method in subclasses to look * elsewhere for move locations.
* Postcondition: The locations must be valid in the grid of this critter. * @return a list of possible locations for the next move */ public ArrayList getMoveLocations() { return getGrid().getEmptyAdjacentLocations(getLocation()); } /** * Selects the location for the next move. Implemented to randomly pick one * of the possible locations, or to return the current location if * locs has size 0. Override this method in subclasses that * have another mechanism for selecting the next move location.
* Precondition: All locations in locs are valid in the grid * of this critter * @param locs the possible locations for the next move * @return the location that was selected for the next move. */ public Location selectMoveLocation(ArrayList locs) { int n = locs.size(); if (n == 0) return getLocation(); int r = (int) (Math.random() * n); return locs.get(r); } /** * Moves this critter to the given location. Implemented to call moveTo. * Override this method in subclasses that want to carry out other actions * for moving (for example, turning or leaving traces).
* Precondition: loc is valid in the grid of this critter * @param loc the location to move to (must be valid) */ public void makeMove(Location loc) { moveTo(loc); } }