Creating New Fish Subclasses
Refactor the Fish
class, following the instructions below,
then implement at least two of the following Fish
subclasses. Develop test plans to test your new classes. (Be sure to view
the testing suggestions at the end of this
document.) Document your classes in the comments at the top and in internal
comments as appropriate.
Refactor Fish
Several of the subclasses below involve finding a set of possible move
locations and then randomly choosing one to move to. The current
nextLocation
method does this, but it combines aspects of the
two. Refactor the nextLocation
method to separate these two
ideas:
- Create a new
findMoveLocs
method and move the code dealing with gathering and narrowing down the list of possible move locations fromnextLocation
tofindMoveLocs
. - Modify
nextLocation
so it callsfindMoveLocs
and then makes the random choice.
Fish Subclass Options (choose at least two)
-
TurningDarter:
A darter always moves east/west or always move north/south. Create a subclass of theDarterFish
class, calledTurningDarter
, that behaves likeDarterFish
except that there is a probability of 0.1 that a turning darter turns right or left (each with equal probability) before it tries to move forward. -
TurningSlowFish:
A slow fish moves in each timestep, even when it doesn’t move far enough to leave its current cell. As it moves slowly in its own cell, it may change direction. Create a new subclass that may still turn right or left (or continue in its current direction) even when it doesn’t move outside its cell it. Decide what the probability should be that it turns, and document that design decision in the class documentation for your class. -
SlowTurningFish:
(Alternative to
TurningSlowFish
)
These slow fish have a 3 in 5 chance of turning, with an equal chance of turning right or left. (So they have a 3 in 10 chance of turning right and a 3 in 10 chance of turning left.) They still have a 1 in 5 chance of moving, but they always move "forward" (though that might be forward after they turned). A key design decision will be: is this similar enough toSlowFish
behavior to extendSlowFish
, or do you just want to extendFish
? -
FastFish:
A fast fish can move one or two cells away in a single timestep, in any of the four directions. It can only swim two cells away, though, if the intermediate cell is empty. The left diagram below shows all the possible neighboring locations (~) of a fast fish (F). The diagram on the right shows how neighboring fish (n) can block a fast fish from moving to empty locations further away (the ones marked #).~ # ~ n ~ ~ F ~ ~ # n F ~ ~ ~ ~ ~ ~
-
ForwardFish:
A forward-moving fish can move forward or forward and slightly to the left or right. For example, a fish facing north could move north, northeast, or northwest. A fish facing east could move northeast, east, or southeast. Since the grid only knows about the four adjacent neighbors, you'll have to identify the additional neighbors on your own. (After a fish moves, its direction might surprise you. If the fish moves on a diagonal, to the northeast for example, the fish's direction will be "rounded" to north or east.)Extension: Notice that forward-moving fish get stuck at the sides of the environment. Modify the
ForwardFish
class so that a fish that is stuck reverses direction. -
CircleFish:
Define a newCircleFish
subclass ofFish
that constantly swims in a circle (as much as is possible in a rectangular grid). In each timestep, the circle fish moves to the location forward and to the right, on a diagonal from its current location, if possible. (The forward location does not need to be empty, but the location on the diagonal does.) It also changes its direction by turning 90 degrees to the right. If the fish cannot move as described above, it stays in its current location, but still turns 90 degrees to the right.Advanced Version: In the first timestep, a circle fish moves forward one location (if possible), without turning. During the next timestep, it moves to the location forward and to the right (if possible), as described above. If the fish cannot move, it stays in its current location, but turns 90 degrees to the right. After the fish has moved and turned, or just turned without moving, its next movement will be to move forward one location. The fish continually alternates these moves (except when it is unable to move and only turns).
Testing Suggestions
As you design your Fish
subclasses, be sure to consider
"weird" conditions as well as obvious ones. For example, what will a fish
do if it's in a corner, facing one of the two edges? What will it do if it
is along an edge but not in a corner? What if it is completely surrounded
with fish? The four scenarios below are examples of the kind of "boundary
conditions" you should always remember to test.
F ~ ~ ~ ~ ~ F ~ ~ n ~ ~ ~ ~ ~ ~ F ~ ~ ~ n F n ~ ~ ~ ~ ~ ~ ~ ~ F ~ n ~ ~ ~ ~ ~ ~ ~ F ~ ~ ~ ~ ~ ~
You might want to make objects of each new subclass a different color,
just as Pat did for darters, just to help you identify the different
types as you test the simulation.
You may also want to develop an initial configuration file that
contains a mixture of Fish
and subclass objects.