|
################################################################################ |
|
# conway.py |
|
# |
|
# Original author: electronut.in |
|
# Added vectorization by: David Contreras |
|
# |
|
# Description: |
|
# |
|
# A vectorized Python/matplotlib implementation of Conway's Game of Life. |
|
################################################################################ |
|
|
|
import numpy as np |
|
import matplotlib.pyplot as plt |
|
import matplotlib.animation as animation |
|
|
|
# Define number of rows and columns |
|
|
|
N = 100 |
|
M = 120 |
|
|
|
# Making and array of rows and columns |
|
rows = np.arange(0,N) |
|
columns = np.arange(0,M) |
|
|
|
# Define rows and columns for toroidal boundary conditions - x and y wrap around |
|
top_rows = np.mod(rows-1, N) |
|
bottom_rows = np.mod(rows+1, N) |
|
left_columns = np.mod(columns-1, M) |
|
right_columns = np.mod(columns+1, M) |
|
|
|
# populate grid with random alive / dead - more dead than alive |
|
grid = np.random.choice([0,1], size=(N,M), p = [0.85, 0.15]) |
|
|
|
def update(data): |
|
global grid |
|
total = np.sum( |
|
np.stack( |
|
[ |
|
grid[np.ix_(top_rows, left_columns)], # top left |
|
grid[np.ix_(top_rows, columns)], # top |
|
grid[np.ix_(top_rows, right_columns)], # top right |
|
grid[np.ix_(rows, left_columns)], # left |
|
grid[np.ix_(rows, right_columns)], # right |
|
grid[np.ix_(bottom_rows, left_columns)], # bottom left |
|
grid[np.ix_(bottom_rows, columns)], # bottom |
|
grid[np.ix_(bottom_rows, right_columns)], # bottom right |
|
]), |
|
axis=0) |
|
|
|
newGrid = np.zeros_like(grid) |
|
# apply Conway's rules |
|
newGrid[(grid & (total == 2)) | total == 3] = 1 |
|
# update data |
|
mat.set_data(newGrid) |
|
grid = newGrid |
|
return [mat] |
|
|
|
# set up animation |
|
fig, ax = plt.subplots() |
|
mat = ax.matshow(grid) |
|
ani = animation.FuncAnimation(fig, update, interval=50, save_count=50) |
|
plt.show() |