Skip to content

Commit 2ece0cf

Browse files
committed
GoL_fast: Add fast PropertyLayer implementation of Game of Life
A special implementation of Conway's Game of Life, using only the PropertyLayer, without needing a Grid or even any Agents.
1 parent 3e5ebd1 commit 2ece0cf

File tree

1 file changed

+36
-0
lines changed
  • examples/conways_game_of_life_fast

1 file changed

+36
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import numpy as np
2+
from mesa import Model
3+
from mesa.space import PropertyLayer
4+
from scipy.signal import convolve2d
5+
6+
# fmt: off
7+
class GameOfLifeModel(Model):
8+
def __init__(self, width=10, height=10, alive_fraction=0.2):
9+
super().__init__()
10+
# Initialize the property layer for cell states
11+
self.cell_layer = PropertyLayer("cells", width, height, False, dtype=bool)
12+
# Randomly set cells to alive
13+
self.cell_layer.data = np.random.choice([True, False], size=(width, height), p=[alive_fraction, 1 - alive_fraction])
14+
15+
def step(self):
16+
self._advance_time()
17+
# Define a kernel for counting neighbors. The kernel has 1s around the center cell (which is 0).
18+
# This setup allows us to count the live neighbors of each cell when we apply convolution.
19+
kernel = np.array([[1, 1, 1],
20+
[1, 0, 1],
21+
[1, 1, 1]])
22+
23+
# Count neighbors using convolution.
24+
# convolve2d applies the kernel to each cell of the grid, summing up the values of neighbors.
25+
# boundary="wrap" ensures that the grid wraps around, simulating a toroidal surface.
26+
neighbor_count = convolve2d(self.cell_layer.data, kernel, mode="same", boundary="wrap")
27+
28+
# Apply Game of Life rules:
29+
# 1. A live cell with 2 or 3 live neighbors survives, otherwise it dies.
30+
# 2. A dead cell with exactly 3 live neighbors becomes alive.
31+
# These rules are implemented using logical operations on the grid.
32+
self.cell_layer.data = np.logical_or(
33+
np.logical_and(self.cell_layer.data, np.logical_or(neighbor_count == 2, neighbor_count == 3)),
34+
# Rule for live cells
35+
np.logical_and(~self.cell_layer.data, neighbor_count == 3) # Rule for dead cells
36+
)

0 commit comments

Comments
 (0)