Implementation of Conway’s game of life written in C++ using SDL2 and Imgui. Source code is available on Github
- Language: C++
- Libraries: SDL2 and Imgui
Introduction
At each step in time , the following transitions occur:
- Any live cell with fewer than two live neighbours dies, as if by underpopulation.
- Any live cell with two or three live neighbours lives on to the next generation.
- Any live cell with more than three live neighbours dies, as if by overpopulation.
- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
Implementation
I used SDL2 for 2D rendering and input, And Imgui for user interface.
The cells are stored in a 2D Array in the Game class in Game.h. The Game class also has all the core logic of the game.
The cells have been rendered using the SDL_RenderFillRect() function which takes a SDL_Rect as a parameter. And the grid lines with SDL_RenderDrawRect().
The cell can be either LIVE or DEAD. All cells in the array are in the default DEAD state when the simulation starts. When the simulation runs, it iterates over every cell and checks its neighbours to determine whether it would live or die based on the above rules.
The Life() function in the Game class first stores all the cells in the m_backupCells
2D array, then it iterates over every cell and calculate the number of neighbours from the m_backupCells
array. Based on the number of neighbours it determine whether the cell would live or die in the next generation and update that information into the m_cells
2D array.
Both the 2D arrays are just boolean arrays storing LIVE or DEAD states as 1 or 0 respectively. And total number of neighbours is the sum of all eight neighbour’s boolean state.
void Game::Life()
{
m_generation++;
for (int y = 0; y < NUM_CELLS; y++)
{
for (int x = 0; x < NUM_CELLS; x++)
{
m_backupCells[y][x] = m_cells[y][x];
}
}
int neighbours = 0;
for (int y = 0; y < NUM_CELLS; y++)
{
for (int x = 0; x < NUM_CELLS; x++)
{
neighbours = m_backupCells[y - 1][x - 1] + m_backupCells[y - 1][x] + m_backupCells[y - 1][x + 1] +
m_backupCells[y][x - 1] + m_backupCells[y][x + 1] +
m_backupCells[y + 1][x - 1] + m_backupCells[y + 1][x] + m_backupCells[y + 1][x + 1];
if (neighbours < 2)
m_cells[y][x] = 0;
else if (neighbours > 3)
m_cells[y][x] = 0;
else if (neighbours == 3)
m_cells[y][x] = 1;
}
}
}
The m_generation
variable just keep track of the number of generations.
For UI it was easy to setup imgui as it already comes with a SDL Renderer backend(imgui_impl_sdlrenderer.h).
There are some interesting effects shown in the Wikipediea page. One of which is called Gosper’s glider gun shown in the above gif.