Version 7

At this point we add all the code for the original (non-applet) Life game. There are a huge number of changes just to get all the accesses to work. There are not, however, any fundamentally new ideas involved.

The "Step" button now makes the Life board advance one step.

Top     Version 6     Version 8    

Source code:

import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;    // needed for ActionListener

public class Life extends Applet
{
  static int boardSize = 10;
  Cell [][] board;
  Cell [][] nextBoard;
  Button stepButton;
  MyCanvas canvas;

  /**
   * Creates an empty (all cells dead) playing board of the given boardSize.
   */
  static Cell[][] emptyBoard (int boardSize)
  {
    Cell[][] result = new Cell[boardSize][boardSize];

    for (int i = 0; i < boardSize; i++)
      for (int j = 0; j < boardSize; j++)
        result[i][j] = new Cell ();
    return result;
  }

  public void init ()
  {
    setLayout (new BorderLayout ());

    stepButton = new Button ("Step");
    add (BorderLayout.NORTH, stepButton);

    // Finally, add code to make the button do something
    stepButton.addActionListener (new Step ());

    board = emptyBoard (boardSize);

    // -------------------------------- start of test data

    board[3][4].setAlive (true);
    board[4][5].setAlive (true);
    board[5][3].setAlive (true);
    board[5][4].setAlive (true);
    board[5][5].setAlive (true);

    // -------------------------------- end of test data

    canvas = new MyCanvas (board, boardSize);
    add (BorderLayout.CENTER, canvas);
  }

  class Step implements ActionListener
  {
    public void actionPerformed (ActionEvent e)
    {
      int numberOfNeighbors;

      nextBoard = emptyBoard (boardSize);
      for (int i = 0; i < boardSize; i++)
        for (int j = 0; j < boardSize; j++)
        {
          numberOfNeighbors = Cell.countLiveNeighbors (board, i, j);
          if (board[i][j].getAlive ())
	  {
	    if (numberOfNeighbors == 2 || numberOfNeighbors == 3)
	      nextBoard[i][j].setAlive (true);
	  }
	  else // cell is dead
	    if (numberOfNeighbors == 3)
	      nextBoard[i][j].setAlive (true);
        }
      board = nextBoard;

      // ...then make the changes visible.
      canvas.board = board; // otherwise it still uses the old one
      canvas.paint (canvas.getGraphics ());
      repaint ();
    }
  }
}

class MyCanvas extends Canvas
{
  int boardSize;
  Cell board[][];

  MyCanvas (Cell [][] board, int boardSize)
  {
    this.board = board;
    this.boardSize = boardSize;
  }

  public void paint (Graphics g)
  {
    Dimension d = getSize ();
    int cellWidth = d.width / boardSize;
    int cellHeight = d.height / boardSize;

    for (int i = 0; i < boardSize; i++) {
      for (int j = 0; j < boardSize; j++) {
        if (board[i][j].getAlive ())
	  g.setColor (Color.blue);
	else
	  g.setColor (Color.white);
	g.fillOval (i * cellWidth, j * cellHeight, cellWidth, cellHeight);
      }
    }
  }
}


/**
 * A Cell is one element of a two-dimensional array in John Conway's
 * "Game of Life."  It is either "alive" or "dead."
 * @author Dave Matuszek
 */

class Cell
{
  boolean alive = false;

  /**
   * Constructs a Cell in a given state (alive or dead).
   */
  Cell (boolean alive)
  {
    this.alive = alive;
  }

  /**
   * Constructs a Cell in a "dead" state.
   */
  Cell ()
  {
    this (false);
  }

  /**
   * Sets this cell to be alive or dead.
   */
  void setAlive (boolean alive)
  {
    this.alive = alive;
  }

  /**
   * Returns the state (alive or dead) of this cell.
   */
  boolean getAlive ()
  {
    return alive;
  }

  // Deleted: static boolean isAlive (int i, int j)

  /**
   * Count the number of living cells adjacent to this one.
   * Cells outside the array bounds are considered "dead."
   * This routine has been modified to eliminate references to
   * Life.isAlive ().
   */
  static int countLiveNeighbors (Cell[][] board, int i, int j)
  {
    int limit = Life.boardSize - 1;
    int count = 0;
    for (int ii = i - 1; ii <= i + 1; ii++)
      for (int jj = j - 1; jj <= j + 1; jj++)
      {
	if (ii == i && jj == j) continue;
	if (ii < 0 || ii > limit) continue;
	if (jj < 0 || jj > limit) continue;
	if (board[ii][jj].getAlive ()) count++;
      }
    return count;
  }
}