This is exercise 2.4.20. from the book Computer Science An Interdisciplinary Approach by Sedgewick & Wayne:
Implement a class that simulates Conway’s Game of Life.
One thing to note: I did not want my grid to have passive edges and so in my program I considered the grid to be an opened torus (for example in a 10-by-10 grid represented by an array: a[9+1][9+1] == a[0][0]). I also tried to make the name of the methods and variables as self-explanatory as possible.
Here is my program:
public class GameOfLife
{
public static boolean[][] randomGridMaker(int n, double p)
{
// n is the number of grid cells in each row or column
// p is the probability of a cell being alive
boolean[][] grid = new boolean[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (Math.random() < p)
{
grid[i][j] = true;
}
}
}
return grid;
}
public static boolean[][] gridEqualizer(boolean[][] a)
{
int n = a.length;
boolean[][] b = new boolean[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = a[i][j];
}
}
return b;
}
public static int liveNeighborCounter(boolean[][] a, int i, int j)
{
int counter = 0;
int n = a.length;
if (a[(i-1)%n][(j-1)%n]) counter++;
if (a[(i-1)%n][j%n]) counter++;
if (a[(i-1)%n][(j+1)%n]) counter++;
if (a[i%n][(j+1)%n]) counter++;
if (a[(i+1)%n][(j+1)%n]) counter++;
if (a[(i+1)%n][j%n]) counter++;
if (a[(i+1)%n][(j-1)%n]) counter++;
if (a[i%n][(j-1)%n]) counter++;
return counter;
}
public static boolean[][] gridUpdater(boolean[][] a)
{
int n = a.length;
boolean[][] b = new boolean[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = a[i][j];
}
}
for (int i = 1; i < n; i++)
{
for (int j = 1; j < n; j++)
{
int liveNeighbors = liveNeighborCounter(a, i, j);
if (!a[i][j] && liveNeighbors == 3) b[i][j] = true;
if (a[i][j])
{
if (liveNeighbors == 1) b[i][j] = false;
if (liveNeighbors > 3) b[i][j] = false;
}
}
}
return b;
}
public static void gridDrawer(boolean[][] a)
{
int n = a.length;
StdDraw.setXscale(0,n);
StdDraw.setYscale(0,n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (a[i][j]) StdDraw.filledSquare(i+0.5,j+0.5,0.47);
}
}
}
public static void main(String[] args)
{
int n = Integer.parseInt(args[0]);
double p = Double.parseDouble(args[1]);
StdDraw.setPenColor(StdDraw.BOOK_BLUE);
StdDraw.enableDoubleBuffering();
boolean[][] a = new boolean[n][n];
boolean[][] b = new boolean[n][n];
a = randomGridMaker(n, p);
while (true)
{
StdDraw.clear();
gridDrawer(a);
StdDraw.show();
StdDraw.pause(50);
StdDraw.clear();
b = gridUpdater(a);
gridDrawer(b);
StdDraw.show();
StdDraw.pause(50);
a = gridEqualizer(b);
}
}
}
StdDraw is a simple API written by the authors of the book. I checked my program and it works. Here are two different instances of it:
Instance 1: n = 20 and p = 0.1:
Instance 2: n = 100 and p = 0.5:
Is there any way that I can improve my program (especially its performance)?
Thanks for your attention.