```
/**
* ConwayLife.java
* The Game of Life is ideally played on an infinite two-dimensional orthogonal grid of
* square cells, each of which is in one of two possible states, alive or dead, or
* "populated" or "unpopulated". Every cell interacts with its eight neighbours, which
* are the cells that are horizontally, vertically, or diagonally adjacent. At each step
* in time, the following transitions occur:
* (1) Any live cell with fewer than 2 live neighbours dies, as if caused by underpopulation.
* (2) Any live cell with 2 or 3 live neighbours lives on to the next generation.
* (3) Any live cell with more than 3 live neighbours dies, as if by overpopulation.
* (4) Any dead cell with exactly 3 live neighbours becomes a live cell, as if by reproduction.
* The initial pattern constitutes the seed of the system. The first generation is created by
* applying the above rules simultaneously to every cell in the seed - births and deaths occur
* simultaneously, and the discrete moment at which this happens is sometimes called a tick
* (in other words, each generation is a pure function of the preceding one). The rules
* continue to be applied repeatedly to create further generations.
* @version 1.0
* @since 1/8/2017
*/

import java.util.Scanner;
import java.awt.Color;
import java.awt.Font;

public class ConwayLife
{
/**    The board object.  If a cell is alive, the value of the cell is true, and if
*     the cell is dead, the value of the cell is false.    */
private boolean [][] board;

/**    The number of rows for the board.  Since the board is square, this is also the
*     number of columns for the board.    */
private final int NUMBEROFROWS = 150;

/**    The edge length, to give the entire board a frame.   */
private final double EDGE = 0.02;

/**    Since the side length is 1, this SIDE will use everything but the edge for the
*     drawing area.    	*/
private final double SIDE = 1 - 2 * EDGE;

/*     The width of an individual cell.        */
private final double CELLWIDTH = SIDE / NUMBEROFROWS;

/**
*  Creates a ConwayLife object, with a sized graphics canvas, and a 2D array
*  of boolean values, with all of them set to false (no live cells) to start with.
*/
public ConwayLife ( )
{
StdDraw.setCanvasSize(800, 800);
board = new boolean [NUMBEROFROWS][NUMBEROFROWS];
for(int i = 0; i < board.length; i++)
{
for(int j = 0; j < board[i].length; j++)
{
board [i][j] = false;
}
}
}

/**
*  Sets up and runs the game of Conway's Life.
*  @param  args     An array of String arguments (the user can pass the name
*  of a text file that indicates the live cells to start with).  If no argument
*  is entered, "p1.txt" is the text file used by default.
*/
public static void main(String [] args)
{
String textFile = "p1.txt";
if(args.length > 0)
{
textFile = args[0];
}
ConwayLife life = new ConwayLife();
life.initializeLife(textFile);
life.runLife();
}

public void initializeLife(String textFile)
{

String temp = null;
int col = 0;
while(infile.hasNext())
{
temp = infile.nextLine();
for(int row = 0; row < temp.length(); row++)
{
if(temp.charAt(row) == '*' && row < board.length && col < board[row].length)
{
board[row][col] = true;
}
}
col++;
}
infile.close();
/*
Scanner infile = OpenFile.openToRead(textFile);      //  This block of code could be used
int row = 0, col = 0;                          //  to read in ordered pairs for live
while(infile.hasNext())                        //  cells from a text file.
{
row = infile.nextInt();
col = infile.nextInt();
board[row][col] = true;
}
infile.close();
*/
//		int aliveCells = 2000;                         //  This block of code could be used to
//		for(int i = 0; i < aliveCells; i++)            //  generate a random configuration of
//		{                                              //  live cells.
//			int randomRow = (int)(Math.random() * board.length);
//			int randomCol = (int)(Math.random() * board[0].length);
//			board[randomRow][randomCol] = true;
//		}
}

/**
*  Runs a loop to show 1200 generations of Conway's Life.
*/
public void runLife ( )
{
int gencount = 0;
StdDraw.show(10);
while(gencount <= 1200)
{
showLife(gencount);
generateNext();
if(gencount == 0)
{
StdDraw.show(500);
}
else
{
StdDraw.show(50);
}
gencount++;
}
}

/**
*  Draws the current generation of Conway's Life to the canvas.
*  @param  gencount     The number of the current generation.
*/
public void showLife(int gencount)
{
StdDraw.setPenColor(new Color(0,0,0));
StdDraw.filledSquare(0.5,0.5,0.5);
StdDraw.setPenColor(new Color(255,255,255));
StdDraw.filledSquare(0.5,0.5,SIDE/2);
for ( int i = 0; i < board.length; i++ )
{
for ( int j = 0; j < board[i].length; j++ )
{
if(board[i][j] == true)
{
StdDraw.setPenColor(new Color(255,0,0));
StdDraw.filledSquare(EDGE + CELLWIDTH * i + CELLWIDTH/2, EDGE + CELLWIDTH * j + CELLWIDTH/2, CELLWIDTH / 2.0);
}
}
}
StdDraw.setPenColor(new Color(0,0,0));
StdDraw.text(0.04, 0.96, "" + gencount);
}

/**
*  Uses the rule for Conway's Life to generate the next generation (see the comment
*  block at the top of this class).  The next generation if saved in a new 2D array,
*  and, once created, is used to replace the previous generation (previous 2D array).
*/
public void generateNext ( )
{
boolean [][] nextboard = new boolean [board.length][board[0].length];

for(int i = 0; i < board.length; i++)
{
for(int j = 0; j < board[i].length; j++)
{
if(countNeighbors(i, j) > 0)       //  Apply the rules
{                                  //  here, by changing/modifying
nextboard[i][j] = true;        //  this if . . .
}
}
}
board = nextboard;
}

/**
*  Counts the neighbors of a given cell, identified by row and col.  The special
*  cases of edges and corners must be considered.
*  @param  row     The row of the current cell.
*  @param  col     The column of the current cell.
*/
public int countNeighbors(int row, int col)
{
int neighborcount = 0;
if(board[row][col] == true)
{
neighborcount++;
}
return neighborcount;
//		for(int i = -1; i <= 1; i++)              //  This nested loop template