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

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.