-
Notifications
You must be signed in to change notification settings - Fork 0
/
conway.py
103 lines (85 loc) · 2.98 KB
/
conway.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import sys
import argparse
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
OFF = 0
ON = 255
vals = [ON, OFF]
def randomGrid(N):
"""returns a grid of NxN random values"""
return np.random.choice(vals, N*N, p=[0.2, 0.8]).reshape(N,N)
def addGlider(i, j, grid):
"""adds a glider with top left cell at (i, j)"""
glider = np.array([[0, 0, 255],
[255, 0, 255],
[0, 255, 255]])
grid[i:i+3, j:j+3] = glider
def update(frameNum, img, grid, N):
# copy grid since we require 8 neighbors for calculation
# and we go line by line
newGrid = grid.copy()
for i in range(N):
for j in range(N):
# compute 8-neighbor sum using toroidal boundary conditions
# x and y wrap around so that the simulation take place on a toroidal surface
total = int((grid[i, (j-1)%N] + grid[i, (j+1)%N] +
grid[(i-1)%N, j] + grid[(i+1)%N, j] +
grid[(i-1)%N, (j-1)%N] + grid[(i-1)%N, (j+1)%N] +
grid[(i+1)%N, (j-1)%N] + grid[(i+1)%N, (j+1)%N]) / 255)
# apply conways rules
if grid[i, j] == ON:
if(total < 2) or (total > 3):
newGrid[i, j] = OFF
else:
if total == 3:
newGrid[i, j] = ON
# update data
img.set_data(newGrid)
grid[:] = newGrid[:]
return img,
# main method
def main():
# parse arguments
parser = argparse.ArgumentParser(description="Conway's Game of Life Simulation")
# add arguments
parser.add_argument('--grid-size', dest='N', required=False)
parser.add_argument('--mov-file', dest='movfile', required=False)
parser.add_argument('--interval', dest='interval', required=False)
parser.add_argument('--glider', action='store_true', required=False)
args = parser.parse_args()
# grid size
N = 100
if args.N and int(args.N) > 8:
N = int(args.N)
# animation update interval
updateInterval = 50
if args.interval:
updateInterval = int(args.interval)
# make grid
grid = np.array([])
if args.glider:
grid = np.zeros(N*N).reshape(N,N)
addGlider(1, 1, grid)
else:
# randomize grid population
grid = randomGrid(N)
# configure animation
fig, ax = plt.subplots()
img = ax.imshow(grid, interpolation='nearest')
ani = animation.FuncAnimation(fig, update, fargs=(img, grid, N, ),
frames=10, interval=updateInterval,
save_count=50)
# number of frames?
# set the output file
if args.movfile:
ani.save(args.movfile, fps=30, extra_args=['-vcodec','libx264'])
plt.show()
# call main
if __name__ == '__main__':
main()
# grid = np.zeros(N*N).reshape(N, N)
# addGlider(1, 1, grid)
# x = np.array([[0 ,0, 255], [255, 255, 0], [0, 255, 0]])
# plt.imshow(x, interpolation='nearest')
# plt.show()