Implementing Conway's Game of Life

The Game of Life, created by John Conway in 1970, is perhaps the best known example of cellular automaton. For those unfamiliar, cellular automaton is a collection of cells that live on a grid. Each cell has a state, and each cell has a neighborhood, which can be defined in any number of ways. At each time unit, each cell represents one of a finite set of states, and each update of a cell state is obtained by taking into account the states of the cells in its neighborhood. Cellular automaton are attractive because despite their apparent simplicity, they can be used to model various kinds of complex phenomena in many scientific fields, including biology, physics, and computer science.

Conway’s Game of Life is a zero-player game. In other words, the evolution of the grid of cells is determined by its initial state.

The Rules

We can simplify these rules to have the following:

Implementing in Python

To begin, we will first load the necessary packages to create our implementation of the Game of Life. The NumPy library will be used to create our grid. Matplotlib’s Pyplot and Animation tools will be used to create the visualizations and animations of our game.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

Then, we will create the 100 by 100 grid that the cells live on by creating a NumPy array:

grid = np.random.binomial(1, 0.3, size=([100,100]))

Next, we create the function, called update, that will apply the rules to our cells and give us our updated grid. This function will be used by FuncAnimation to create an animation of the evolution of our cells. The nested for-loops in the code iterates through each cell in our grid and looks at the states of the cell’s neighbors. It does this by finding the sum of the neighboring cells’ states, where live = 1 and dead = 0. It then uses if statements to apply Conway’s rules to determine what the updated state of the cell should be.

def update(data):

    # make a copy of the current version of the grid
    global grid
    newgrid = grid.copy()
    
    # for loop applies Conway's rules to update state of the cell
    for i in range(100):
        for j in range(100):
            leftmost = max(0, j-1)
            uppermost = max(0, i-1)
            cell_value = grid[i,j]
            neighbor_sum = np.sum(grid[uppermost: i+2, leftmost: j+2]) - cell_value
            if neighbor_sum == 3:
                newgrid[i,j] = 1
            if neighbor_sum > 3 or neighbor_sum < 2:
                newgrid[i,j] = 0
    
    # used to display our animation of the grid
    mat.set_data(newgrid)
    grid = newgrid
    return [mat]

Finally, we can write the segment of code to create an animation of our game using FuncAnimation.

fig, ax = plt.subplots()
mat = ax.matshow(grid)
ani = animation.FuncAnimation(fig, update, frames = 200, interval = 100)
plt.show()

Below you will find a gif of the animation of one round of Conway’s Game of Life.