# 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 :
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 :
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):
current, next = next, current
show_board(current)

In :
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 == current.shape, \
'Expected square universe'
next[:] = 0
count = convolve(current, FILTER, mode='same')
next[(count == 3) | (count == 102) | (count == 103)] = 1

In :
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 :
evolve(40, 100)

In [ ]: