Lab 9: Classes, interfaces, and encapsulation

This project gives you practice writing classes that implement provided interfaces.

Clone the repository for this week's lab:

hg clone /cslab/class/csci235/lab9

Read the entire lab before you start coding. You need to have the big picture in mind. There are also some tips at the end about how you might break up the work into testable phases.

1. Introduction

Mathemematician John Conway invented the Game of Life as an exploration of a model of computation known as cellular automata. The rules are very simple, but the patterns produced can be entertaining. In today's lab you will implement the core of the game, working with a GUI that I have provided.

The world is a rectangular grid, and each cell (location) in the grid is either alive or dead. At every turn, each cell computes whether it will be alive or dead in the following turn, based on these rules:

Note that the computation is local, occurring in each cell at the same time, depending solely on its own state and the state of its eight immediate neighbors.

2. The structure of the simulation

You have been provided with two interfaces, Grid and Cell, that define the methods for those two components of the simulation. Your job is to write classes LifeGrid and LifeCell that implement these interfaces.

The additional information that you need is that the constructor for LifeGrid takes two integer parameters, specifying the number of rows and columns, respectively, in the grid to be created. That constructor needs to create the grid and populate it with initially-dead instances of LifeCell. After it has created all of the cells, it then needs to iterate over the cells to tell each of them about all of its neighbor cells (calling addNeighbor()).

Note that a way to get started on each of LifeCell.java and LifeGrid.java would be to copy the corresponding interface file. To copy one of them and inform Mercurial about it, you can use a command like

hg copy Grid.java LifeGrid.java
If you create the file in some other way, you'll need to tell Mercurial to keep track of it with
hg add LifeGrid.java
Don't forget to commit your work to Mercurial at reasonable points.

3. Running the simulation

You can run the simulator with the command

java -cp .:life.jar ConwayLife

You'll see a picture of the grid; dead cells are black, live cells are green. If you click on a cell, its state will be toggled (calling the toggle() method you wrote). If you clock on the Step button, it will call your grid's plan() method and then its act() method before redisplaying the world.

To help you out a bit, the method that displays the grid uses two extra colors: index-out-of-bounds exceptions show up in yellow, and null pointer exceptions show up in red.

If you add two integers to the command line, you can specify the number of rows and columns for the world you create.

4. Working in stages

There is quite a bit to do here; it will be important to figure out how to do it in stages so that you can test pieces as you proceed. You can do that by providing dummy versions of methods methods at first, then replacing them as you get pieces working. Here are some observations that may help.

5. Turn in

Turn in the source files you modified (LifeCell.java and LifeGrid.java) as lab9.

Don't forget to copy the code to your own account.


Cary Gray (with code from Thomas VanDrunen)
Last modified: Fri Oct 21 11:05:23 CDT 2011