16/05/2019

Arduino LED Matrix “Game of Life”

By snorlaxprime

I was reading a post about someone making a Thanos Gauntlet and simulating wiping off half of the population randomly. So I thought about the “Game of Life” simulation. If you want to know more about “Game of Life” you can read it all up here. So why not trying to make this simulation based on my previous build of the 8×8 LED Matrix. The circuit can be found below:

Using the previous build, I made a few adjustment to the code to simulate the game of life. The first thing to note is to initialise the 8×8 variable to hold the initial life form, the next variable is the next stage after the life form evolved, this is shown as below:

bool field[8][8] = {};
bool nextfield[8][8] = {};

When the program start, we randomly assign the 8×8 matrix with zeros and ones to simulate the initial stage, this is shown in the following code. The code will only be executed when the button is pressed longer than the threshold defined by variable debounce. I define this to be 50ms.

if (buttonpressed == HIGH && millis() - time > debounce){ // set random life
time = millis();
started = false;
for (int i = 0; i<8; i++) {
for (int j = 0; j<8; j++){
field[i][j] = random(2);
Serial.print("field["); Serial.print(i); Serial.print("]["); Serial.print(j);
Serial.print("]:");
Serial.println(field[i][j]);
}
}
delay(200);
started = !started; // start the Game of Life simulation
}

Right after the initialisation, the code will set the started variable to true. The program will calculate the next field at every iteration this is done by calling the fillNextField() function, shown in the following code.

}else if (started){
// calculate next field
if (millis() - 1000 > lastMillis) {// delay each iteration by 1000 ms
fillNextField();
for (int x = 0; x<8; x++){
for (int y = 0; y<8; y++) {
field[x][y] = nextfield[x][y];
}
}
lastMillis = millis();
}
}

The rule of Game of Life is as below. Each cell’s existence depends on all the other 8 cells that are surrounding it.

  1. Any live cell with fewer than 2 live neighbours dies, as if by underpopulation
  2. Any live cell with two or three live neighbours lives on to the next generation (cycle)
  3. Any live cell with more than three live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly 3 live neighbours becomes a live cell, as if by reproduction.

Based on the logic above the getCellsNextState(int x, int y) function is being developed as shown below:

//returns the cell's next state, true if alive, false otherwise
bool getCellsNextState(int x, int y) {
bool shouldBeAlive = false;
shouldBeAlive |= (!field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 3);
shouldBeAlive |= (field[y][x] && countAliveNeighbours(x, y) == 2);
return shouldBeAlive;
}

As you can see the CountAliveNeighbours(x,y) function will count the number of alive neighbours around the cell. This is done by simply iterating from the one cell before and after in x coordinate and one cell before and after in y coordinate. Then we define the boundary condition as per our LED matrix boundary, which is 8 cells x 8 cells. And finally we count how many live cells as per below function.

// counts the alive neighbours this step
int countAliveNeighbours(int x, int y) {
int retVal = 0;
for (int row = y - 1; row <= y + 1; row++) { for (int col = x - 1; col <= x + 1; col++) { if ((row == y && col == x) || (row < 0) || (row > 7) || (col < 0) || (col > 7)) continue;
if (field[row][col]) retVal++;
}
}
return retVal;
}

If all goes well, you should see the following Game of Life simulation similar to the following video.

Congratulations, how you are able to simulate this classic Game of Life and you can modify this to your heart’s content. What you can do next is to stop the simulation and wipe off half of the live form like what Thanos did, and feel the power of the Infinity Gauntlet.

Please share or comments if you like this post, and let me know if you have any questions related to this.