|
CSE 142 Summer 2001
Homework #6
Due: At the beginning of class, Monday, August 6, 2001
|
Purpose
The purpose of this assignment is to extend a program that implements an
environmental simulation. This assignment builds on previous assignments -
defining classes, sending messages (calling methods), using collections - and
introduces the following topics:
- Time driven simulations, including pseudo-random numbers
- Creating classes that implement interfaces
- Extending code written by someone else, which contains some code that
might not even make sense at this point - but which doesn't need to be
understood to complete the job at hand
We will evaluate your work both on functionality (does it work?) and quality
(how well is the program written). This means doing your best in terms of
commenting and using good names in your program.
Problem Statement
In March of 1989, the Exxon Valdez oil tanker ran aground in the Gulf of Alaska,
rupturing many of its oil compartments and ultimately spilling 11 million
gallons of North Slope crude oil into Prince William Sound. In this assignment,
we'll simulate the impact of an oil spill such as the above on an environment.
We'll provide you with the simulation engine and a few simulation classes, and
ask you to modify the existing classes and to add a few new ones, such as
genetically engineered bacteria that can eat oil.
Out of the box, we provide the following classes, and one interface:
- Thing - this interface defines the basic behaviors that must be
implemented by all objects in our simulation.
- Environment - this is the core of the simulation. It maintains a
collection of all Things. The simulation begins by adding a bunch of Things
to the Environment, and then simulating the passage of time by asking all of
the objects to perform their basic behaviors over and over again. Each cycle
of the simulation has several phases:
- Display: all Things are asked to display themselves onto the screen
- Interaction: all Things asked if they wish to "consume"
other things that are nearby. If so, the other Things are removed from
the simulation.
- Spawning: all Things are asked if they wish to reproduce and given the
chance to add new Things to the simulation.
- Movement: all Things are asked to move about the world.
- Tanker - this kind of Thing travels across the screen spilling OilBlobs
into the environment.
- OilBlob - this kind of Thing floats around and kills (consumes) Fish and
Algae.
- Algae - this kind of Thing just floats around and gets eaten.
- Fish - this kind of Thing swims around and eats Algae. When it eats enough
Algae, it reproduces.
Instructions/Hints
- The online copy of this assignment web page has links to the starter files
for the project. You can obtain the .java source files individually: Environment.java,
Thing.java, Tanker.java, Algae.java,
OilBlob.java, and Fish.java.
Or you can obtain the same six files in a single executable zip file, hw6files.exe.
Double click on the zip file to extract the Java source files.
- Save the files in a folder and open the folder in BlueJ. Here is a
quick description of the files:
Environment.java
defines the Environment class and the
main driver for the application. You'll only make minor modifications
here, but you'll want to read the comments, because you'll need to use
some of the methods.
Thing.java
an interface description for all Things.
Tanker.java
defines the Tanker class
Algae.java
defines the Algae class
OilBlob.java
defines the OilBlob class
Fish.java
defines the Fish class
- First, you'll want to get the application working fully. Compile the
files, then create an instance of Environment and start the simulation by
executing it's startSimulation() method. You
should see a bunch of green and yellow dots moving around. These are Algae
and Fish. Run it for a while and watch the statistics that are printed out.
To stop the simulation before it finishes, you can open the debugger (in the View Menu),
and hit the "Stop" button, and then the "Terminate"
button.
- Next introduce a Tanker into the mix. Check out the go() method in the
Environment class and uncomment the place where the Tanker gets added. Run
the simulation again and look at the impact of the OilBlobs on the
environment.
- Now modify the spawn() method for the Fish class. After eating 5 algae, it
should add another Fish. Check out the Tanker class's spawn method for hints
on how to do this.
- Now modify the spawn() method for the Algae class. Algae should simply
reproduce every so often. It's up to you to figure out how to implement
this. Warning: adding a new Algae every turn will swamp the simulation.
Probably using a random number generator and just reproducing about one time
in a thousand should give decent results.
- Now its time to invent oil eating bacteria. Create a class called
PoisonEatingBacteria which consumes OilBlobs. These bacteria shouldn't
reproduce and are essentially indestructable (nobody else eats it). At first,
it should just wander randomly around the world eating any oil it
encounters. You can start by just copying the code for one of the other
kinds of things, like Algae, and modifying its methods. You'll then have to
modify the go() method in the Environment class to add about 50 (or so) of
these bacteria to the environment.
- Make your PoisonEating bacteria smarter. Using the thingsEast(),
thingsWest(), etc methods on the Environment to help your bacteria
"smell" if there is Oil in a given direction. If so, it should
move in that direction. The trick here is that when the Poison eating
bacteria is created, it needs to be told about the environment it lives in,
so it can call Environment methods that return collections of neighboring
objects.
- There's lots of flexibility for how smart you make your bacteria. It could
check north, south, east, and west, and move to where there is the most oil.
- Finally, we want you to add at least one more kind of thing in the world.
Be creative -- you could add birds (who eat Fish and are killed by OilBlobs),
otters, cleanup workers (who remove Oil, but are killed by
PoisonEatingBacteria), etc.
- We may have a contest to see who makes the smartest PoisonEating bacteria,
if there is sufficient interest.
Notes on Random Numbers
For a simulation to be interesting, the individual objects in the world
should not all do exactly the same thing at the same time. A standard
technique for producing variations in behavior is to use a random number
generator. Java contains a class Random that provides this
capability. An instance of class Random provides methods that return a new
value each time they are called. The most useful one for this simulation
is method nextInt, which takes an integer argument n, and returns a
random number in the range 0 to n-1. If you look at the various
Thing classes like Fish, you'll see examples. Fish, for instance,
calculates how far to move on each tick of the clock by evaluating
rand.nextInt(5)-2, which yields a number between -2 and +2. Use Jeva to
experiment with Random objects and the nextInt method to see how it works.
What to Turn In
A turnin form is available. Use that to turn in
your (modified) copies of the original files, plus your
PoisonEatingBacteria.java file and the file(s) containing your additional kind
of thing(s). You can either turn in all of your Java source files by
selecting them one at a time, or you can create a single archive (a zip, jar, or
tar file) containing your Java files and turn that in instead.