Clojure Assignment 2: Sharks
Fall 2010, David Matuszek

Purposes of this assignment

• To teach agents and Software Transactional Memory

The "rules"

This assignment is based loosely (very loosely) on a well-known simulation program, "Wator," in which sharks and smaller fish interact in a two-dimensional world. To avoid unnecessary complications so that you can concentrate on the main Clojure points, I have greatly simplified the simulation.

• The only kind of fish is the shark.
• Sharks live in a one-dimensional world (a sequence).
• Sharks differ in weight, and start out weighing 100 pounds, plus or minus a certain random amount.
• Use real numbers, and don't worry about two sharks weighing exactly the same.
• Sharks cannot turn around, and must always swim in the same (randomly chosen) direction they start in.
• Sharks move independently (they are separate processes). To move:
• A shark must wait a random amount of time, between 1/2 second and 1 second, before each move.
• When a shark moves, it moves to the next (or previous) location in the sequence, end-around (so it is actually swimming in a circle).
• A shark cannot move into a space containing a larger, living shark.
• A shark can and will move into a space containing a smaller shark, or a dead shark--it "eats" the other shark, and gains 25% of the eaten shark's weight.
• A shark starves to death (and stops moving) if it moves ten times without finding something to eat.

Details

Use an `agent`, whose value is a `struct`, to represent a shark. The struct can contain whatever information is needed. I think it probably needs the weight of the shark, the direction the shark moves, how long it has been since its last meal, and whether the shark is dead. As a process, it's job is to update the shark every so often (as noted above, between 1/2 and 1 second).

Use a sequence of some sort (a vector is probably best) to represent the one-dimensional world. For each location in the sequence, either generate a random shark (probability = 0.5) or leave it "empty" (probability = 0.5). It might be helpful to put some kind of explicit "empty object" in the locations that don't contain sharks.

Sharks interact with other sharks (by eating them), so you will have to coordinate updates to sharks; use a transaction for this. Note that transactions may fail--shark A may be eating shark B, which is eating shark C, while shark D (which is coming from the other direction) is eating shark C.

Print out what is happening, so we can see what the program is doing. Default printout is likely to be far too messy to be understood, so try to come up with something simpler. Giving each shark an id of some sort, probably a small integer, might be helpful.

The built-in function `(rand)` returns a random floating-point number between 0 and 1. The Java method `(. Thread (sleep ms))` pauses for `ms` milliseconds.

Watch the course web page for important updates, as I try to implement this program myself.

Due date:

Turn in your` shark.clj `file by midnight, Wednesday October 27. As only one file is required, there is no need to zip it.