This version of GameOfLife.java have the game board grid stores an int instead of boolean, which is easier for generalize. For step by step simulation, we can calculate the next generation's value based on previous generations.
public class GameOfLife {
static int countSurrounding(int[][] board, int a, int b) {
int count = 0;
int[][] surroundings = { { a - 1, b - 1 }, { a - 1, b },
{ a - 1, b + 1 }, { a, b - 1 }, { a, b + 1 }, { a + 1, b - 1 },
{ a + 1, b }, { a + 1, b + 1 } };
for (int surrounding[] : surroundings) {
try {
if (board[surrounding[0]][surrounding[1]] == 1) {
count++;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
}
return count;
}
static void visualizeBoard(int[][] board) {
for (int row[] : board) {
for (int cell : row) {
System.out.print(cell == 1 ? "#" : ".");
}
System.out.println();
}
System.out.println();
}
private static int nextCellState(int[][] board, int i, int j) {
int count = countSurrounding(board, i, j);
if (board[i][j] == 1 && (count == 2 || count == 3)) { // stay alive rule
return 1;
}
if (board[i][j] == 0 && count == 3) { // birth new rule
return 1;
}
return 0;
}
public static int[][] nextGeneration(int[][] board) {
int next[][] = new int[board.length][board[0].length];
int rows = board.length;
int cols = board[0].length;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
next[i][j] = nextCellState(board, i, j);
}
}
return next;
}
static final int[][] initialBoard = new int[10][10]; //default 0
public static void main(String[] args) {
initialBoard[0][1] = initialBoard[0][2] = initialBoard[0][3] = initialBoard[0][4] = 1; //seeds
int[][] board = new int[initialBoard.length][initialBoard[0].length];
// copy over the initial board
for (int i = 0; i < initialBoard.length; i++) {
for (int j = 0; j < initialBoard[i].length; j++) {
board[i][j] = initialBoard[i][j];
}
}
// loop over 25 generations
visualizeBoard(board);
for (int gen = 0; gen < 25; gen++) {
System.out.println("\nGeneration " + gen);
board = nextGeneration(board);
visualizeBoard(board);
}
}
}