Note
This notebook can be downloaded here: Scientific_Python_Tutorial.ipynb
Code author: Ludovic Charleux ludovic.charleux@univ-smb.fr
A Scientific Python Tutorial: Coding Game of Life (GoL)¶
Part 1: Introduction¶
Introductory readings¶
What is GoL ?¶
GoL is not really a game as long as players are not required. It is played on a chessboard-like grid on which cells exist in two states: dead (0) and alive (1). The state of the cells evolve at every step depending on two rules : * The survival rule (S): in GoL, if a living cell has 2 or 3 living cells among its neighbors, it stays alive, otherwise it dies. * The birth rule: (B): if a cell has 3 living cells among its neighbors, it gets alive.
Don’t hesitate to try existing online simulators to understand how the game works: https://bitstorm.org/gameoflife/
Part 2: Counting living neighbors¶
In this part, you will learn how to count the number of neighbors around a each cell.
%matplotlib nbagg
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation, rc, cm
rc('animation', html='html5')
We can easily create a random binary matrix usin numpy
cells = np.random.randint(2, size = (5, 5))
cells
array([[1, 1, 1, 0, 1],
[1, 1, 1, 1, 1],
[0, 1, 0, 0, 0],
[1, 0, 0, 1, 0],
[0, 1, 1, 1, 0]])
plt.figure()
plt.imshow(cells, cmap = cm.gray)
plt.colorbar()
plt.show()
<IPython.core.display.Javascript object>
Now, you need to find a way to calculate the number of living (1) neighbors around every cell.
Tips: * Try several methods and determine which one is the best for you, * The use numpy’s slicing can help, * Boundary conditions are importants.
Neighbors counts can be stored in a matrix like the following one:
neighbors = np.zeros_like(cells)
neighbors
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
Part 2: Creating a class¶
Now that you master neighbors counting, it is time to create a class to manage the evolution of the cells count. An embryo of GoL class is given below:
class GoL:
"""
A game of life class.
"""
def __init__(self, cells):
self.cells = np.array(cells)
def __repr__(self):
return "<GoL with {0} cells>".format(self.cells.size)
def count_living_neighbors(self):
"""
Counts the number of living neighbors of each cell.
"""
# to be completed.
return
def step(self):
"""
make an evolution step forward.
"""
# to be completed.
return
g = GoL(cells)
g
<GoL with 25 cells>
Part 3: animate your work¶
Now, it’s time to animate your work. For that purpose, you can use a modified version of the following code that animates a random image:
class RandomImage:
"""
Creates a random image.
"""
def __init__(self, size = (5,5), depth = 8):
self.size = size
self.depth = depth
self.evolve()
def evolve(self):
"""
Randomizes the image
"""
self.image = np.random.randint(self.depth, size = self.size)
ri = RandomImage( size = (50, 50))
def updatefig(*args):
ri.evolve()
im.set_array(ri.image)
return im,
fig, ax = plt.subplots()
ax.axis('off')
im = plt.imshow(ri.image, interpolation = "nearest", cmap = cm.gray, animated=True)
anim = animation.FuncAnimation(fig, updatefig, frames=40, interval=50, blit=True)
#plt.show()
plt.close()
anim
<IPython.core.display.Javascript object>
Part 4: Other rules¶
GoL is just the set of rules B3/S23 in the wider group of Life-like cellular automatons: https://en.wikipedia.org/wiki/Life-like_cellular_automaton
Modify your work in order to be able to simulate other rules.