Cellular Automata: Part 3,
Object-Oriented CGoL

For the final project deliverable, you will revise your implementation of Conway's Game of Life to utilize our version of object-oriented design. The cells in your grid will now be objects as described in class. You will use the principles covered in class and in Sections 39-41 to create a cell class that encapsulates appropriate state variables and services relevant to a cell. Thus, a cell will be a service manager function that consumes messages and provides access to services.

Definitions and other details

We are only changing the underlying representation of cells. Now, a cell will be an object, or in the terminology of your text, an interface. Your cell objects must respond to the following messages and provide the appropriate services:

The key problem you may immediately notice is, How will a cell know its neighbors? Note that your grid definition, (vectorof (vectorof cell)), has changed implicitly by way of the new definition of a cell. So how can a cell access its neighbors? A good approach for this is to provide a cell's row and column as well as the grid itself as arguments to the cell constructor when you first create a cell-object. Note, each cell should only get created once and then persist throughout the simulation. Using this approach, a cell has ready access to its neighbors, since it has its own coordinates within the grid and the grid as a whole. However, as you create the cell objects, you may need to store them in their appropriate grid locations using vector-set!.

Finally, you'll need to make minor alterations to the rest of your program that displays the grid and updates it. The basic approach you'll want to use is to have all of the cell-objects ‘determine-new’ by querying the ‘current’ state of their respective neighbors, and then have all the cell-objects ‘switch-to-new’. Finally, have all the cell-objects ‘show-self’ according to their (new) current states. You'll want to repeat this sequence as many times as needed. Your main function, oo-cgol, should accept (as before) two arguments -- a number of times to simulate updates and an initial grid. And of course, oo-cgol should simulate the generations of the grid according to the rules for Conway's Game of Life from the second deliverable.


  1. Top-level constants. As before, you should have top-level identifiers: CELL-SIZE for the size of a rendered cell (either diameter or square edge length); WRAP? that when true causes cells on the edge of the grid to be treated as neighbors of cells on the opposite edges. The size of your display should depend on the CELL-SIZE and the number of rows and columns in your grid.
  2. Cell constructor. Define a cell ‘class’ with a constructor called make-cell-object. This constructor should consume four arguments (in order), an initial state (either 1 or 0), a row index, a column index, and a grid in which the cell object resides. Your cell objects must support the messages and services described above.
  3. Random grid. Modify your function, random-grid that consumes two numbers for row and columns and a third number for the probability of a live cell. Your function should return a grid (as defined with vectors above) that has been appropriately initialized with cell objects.
  4. Updating grids. Write the function, update-CA3, using your previous code for update-CA2. As before, the function should consume and return a grid. However, instead of producing a new grid, it should have the side effect that all the cells have updated their states. That is, cells must persist. As before, the updates around the edges should reflect the current value of WRAP?.
  5. Rendering grids. Write a function, draw-CA3, that ideally will be a modest revision of your draw-CA2 function. Your draw-CA3 should consume a grid under our new definitions and return an image. The size of the resulting image should reflect the CELL-SIZE and the number of rows and columns in the given grid.
  6. Animating the Game of Life. Write a function, oo-cgol, that consumes a number and a grid. The number specifies how many generations to simulate, after which the animation should stop. The given grid represents the initial state of the cellular automata that is subsequently updated/animated. The number of rows and columns necessarily follows from the initial grid that is provided; this should determine the height and width of your animated display.


Do not forget to include the standard acknowledgements header at the top of your file. To grade this deliverable, I will review your code (including contracts, purpose statements, test cases, indentation, etc.), and then call oo-cgol with a given number of steps to simulate and an initial organism of my choosing.

Submit a single file with your username followed by “P3.rkt” as the name of the file, which should contain your code fulfilling the above requirements as well as your acknowledgements.