In lab this week, and in the next class meeting time, you and your partner (or partners) will be experimenting with a biological simulator. This is an exercise in using subtype polymorphism. It help you make a quicker start during the lab if you take a little bit of time to think about how the simulation is structured before you come to lab.
You will be working with various implementations of the
Agent
interface.
The subclasses of Agent
represent the various species
occupying the simulated world, which is represented by the
SimulationGrid
class. As the name suggests, the world is modelled as a
rectangular grid of cells, where each cell can be occupied by at most
one Agent
.
On each tick of the clock, the simulation calls the
act()
method for each agent in the grid. That agent can
examine the world around it (via methods on the grid), update its
state, and, if appropriate, move to another cell.
It may help to think about the
ball-catching project. In that
program, you wrote the Player
class, which corresponds to
an agent in this simulation. The constructor for a
Player
was passed its coordinates in the grid and the
GridInfo
for the grid it was in. The relationship
between various agents and the grid here is similar: an agent can
examine locations in the by calling three methods on
SimulationGrid
:
boolean isOccupied(int xPos, int yPos)
boolean isOpen(int xPos, int yPos)
Agent getAgentAt(int xPos, int yPos)
Conveniently, these methods all do the right thing when passed a
position that is outside the grid: both isOccupied()
and
isOpen()
return false, and getAgentAt()
returns null
.
In the ball-catching game, the Player
never updated
the grid directly; the only way that it could interact was to return a
new position to move to, and the simulation took care of everything
else. In this program, an agent must update the grid using the method
void setAgentAt(int xPos, int yPos, Agent a)
Movement requires calling this method twice: once to clear the
cell where the agent previously resided (by setting the agent there to
null
) and then a second to occupy its new location.
Because the grid allows only one agent to occupy a cell,
setting the agent in a cell results in the demise of any agent that
previously occupied that location.
Your simulation starts out with three agent classes, implementing
behaviors of Clover
, Rabbit
, and
Fox
. Even before you look at the code, you can imagine
the strategies of each:
Before you look at the code, you might want to think about how you might write each of these behaviors. When you come to lab, you'll have a chance to see how they have been implemented.
When you come for the lab, remember to bring your printed copy of the agent classes. You and your partner(s) will do several things: