University of Virginia, Department of Computer Science
CS201J: Engineering Software, Fall 2003

Problem Set 1: Game of Life Out: 28 August 2003
Due: Tuesday 2 September, beginning of class

Collaboration Policy - Read Carefully

For this problem set, you should work alone, but feel free to ask other students for help and offer help to other students.

Purpose

Background

Cellular automata are computer simulations inspired by biological cells. An automata simulation starts with a grid of cells, where each cell is initialized to a particular state. At each step in a simulation, the next state of each cell is determined based on simple rules that depend on its current state and the current states of its neighbors.

Despite their simplicity, cellular automata can produce complex and interesting patterns. We have provided you with code that implements a cellular automata simulator. You are encouraged to look over the code, but you do not need to understand this code now and should not be concerned if it doesn't all make sense yet as it uses concepts that we will not encounter until later in the course.

The cellular automata simulator takes a Java class that defines the rules for each step, and simulates a grid of cells. Each cell can be in one of two states: dead or alive. A dead cell is shown as a white square and a live cell is shown as a green square. Each cell has neighbors which are the eight cells that surround it.

The file ExtremeLifeCell.java defines an example cell class that implements the game of Extreme Life in each step any cell with at least one alive neighbor will become alive. So, if we start with one live cell, after one step every cell touching it will be alive. This will continue until the entire grid is full of live cells.

Running Extreme Life

Downloads: You will need to download this file to your machine: ps1.zip

The following steps will create an Eclipse project containing the provided source code for Problem Set 1:

Eclipse automatically compiles Java projects when they are imported. Also, whenever you make a change to a Java source file and save it, the changes are automatically compiled. If you want to rebuild the entire project, select Project | Rebuild All.

Try running the cellular automata simulator using the provided ExtremeLifeCell class to model each cell. To do so, click on Run | Run from the Eclipse menu bar. Select Java Application as the configuration on the left. Enter CellAutomata for the main class. Then click on the Arguments tab and enter ExtremeLifeCell into the program arguments text window. Click on the Run button on the bottom right of the window.

Eclipse will run the Java virtual machine, which starts by calling the main method of the CellAutomata class. The command line arguments (ExtremeLifeCell) are passed as a parameter to the main method, which loads the ExtremeLifeCell class and initializes the grid to contain an ExtremeLifeCell object in each square.

When the simulator starts, click on a cell and wait for it to turn green. Then press start and observe how the game operates by the extreme life rules.

The Cellular Automata Simulator

The implementation of this cellular automata contains modules for providing the graphical user interface, maintaining a grid of cells, and implementing the rules for a given cell. Here we provide a description of some of the most important classes, but you do not need to understand the details of how these classes are implemented.

CellAutomata.java

This is the main class for the implementation of the cellular automata. It sets up the user interface using Swing. It can load any cellular automata cell class of your choosing and runs a thread that calls the cells every so often to update their state. To load a specific cell class, you specify the cell class as a program argument when running the Java application. To test the class your create, replace ExtremeLifeCell with the name of your cell class. (Note that the .class extension should not be included.)

CellGrid.java

This class keeps track of all the states of the cells on the board. The most important method of the CellGrid class is step which excutes one step in the simulation:
	
public void step()
  // MODIFIES: this
  // EFFECTS: Executes one step for each cell in the grid.  Each cell first caluclates its next
  //    state based on the current state of itself and its neighbors.  Then, all cells advance
  //    to their next state.
{
    CellState [][] nextStates = new CellState[x_max+1][y_max+1];
    
    // Because we need to update all cells synchronously, we first calculate the next state
    // for each cell, and store it in a temporary array.  Then, we update all the cells.
    
    for (int x = 0; x <= x_max; x++)
    {
	for (int y = 0; y <= y_max; y++)
	    {
		Cell cell = (Cell) getObjectAt(x,y);
		nextStates[x][y] = cell.getNextState();
		
	    }
    }
    
    for (int x = 0; x <= x_max; x++)
    {
	for (int y = 0; y <= y_max; y++)
	{
	    Cell cell = (Cell) getObjectAt(x,y);
	    cell.setState(nextStates[x][y]);
	}
    }
}
CellState.java
This class implements a datatype for recording the state of a cell. It includes these methods:
   public class CellState
   {
      // OVERVIEW: A CellState is an immutable object that represents
      //           the state of a cell, either alive or dead.

    static public CellState createAlive()
       // EFFECTS: Returns an alive cell state. 
    
    static public CellState createDead ()
       // EFFECTS: Returns a dead cell state. 

    public boolean isAlive ()
       // EFFECTS: Returns true iff this is alive.
   }
The methods with static modifies are class methods. They are not invoked on an object (there is no this). Instead, call them as CellState.createAlive () and CellState.createDead ().
Cell.java
This class provides a basic Cell implementation. It includes these methods:
    public boolean setState (CellState s) 
       // MODIFIES: this 
       // EFFECTS: Sets the cell's current state to s.  Returns true iff the new
       //    state is different from the current state.
       
   CellState getState ()
       // EFFECTS: Returns the cell's current state.

   boolean isAlive ()
       // EFFECTS: Returns true if the cell is alive, false otherwise.

   int countAliveNeighbors ()
       // EFFECTS: Returns a count of the cell's live neighbors.

   public CellState getNextState()
       // EFFECTS: Returns next state value for this.
       //    For the underlying Cell class, the next state is always the
       //    current state.
To produce cellular automata with interesting behavior, you will produce a subtype of the Cell class and override the getNextState method to do something more interesting.
ExtremeLifeCell.java
This class implements a cell that follows the Extreme Game of Life rules described above. We use extends Cell to indicate that the ExtremeLifeCell class is a subtype of Cell. This means it inherits the non-private methods from the Cell class. To implement a new cell behavior, we need to provide a new implementation of the getNextState method:
public class ExtremeLifeCell extends Cell 
{
    public CellState getNextState ()
       // EFFECTS: Returns the next state for this cell.
       //          The next state will be alive if this cell or any of its neighbors
       //          is currently alive.
    {
        if (countAliveNeighbors () > 0) { 
            // If the cell has at least one neighboring cell
            // that is alive, this cell should become alive.
            return CellState.createAlive (); 
        } else { 
            // Otherwise, the cell maintains its previous state.
            return getState ();
        }
    }
}

Conway's Game of Life

John Conway, a Cambridge mathemetician, invented the game of life with these simple rules:

Assignment: Using the ExtremeLifeCell.java code as an example, produce a ConwayLifeCell.java file containing a class that implements the Conway's Game of Life cellular automaton. To create a new class in Eclipse, select File | New | Class fron the Eclipse main menu, and enter the class name (ConwayLifeCell in the Name field. Change the superclass to Cell. Eclipse will generate a stub class file for you. You will need to provide an implementation of the getNextState method that implements the Conway's Game of Life rules.

With these simple rules, it is possible to produce many interesting patters. For example, if you start with three cells in a row it should produce a blinker that alternates between three horizontal and three vertical live cells. Experiment with different initial conditions to see what happens.

Turn-in Checklist: Turn in your ConwayLifeCell.java code.


Related links:

Credits: This problem set was developed for UVa CS 201J Fall 2002 by Mike Peck, Tiffany Nichols and David Evans and revised for UVa CS201J Fall 2003 by Mike Peck, John Franchak and Leonid Bolotnyy.


CS201J University of Virginia
Department of Computer Science
CS 201J: Engineering Software
Sponsored by the
National Science Foundation
cs201j-staff@cs.virginia.edu