CS010 Introduction to Computer Science I
Term Project
Deliverable Four

Swarm and Flocking Behavior:
Classes and Objects
(last updated 4/19/2006)

For the fourth deliverable, we will modify our program to use an object-oriented style; that is, we will use encapsulation and interfaces as discussed in class and the text.   We will also be adding a few new features that should make the overall behavior more interesting.

Critter Interface and Objects
Apply the encapsulation techniques from Sections 39 through 41 to create an interface for a critter.  The primary services that a critter must provide include: draw-self, clear-self, and update-self.  To draw and clear, the critter need only encapsulate the location and velocity vectors and the color so that it can draw a dot and a pointer in the appropriate color.  However, to update itself, the critter needs to be able to determine its neighbors.  Once it identifies its neighboring critters, it also needs to access the locations and velocities of each neighbor.  Also, for reasons we will see, we also need to be able to access the type of a given critter.  Thus, the critter interface must also support accessors for location and velocity.  Thus, we have something like the following:

A critter is an interface:
1. 'draw:: true
2. 'clear:: true
3. 'update-self:: swarm -> true
4. 'location:: posn
5. 'velocity:: posn
6. 'type:: symbol

A swarm will be a (listof critter) where we are now talking about critter interfaces or instances. 

Rewrite your existing functions, such as draw-critter, clear-critter, update-critter, etc., to utilize this new formulation.

Critter Types and Species-selective Swarming
We want a critter to swarm with other critters of its own type, but avoid critters of a different type.  When checking for neighbors, you will now also want to check for type.  In addition, you will also need to be able to find neighbors of the other type.  (Think about abstracting these.)

Basically, when considering critters like itself, a critter will use alignment, cohesion, and separation, much as before.  But when considering neighbors of a different type, it will compute a separation vector and this will be included as a distinct contribution to the overall steering.  Naturally, it will need its own weight that is distinct from the separation weight (e.g., SEPARATION-W) that is used for basic swarming with one's own kind.

Efficiency

Although we will not implement the grid-based strategy I described in class, I am sending you on a treasure hunt for other efficiency improvements.  When you find and make an efficiency improvement, be sure to place a comment starting with ";;E: " and followed by a short note of what you changed.  One thing to look for are repeated computations -- especially computations that involve recursion or maps, folds, etc.  Another clue is to avoid expensive operations such as sqrt.  You can also reduce your need for garbage collection by only creating new instances of structures or classes when absolutely necessary. 

You can eyeball your progress by the visual flash as you animate a swarm of a given size.  You can also use the time function for your satisfaction.  (I will use time to compare your time with mine on the same swarm.)  You are free to extend the data definitions if you think it will improve your efficiency.  If you intend to change the contract of a primary function (e.g., animate-swarm), you probably want to create a wrapper.


For this final project deliverable, you should have working code that implements:
  1. Everything from deliverable 3 (i.e., swarming and edge avoidance)
  2. Three or more different critter species that swarm independently and avoid each other.
  3. Improved efficiency sufficient to animate a swarm of three types of critters of about a dozen critters each.
To grade this deliverable, I will review your code (including contracts, purpose statements, indentation, etc.) and I will run the animate-swarm with my own swarm.  It is important that you follow the instructions carefully.