V22.0101 Homework Assignment 4 Spring 2007
The Game of Life

Assigned: MON MAR 19
Due: Draft #1, SUN APR 1, 11:59 pm
Draft #2, THURS APR 12, 11:59 pm (Honors students required to do this)
Honors draft #2, SUN APR 15, 11:59 pm
Final Exam:MON MAY 7, 10:00 -11:50. rm 109 WWH

Draft #1

Consider a two dimensional array with M rows and N columns. This represents the world in which some organisms live. Each of the M by N cells in this array is either occupied (if an organism lives there) or is vacant. No more than one organism can live in any one cell at any time. Each cell, except those on the boundaries (the edge of the world), has exactly eight neighboring cells (above, below, left, right, and four diagonals). The cells on the boundaries have less than eight neighboring cells.

Initially, there is a given population of organisms occupying certain of the cells. At each succeeding generation, the organisms reproduce and die as follows:

• Each organism of the current generation survives to the next generation if, and only if, it has 2 or 3 neighbors (a neighbor is an organism that lives in a neighboring cell). Otherwise, it dies and its cell becomes empty in the next generation. Note: it dies if it is ``lonely'' or ``overcrowded''.

• Each vacant cell in the current generation becomes occupied by a new organism in the next generation if, and only if, it has exactly 3 neighbors. Otherwise, it remains vacant in the next generation.

For example, suppose the initial world (the ``zero"th generation) is as follows, using X to indicate the occupied cells and blanks for the vacant cells:

```                  X X
XXX                XX       XXXX
X X       XX
```
Then the next generation is
```          X                           XX
X                 XX        XX
X                 XX        XX
```

On the input file, the blanks are represented by dots.

Write a program to play this Game of Life. Your program should read the initial world from a file (see below) and repeatedly generate new generations, prompting the user each time to see if he or she wants to see the next generation or terminate the program. Also, the program should terminate automatically if the world becomes empty, (use isEmpty()for this) displaying a message accordingly (this will happen for life3.dat).

Use two-dimensional arrays of type char to store the old and new generations respectively. To keep things simple, assume that M=25 and N=75, i.e. the world has 25 rows and 75 columns, and define these in a final statement before declaring your array variables.

Data files for testing your program will be provided on the home page. You should make sure your program works correctly on all these files, and you should also try your own test data. Download these files simply by choosing save Target link as when the cursor is on the specific file on the The Data for the Game of Life page and the mouse right button is pressed. If you type .dat after the file name, it will be saved as dat file. Thus your program would read for instance, file0.dat. The program should prompt the user for the name of the input file (use a String variable).

Programming Details

You need two 2-dimensional arrays---the new generation should be created based on information from the old generation. If you use only one array, you will find that your old generation is overwritten by the new one before you have finished using all the information you need from it.

You should create a ``border'' of cells that always stay empty by declaring your arrays from 0 to M+1 and from 0 to N+1. This way, the cells on the edge will also have eight neighboring cells and won't need special treatment.

Include at least two non-void methods. One should take a world and the coordinates of a cell and return the number of neighbors (organisms in neighboring cells) that the cell has. The other should take a generation array and return a Boolean value that tells whether or not the world represented by the array is empty.

Write all generations to the screen (don't forget the generation numbers), with a prompt to the user to type a key when ready to see the next one.

You can see how the game, as described so far, works by connecting to the web page and running the program there on the Demo for different worlds link. However, your program should not be an applet; it should be a Java application.

Once your program is working, also terminate if the world is the same as the previous one (this will happen for life4.dat). Use isSame() for this.

Draft #2

Have your program of the first draft run as a Swing application using JFrame and JPanel. The program should use the sleep method to pause after each generation. The only way to print on a panel is to use the instance g (or g2), e.g.,g.showString(String, x, y) prints the string String at coordinates x, y. The method that prints data on a panel must be called from paintComponent() since g is required. You may "hardwire" the file name of the initial world or read it using JOtionPane or ConsoleReader. Use the following for your paintComponent() method.

```public void paintComponent(Graphics g)
{
if(flag)//skips executing paintComponent on first call
{
super.paintComponent(g);//erases panel Contents
g.setColor(Color.yellow);
if(!flag1 && !flag2)//not isSame nor isBlank
{
writeEm(g);//prints the world
}
else if( flag1)
{
g.drawString("The worlds are repeating!", 10, 250);
}
else //flag2 is true
{
g.drawString("The world is blank!", 10, 250);
}
}
else
flag = true;
}
```

As in draft #1, use grid as the two-dimensional array; but now it should be an instance variable (i.e., global). The boolean variable flag is originally set to false, flag1 is set in isSame() and flag2 in isBlank(). The variable flag is used since show() which precedes the call to start the evolution of the worlds, envokes paintComponent(). If flag is not false, paintComponent() would call writeEm() before grid is initialized, producing a null pointer exception.

You call paintComponent() by executing repaint(); repaint() is incorported into the system. You do not write it!

At the risk of repeating infomation, we state the following:

1. paintComponent() does all the display.
2. You call paintComponent() using repaint().
3. show() not only displays the panel but calls paintComponent() as well.
4. You draw on a panel.
5. You must set the layout on a panel. This is done with setLayout().
6. A panel is a GUI and all GUIs must be placed on the ContentPane. This is done by setContentPane(panel).
7. The program class you write, here Class Life, must be added to the panel. This is done by panel.add(life)

Michael Overton & Samuel Marateck
SUN MAR 18 22:23:14 EST 2007