- Notifications
You must be signed in to change notification settings - Fork 46.7k
/
Copy pathconways_game_of_life.py
96 lines (82 loc) · 3.09 KB
/
conways_game_of_life.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
"""
Conway's Game of Life implemented in Python.
https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
"""
from __future__ importannotations
fromPILimportImage
# Define glider example
GLIDER= [
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 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, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
]
# Define blinker example
BLINKER= [[0, 1, 0], [0, 1, 0], [0, 1, 0]]
defnew_generation(cells: list[list[int]]) ->list[list[int]]:
"""
Generates the next generation for a given state of Conway's Game of Life.
>>> new_generation(BLINKER)
[[0, 0, 0], [1, 1, 1], [0, 0, 0]]
"""
next_generation= []
foriinrange(len(cells)):
next_generation_row= []
forjinrange(len(cells[i])):
# Get the number of live neighbours
neighbour_count=0
ifi>0andj>0:
neighbour_count+=cells[i-1][j-1]
ifi>0:
neighbour_count+=cells[i-1][j]
ifi>0andj<len(cells[i]) -1:
neighbour_count+=cells[i-1][j+1]
ifj>0:
neighbour_count+=cells[i][j-1]
ifj<len(cells[i]) -1:
neighbour_count+=cells[i][j+1]
ifi<len(cells) -1andj>0:
neighbour_count+=cells[i+1][j-1]
ifi<len(cells) -1:
neighbour_count+=cells[i+1][j]
ifi<len(cells) -1andj<len(cells[i]) -1:
neighbour_count+=cells[i+1][j+1]
# Rules of the game of life (excerpt from Wikipedia):
# 1. Any live cell with two or three live neighbours survives.
# 2. Any dead cell with three live neighbours becomes a live cell.
# 3. All other live cells die in the next generation.
# Similarly, all other dead cells stay dead.
alive=cells[i][j] ==1
if (aliveand2<=neighbour_count<=3) or (
notaliveandneighbour_count==3
):
next_generation_row.append(1)
else:
next_generation_row.append(0)
next_generation.append(next_generation_row)
returnnext_generation
defgenerate_images(cells: list[list[int]], frames: int) ->list[Image.Image]:
"""
Generates a list of images of subsequent Game of Life states.
"""
images= []
for_inrange(frames):
# Create output image
img=Image.new("RGB", (len(cells[0]), len(cells)))
pixels=img.load()
# Save cells to image
forxinrange(len(cells)):
foryinrange(len(cells[0])):
colour=255-cells[y][x] *255
pixels[x, y] = (colour, colour, colour)
# Save image
images.append(img)
cells=new_generation(cells)
returnimages
if__name__=="__main__":
images=generate_images(GLIDER, 16)
images[0].save("out.gif", save_all=True, append_images=images[1:])