For the third deliverable of your Swarm Project, you will modify your program to use an object-oriented style; that is, we will use encapsulation and classes (what the text calls interfaces) as discussed in class and in the text (Part VIII, Sections 39-43). We will also be adding a few new features that should make the overall behavior more interesting.
Apply the encapsulation techniques from Sections 39 through 41
to create a class, or interface, for a bug.
The primary services that a bug must provide include:
draw-self and update-self.
To draw itself, the bug need only encapsulate
its location and velocity vectors and its type and color
so that it can draw a dot and a pointer in the appropriate color.
However, to update itself, the bug needs to be able to determine its
neighbors. Once it identifies the bugs in its neighborhood,
it also needs to access the locations and velocities of each respective neighbor.
Also, for reasons that will become apparent,
we also need access to the type of a given bug.
Thus, the bug interface must also support accessors for location, velocity, and type.
Thus, we have the redefinition of a bug according to the following:
A bug is an interface:
Objects are instances of a pattern encoded in a class. These instances are generally intended to be somewhat persistent. In our case, you will create a swarm of bug instances at the beginning and then they will modify, or mutate themselves in response to messages that exercise the update service. Your constructor should consume a bug's initial location, velocity, type and color.
We want a bug to swarm with other bugs of its own type, but avoid bugs of a different type. When checking for neighbors, you will now also need to check for type. In addition, you will also need to be able to find neighbors of the other type. (Think about abstracting these.)
When considering bugs of its own type, a bug will use alignment, cohesion, and separation, much as before. But when considering neighbors of a different type, it will compute a separate separation vector and this will be included as a distinct contribution to the overall steering update. 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.
I am sending you on a treasure hunt for efficiency improvements. When you find and make an efficiency improvement, be sure to include a comment describing what you did and why. To get you started, look for repeated computations -- especially computations that involve recursion or maps, folds, etc. Another clue is to avoid expensive operations such as sqrt or trig functions. You can also reduce your need for garbage collection by only creating new lists, posns or other instances of structures when absolutely necessary. (Note, you should not be creating bugs except to create the initial swarm for big-bang.
You can eyeball your progress by the visual flash as you animate a large swarm. You can also use the time function for your satisfaction. (I may use time to compare your time with mine on the same swarm for certain operations such as update.) 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., update-swarm), you will need to create a wrapper.
For this final project deliverable, you should have working code that implements:
To grade this deliverable, I will review your code (including contracts, purpose statements, indentation, etc.) and I will run big-bang with my own swarm. It is important that you follow the instructions carefully.