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) 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) 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 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 = '\n' for y in xrange(ny-1, -1, -1): table += '' for x in xrange(0, nx): if board[x, y]: table += '' else: table += '' table += '\n' table += '
' display_html(table, raw=True) time.sleep(0.1) evolve(40, 100)