Skip to content

Commit 898cb45

Browse files
committed
Add doctests for create_canvas, run, and __judge_point
Added comprehensive doctests to Conway's Game of Life implementation. Contributes to #9943
1 parent a71618f commit 898cb45

1 file changed

Lines changed: 85 additions & 9 deletions

File tree

cellular_automata/game_of_life.py

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@
4242

4343

4444
def create_canvas(size: int) -> list[list[bool]]:
45+
"""
46+
Create a square canvas of given size filled with False (dead cells).
47+
48+
Args:
49+
size: The dimension of the square canvas
50+
51+
Returns:
52+
A size x size 2D list of boolean values, all initialized to False
53+
54+
>>> canvas = create_canvas(3)
55+
>>> len(canvas)
56+
3
57+
>>> len(canvas[0])
58+
3
59+
>>> all(all(not cell for cell in row) for row in canvas)
60+
True
61+
>>> create_canvas(1)
62+
[[False]]
63+
>>> create_canvas(0)
64+
[]
65+
"""
4566
canvas = [[False for i in range(size)] for j in range(size)]
4667
return canvas
4768

@@ -54,15 +75,33 @@ def seed(canvas: list[list[bool]]) -> None:
5475

5576
def run(canvas: list[list[bool]]) -> list[list[bool]]:
5677
"""
57-
This function runs the rules of game through all points, and changes their
58-
status accordingly.(in the same canvas)
59-
@Args:
60-
--
61-
canvas : canvas of population to run the rules on.
62-
63-
@returns:
64-
--
65-
canvas of population after one step
78+
Run one generation of Conway's Game of Life on the canvas.
79+
80+
Applies the Game of Life rules to all cells simultaneously to produce
81+
the next generation.
82+
83+
Args:
84+
canvas: 2D list representing current state of cells
85+
86+
Returns:
87+
2D list representing the next generation state
88+
89+
>>> blinker = [[False, False, False, False, False],
90+
... [False, False, True, False, False],
91+
... [False, False, True, False, False],
92+
... [False, False, True, False, False],
93+
... [False, False, False, False, False]]
94+
>>> result = run(blinker)
95+
>>> result[2]
96+
[False, True, True, True, False]
97+
>>> run([[False, False, False], [False, False, False], [False, False, False]])
98+
[[False, False, False], [False, False, False], [False, False, False]]
99+
>>> block = [[False, False, False, False],
100+
... [False, True, True, False],
101+
... [False, True, True, False],
102+
... [False, False, False, False]]
103+
>>> run(block)[1]
104+
[False, True, True, False]
66105
"""
67106
current_canvas = np.array(canvas)
68107
next_gen_canvas = np.array(create_canvas(current_canvas.shape[0]))
@@ -76,6 +115,43 @@ def run(canvas: list[list[bool]]) -> list[list[bool]]:
76115

77116

78117
def __judge_point(pt: bool, neighbours: list[list[bool]]) -> bool:
118+
"""
119+
Apply Conway's Game of Life rules to determine the next state of a cell.
120+
121+
Args:
122+
pt: Current state of the cell (True=alive, False=dead)
123+
neighbours: 3x3 grid including the cell and its 8 neighbors
124+
125+
Returns:
126+
The next state of the cell
127+
128+
Rules:
129+
1. Live cell with <2 live neighbours dies (under-population)
130+
2. Live cell with 2-3 live neighbours survives
131+
3. Live cell with >3 live neighbours dies (over-population)
132+
4. Dead cell with exactly 3 live neighbours becomes alive
133+
134+
>>> __judge_point(
135+
... True, [[True, True, False], [False, True, False], [False, False, False]]
136+
... )
137+
True
138+
>>> __judge_point(
139+
... True, [[True, False, False], [False, True, False], [False, False, False]]
140+
... )
141+
False
142+
>>> __judge_point(
143+
... True, [[True, True, True], [True, True, False], [False, False, False]]
144+
... )
145+
False
146+
>>> __judge_point(
147+
... False, [[True, True, False], [True, False, False], [False, False, False]]
148+
... )
149+
True
150+
>>> __judge_point(
151+
... False, [[True, False, False], [False, False, False], [False, False, False]]
152+
... )
153+
False
154+
"""
79155
dead = 0
80156
alive = 0
81157
# finding dead or alive neighbours count.

0 commit comments

Comments
 (0)