Lab 11: The strategy pattern

The goal of this lab is to practice using the strategy pattern.

1. Introduction and setup

Today we go back to the predator/prey simulation. This time we will be adjusting the algorithm the animals use to find prey and elude predators.

The current version of the simulation can be copied from a subdirectory of the course public directory.

cp -r /homes/tvandrun/Public/cs245/lab11/* .

(The -r flag is for "recursive", and it indicates that entire directories should be copied.)

The algorithm that all animals use is to scan the the visible area around it, starting with the lower left hand corner, and given the first thing seen that is either a predator or a prey,

We have seen the effects of this. Rabbits congregate on the lower left can corner of a patch of clover-- either moving right into a predator's mouth even though a there's a predator-free clover-filled area nearby, or forming a swarm which moves from left to right. Animals lower on the food chain get away from predators above and to the left of them, but are practically blind to those below or to the right. Predators chase rabbits to the left of the board, or compete with each other for the same rabbit, when a swarm is only a few squares to the right. These animals could help their survival and the survival of their species if they only had smarter behavior.

In the current version of the simulation, the behavior of the scan method is mostly delegated to a strategy.

2. Inspecting the code

First, you will become familiar to the changes in the code base. The files relevant for this lab (ie, what you will need to know and possibly change) are Animal, ScanStrategy, StupidStrategy, Position, and the animal subclasses.

Re-familiarize yourself with Animal. Most of the functionality has been pulled up here in a variety of helper methods. The information about speed, growth rate, etc, is almost all that is left to the subclasses. What has changed in Animal (since the last iteration of this example) is that it has an instance variable of type ScanStrategy, which the scan() method make use of.

ScanStrategy is an interface with one method, which takes as parameters all the information necessary to make a scan decision and pick a position to which to move.. Notice that findPosition() als need a reference to the Animal calling it.

StupidStrategy is the old scan algorithm we've used before, now encapsulated in a class implementing ScanStrategy.

Since findPosition() must return both an x and a y coordinate, we have the simple class Position encapsulating those two things.

Finally, the Animal subclasses pick a strategy (right now there's only one) in their constructors. It is conceivable that you will want some classes to have some of their instances with one strategy, others with another. In that case, the constructor will somehow need to pick which one.

3. Writing new strategies

Your task is to encode new behavior for the animals by writing new ScanStrategy classes. Some things to think about:

Experiment. Start out by observing the current behavior. There basically are two possible outcomes: The clover wins, because all the rabbits are eaten before the clover is eaten, and then the clover expands with nothing to stop it; or, the rabbits win, by forming an unstoppable swarm that sweeps the clover off the map. I have found that if we hold constant the number of clover at 100, rabbits at 20, cougars at 1, and bears at 1 and vary the number of foxes, the boundary is somewhere around 12 foxes. At 10 foxes, the rabbits almost always win. At 15 foxes, the clover almost always wins.

When you write new Strategy classes, you'll have to change the constructors of the animal classes in order to use them. This may also require changing the place in PredPrey where the constructors are called (ask for help if you need it). You may also want to makes changes to the animals' getColor() methods so that, for example, if you have two different strategies that rabbits are using, you can trace which rabbits are using which.

To turn in: Leave the code in the appropriate directory. Make sure it is documented in a way that makes its intent clear.


Thomas VanDrunen
Last modified: Wed Apr 2 16:16:35 CDT 2008