#!/usr/bin/env python # coding: utf-8 # # Conway's Game of Life # # This is a (slightly) modified version of [Glowing Python](# http://glowingpython.blogspot.co.il/2015/10/game-of-life-with-python.html # )'s code. I make it available here because it features a few nice things: # # * how to make a movie using matplotlib.animation # * how to write a generator (function with yield) # * how to plot a sparce array (```spy```) # # See the result on my website, [yairmau.com](yairmau.com), specifically the page [/tutorials/python](yairmau.com/tutorials/python). # In[1]: import numpy as np from matplotlib import pyplot as plt import matplotlib.animation as manimation def life(X, steps): """ Conway's Game of Life. - X, matrix with the initial state of the game. - steps, number of generations. """ def roll_it(x, y): # rolls the matrix X in a given direction # x=1, y=0 left; x=-1, y=0 right; return np.roll(np.roll(X, y, axis=0), x, axis=1) for _ in range(steps): # count the number of neighbours # the universe is considered toroidal Y = roll_it(1, 0) + roll_it(0, 1) + \ roll_it(-1, 0) + roll_it(0, -1) + \ roll_it(1, 1) + roll_it(-1, -1) + \ roll_it(1, -1) + roll_it(-1, 1) # game of life rules X = np.logical_or(np.logical_and(X, Y == 2), Y == 3) X = X.astype(int) yield X # In[2]: dimensions = (90, 160) # height, width X = np.zeros(dimensions) # Y by X dead cells middle_y = dimensions[0] / 2 middle_x = dimensions[1] / 2 N_iterations = 600 # acorn initial condition # http://www.conwaylife.com/w/index.php?title=Acorn X[middle_y, middle_x:middle_x+2] = 1 X[middle_y, middle_x+4:middle_x+7] = 1 X[middle_y+1, middle_x+3] = 1 X[middle_y+2, middle_x+1] = 1 # In[3]: FFMpegWriter = manimation.writers['ffmpeg'] metadata = dict(title='Game of life', artist='Acorn initial condition') writer = FFMpegWriter(fps=10, metadata=metadata) fig = plt.figure() fig.patch.set_facecolor('black') with writer.saving(fig, "game_of_life.mp4", 300): # last argument: dpi plt.spy(X, origin='lower') plt.axis('off') writer.grab_frame() plt.clf() for i, x in enumerate(life(X, N_iterations)): plt.title("iteration: {:03d}".format(i + 1)) plt.spy(x, origin='lower') plt.axis('off') writer.grab_frame() plt.clf()