10.2 The foxes-and-rabbits simulation
10.2.4 The Simulator class: setup
TheSimulator class is the central part of the application that coordinates all the other pieces.
Code 10.3 illustrates some of its main features.
// import statements and class comment omitted public class Simulator
{
// static variables omitted
// Lists of animals in the field.
private List<Rabbit> rabbits;
private List<Fox> foxes;
// The current state of the field.
private Field field;
// The current step of the simulation.
private int step;
// A graphical view of the simulation.
private SimulatorView view;
/**
* Create a simulation field with the given size.
* @param depth Depth of the field.
* Must be greater than zero.
* @param width Width of the field.
* Must be greater than zero.
*/
public Simulator(int depth, int width) {
if(width <= 0 || depth <= 0) { System.out.println(
"The dimensions must be greater than zero.");
System.out.println( "Using default values.");
depth = DEFAULT_DEPTH;
width = DEFAULT_WIDTH;
}
rabbits = new ArrayList<Rabbit>();
foxes = new ArrayList<Fox>();
field = new Field(depth, width);
// Create a view of the state of each location in the // field.
view = new SimulatorView(depth, width);
view.setColor(Rabbit.class, Color.ORANGE);
view.setColor(Fox.class, Color.BLUE);
// Set up a valid starting point.
reset();
} /**
* Run the simulation from its current state for the Code 10.3
Part of the Simulator class
10.2 The foxes-and-rabbits simulation | 339
* given number of steps.
* Stop before the given number of steps if it ceases to * be viable.
* @param numSteps The number of steps to run for.
*/
public void simulate(int numSteps) {
for(int step = 1; step <= numSteps &&
view.isViable(field); step++) { simulateOneStep();
} } /**
* Run the simulation from its current state for a single * step.
* Iterate over the whole field, updating the state of * each fox and rabbit.
*/
public void simulateOneStep() {
// method body omitted
} /**
* Reset the simulation to a starting position.
*/
public void reset() {
step = 0;
rabbits.clear();
foxes.clear();
field.clear();
populate();
// Show the starting state in the view.
view.showStatus(step, field);
} /**
* Populate the field with foxes and rabbits.
*/
private void populate() {
Random rand = Randomizer.getRandom();
field.clear();
Code 10.3 continued
Part of the Simulator class
for(int row = 0; row < field.getDepth(); row++) { for(int col = 0; col < field.getWidth(); col++) {
if(rand.nextDouble() <= FOX_CREATION_PROBABILITY) { Location location = new Location(row, col);
Fox fox = new Fox(true, field, location);
foxes.add(fox);
}
else if(rand.nextDouble() <=
RABBIT_CREATION_PROBABILITY) { Location location = new Location(row, col);
Rabbit rabbit = new Rabbit(true, field, location);
rabbits.add(rabbit);
}
// else leave the location empty.
} } }
// other methods omitted
} Code 10.3
continued
Part of the Simulator class
The Simulator has three important parts: its constructor, the populate method, and the simulateOneStep method. (The body of simulateOneStep is shown below.)
When a Simulator object is created, all other parts of the simulation are constructed by it (the field, the lists to hold the different types of animals, and the graphical interface). Once all these have been set up, the simulator’s populate method is called (indirectly, via the reset method) to create the initial populations. Different probabilities are used to decide whether a particular location will contain one of these animals. Note that animals created at the start of the simulation are given a random initial age. This serves two purposes:
■ It represents more accurately a mixed-age population that should be the normal state of the simulation.
■ If all animals were to start with an age of zero, no new animals would be created until the ini- tial population had reached their respective breeding ages. With foxes eating rabbits regard- less of the fox’s age, there is a risk that either the rabbit population will be killed off before it has a chance to reproduce or that the fox population will die of hunger.
Exercise 10.22 Modify the populate method of Simulator to determine whether set- ting an initial age of zero for foxes and rabbits is always catastrophic. Make sure that you run it a sufficient number of times—with different initial states, of course!
Exercise 10.23 If an initial random age is set for rabbits but not foxes, the rabbit population will tend to grow large while the fox population remains very small. Once the foxes do become old enough to breed, does the simulation tend to behave again like the original version? What does this suggest about the relative sizes of the initial populations and their impact on the outcome of the simulation?
10.2 The foxes-and-rabbits simulation | 341