All of the features listed in the proposal for the basic game were implemented. The one concession to modern persistent display technology was the placement (launching) of mines sufficiently far from the ship to allow the mines to be immediately armed. In contrast, in the PDP-12 implementation, the non-persistent monochrome display allowed a yet-to-be-armed mine to be spotted easily even when displayed right on top of the ship.
We also implemented the following features beyond the basic game:
The blue ship is controlled by the mouse, and the green ship is controlled by the keyboard. The mouse may be used on a grid of nine buttons, arranged as follows:
The keyboard presents the same controls on the numeric keypad (if "Num Lock" is enabled!), using the same pattern so that the numbers map to the functions as follows:
The game looks as follows when the full five mines and one missile per ship are in flight.
The sun is in the center of the screen. The tiny white dots are stars. The pale green box is the edge of the universe, off which objects bounce. The small blue and green circles with crosses are mines. The small blue and green circles with flames coming from them are missiles. The large blue and green circles each with the single short line from center to edge are the ships. The lines denote engines, and if the ships’ engines were on, there would be flames emanating from the lines, similar to the flames emanating from the two missiles.
The Universe class is an example of a mediator. All in-flight SpaceObjects’ gravitational and collision interactions are managed by Universe, and SpaceObjects are in general unaware of each other’s position, velocity, state, and existence. There are two exceptions to the lack of awareness of existence: SpaceShips track how many of their SpaceMissiles and SpaceMines are still extant in order to determine whether the player may legally launch another SpaceMissile or SpaceMine. Note that Universe is not a Singleton. As every Star Trek fan knows, limiting your game to a single Universe is just plain shortsighted.
The SpaceGraphics class is an example of a decorator. This class delegates graphics operations to the underlying AWT Graphics object after making the coordinate transformations needed to move from a physics-friendly right-hand-rule coordinate system based on the centers of objects to the increasing-Y-downwards upper-left-corner coordinate system implemented by AWT.
The SpaceObject class serves as a template for the SpaceSun, SpaceShip, SpaceMissile, and SpaceMine classes.
The SpaceObjectRegistry class serves as an abstract factory. New SpaceSuns, SpaceShips, SpaceMissiles, and SpaceMines may be created by sending the SpaceObjectRegistry a message containing the string "sun", "ship", "missile", and "mine", respectively. The SpaceObjectRegistry class is also a singleton: its constructor is private, and all of its methods and instance variables are declared static.
The SpaceObjectListIterator serves as an iterator. This object reduces the number of explicit cast operations required, and supports "all pairs only once" scanning by allowing a iterator to start after a particular object. This simplifies scanning SpaceObject lists when computing gravity or checking for collisions.
Overview
We used a "spiral" implementation methodology. Paul implemented from the display in towards the model, while Venu implemented from the keyboard and mouse in towards the model. We integrated our two components once per week. This approach allows incremental testing with very low scaffolding-creation overhead. Each component was tested as it was created; using previously constructed and tested components as test scaffolding.
Venu used the title bars of the input components to display text messages, thereby verifying that input components were providing the correct response to user input. Paul used hard-coded placement of SpaceObjects with Java statements to verify that the display and the model components were working correctly.
Between these functional tests were interspersed the unplanned, but surprisingly useful, random testing efforts of Melissa, Sarah, and Aaron, Paul’s three children.
We did specific tests for precession and for delta-V at perihelion and apohelion. The precession and delta-V tests are covered in the following subsections.
In theory, orbits should be perfect ellipses, parabolas, and hyperbolas. However, calculation errors cause the simulated orbits to deviate from their theoretical forms. There are two major sources of error: (1) roundoff error and (2) integration error.
Although roundoff error was the major contribution to error in the PDP-12 implementation, it is negligible in the Java implementation due to Java’s 64-bit IEEE floating point arithmetic.
However, integration error is significant, especially on highly elliptical orbits. The following diagram helps illustrate integration error:
This diagram shows a blue object in a clockwise elliptical orbit around the sun. We simulated motion using Eulerian integration, which means that we compute the force at a time t1, compute the resulting acceleration, change in velocity, and new position at time t2. However, the force will be changing continuously as the object moves from t1 to t2, and will be changing especially quickly when the object is passing close to the sun in an elliptical orbit. The diagram shows the force of gravity pulling the object upwards and to the right at t1. Eulerian integration uses this same force vector for the entire path from t1 to t2, with about 700 of error in direction of the force at point t2. This error results in precession. Highly elliptical orbits precess about 2 degrees per minute.
Delta-V at Perihelion and Apohelion
If an object is given an impulse (short burst of acceleration) at perihelion, this will cause the apohelion to move, but will not affect the perihelion. This is shown in the following diagram: an impulse in the direction of motion at perihelion causes the object to move from the inner orbit to the outer orbit. (A subsequent identical impulse at perihelion against the direction of motion would cause the object to revert back to the inner orbit.
Similarly, an impulse at apohelion will affect the perihelion, but not the apohelion.
Tests on our SpaceWar game showed that our simulation of gravity closely obeyed this law of motion.