Conway's Game of Life

For more on Conway's Game of Life: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

Based on code originally sent to me by @gvwilson.

In [1]:
import numpy as np
from scipy.signal import convolve

# used for counting the number of living neighbors each cell has
FILTER = np.array([[1, 1, 1],
                   [1, 100, 1],
                   [1, 1, 1]], dtype=np.uint8)
In [2]:
def evolve(length, generations):
    """
    Run the Game of Life. Starting state is random.

    Parameters
    ----------
    length : int
        Universe will be `length` units per side.
    generations : int
        Number of generations to run simulation.

    """
    current = np.random.randint(2, size=(length, length))
    next = np.empty_like(current)
    current[length/2, 1:(length-1)] = 1
    show_board(current)
    for _ in xrange(generations):
        advance(current, next)
        current, next = next, current
        show_board(current)
In [3]:
def advance(current, next):
    """
    Calculate the next iteration of the Game of Life.

    Parameters
    ----------
    current : 2D array
        Current state of universe.
    next : 2D array
        This array will be modified in place so that it contains the
        next step. Must be the same size as `current`.

    """
    assert current.shape[0] == current.shape[1], \
           'Expected square universe'
    next[:] = 0
    count = convolve(current, FILTER, mode='same')
    next[(count == 3) | (count == 102) | (count == 103)] = 1
In [4]:
from IPython.display import clear_output, display_html
import time
def show_board(board):
    """
    Print the current Game of Life universe in an HTML table.
    Removes any existing output using `IPython.display.clear_output`
    to make an animation. This doesn't scale well beyond ~50x50 boards.

    Parameters
    ----------
    board : 2D array
        Array representing the current universe.

    """
    clear_output()
    nx, ny = board.shape
    table = '<table style="border-color: black; border-width: 5px;">\n'
    for y in xrange(ny-1, -1, -1):
        table += '<tr>'
        for x in xrange(0, nx):
            if board[x, y]:
                table += '<td style="background: black; border-color: white;"></td>'
            else:
                table += '<td style="border-color: white;"></td>'
        table += '</tr>\n'
    table += '</table>'
    display_html(table, raw=True)
    time.sleep(0.1)
In [5]:
evolve(40, 100)
In [ ]: