public class Automata2D { /* The 2D arrays for our old and new generation of the automata */ int[][] oldGeneration; int[][] newGeneration; /* We need to keep track of how big each cell is, and how many rows (cellHeight) and columns (cellWidth) their are. */ int cellSize; int cellWidth; int cellHeight; public Automata2D(int cell_) { // Save our parameter and calculate the array sizes cellSize = cell_; cellWidth = width / cellSize; cellHeight = height / cellSize; // Create our automata arrays oldGeneration = new int[cellWidth][cellHeight]; newGeneration = new int[cellWidth][cellHeight]; // start the board with a random cell arrangement randomize(); } public void randomize() { // Randomly turn on or off various cells in the oldGeneration for (int x = 0; x < cellWidth; x++) { for (int y = 0; y < cellHeight; y++) { if ( random(1.0) < 0.5) { oldGeneration[x][y] = 1; } else { oldGeneration[x][y] = 0; } } } } public void simulate() { update(); render(); } public void update() { // We need to loop over each cell in the oldGeneration, and // figure out what that cell will be like in the newGeneration for (int x = 0; x < cellWidth; x++) { for (int y = 0; y < cellHeight; y++) { int neighbors = 0; // As a short cut, figure out what the index numbers // are for X+1 X-1 and Y+1 Y-1, we use the modulus // so that the borders of our array "wrap" around to // the other side int c_xmo = (x + cellWidth - 1) % cellWidth; int c_xpo = (x + 1) % cellWidth; int c_ymo = (y + cellHeight - 1) % cellHeight; int c_ypo = (y + 1) % cellHeight; // Check the row above if (oldGeneration[c_xmo][c_ymo] == 1) { neighbors++; } if (oldGeneration[x ][c_ymo] == 1) { neighbors++; } if (oldGeneration[c_xpo][c_ymo] == 1) { neighbors++; } // check this row if (oldGeneration[c_xmo][y ] == 1) { neighbors++; } if (oldGeneration[c_xpo][y ] == 1) { neighbors++; } // check the row below if (oldGeneration[c_xmo][c_ypo] == 1) { neighbors++; } if (oldGeneration[x ][c_ypo] == 1) { neighbors++; } if (oldGeneration[c_xpo][c_ypo] == 1) { neighbors++; } // Apply the logic of our Game of Life if (oldGeneration[x][y] == 1) { if (neighbors < 2) { // Old is alive, and has less than 2 neighbors // Die of Lonliness newGeneration[x][y] = 0; } else if (neighbors > 3) { // Old is alive, and has more than 3 neighbors // Die of Overpopulation newGeneration[x][y] = 0; } else { // Old is alive, and has 2 or 3 neighbors // Stay Alive newGeneration[x][y] = 1; } } else { if (neighbors == 3) { // Old is dead, and has 3 neighbors // Reproduction newGeneration[x][y] = 1; } else { // Old is dead, and conditions aren't right for reproduction // Stay dead newGeneration[x][y] = 0; } } } } // We need to swap the old and new generation now, as we // do all of our drawing and calculations of oldGeneration int[][] tmp = oldGeneration; oldGeneration = newGeneration; newGeneration = tmp; } public void render() { // draw each cell fill(255); noStroke(); for (int x = 0; x < cellWidth; x++) { for (int y = 0; y < cellHeight; y++) { if (oldGeneration[x][y] == 1) { rect(x * cellSize, y * cellSize, cellSize, cellSize); } } } } }