11import numpy as np
22from mesa import Model
33from mesa .datacollection import DataCollector
4- from mesa .discrete_space import PropertyLayer
54from scipy .signal import convolve2d
65
76
87# fmt: off
98class GameOfLifeModel (Model ):
109 def __init__ (self , width = 10 , height = 10 , alive_fraction = 0.2 ):
1110 super ().__init__ ()
12- # Initialize the property layer for cell states
13- self .cell_layer = PropertyLayer (
14- "cells" , (width , height ), default_value = False , dtype = bool
11+ self .cell_layer_data = np .random .choice (
12+ [True , False ],
13+ size = (width , height ),
14+ p = [alive_fraction , 1 - alive_fraction ],
1515 )
16- # Randomly set cells to alive
17- self .cell_layer .data = np .random .choice ([True , False ], size = (width , height ), p = [alive_fraction , 1 - alive_fraction ])
18-
1916 # Metrics and datacollector
20- self .cells = width * height
17+ self .total_cells = width * height
2118 self .alive_count = 0
2219 self .alive_fraction = 0
2320 self .datacollector = DataCollector (
@@ -36,19 +33,19 @@ def step(self):
3633 # Count neighbors using convolution.
3734 # convolve2d applies the kernel to each cell of the grid, summing up the values of neighbors.
3835 # boundary="wrap" ensures that the grid wraps around, simulating a toroidal surface.
39- neighbor_count = convolve2d (self .cell_layer . data , kernel , mode = "same" , boundary = "wrap" )
36+ neighbor_count = convolve2d (self .cell_layer_data , kernel , mode = "same" , boundary = "wrap" )
4037
4138 # Apply Game of Life rules:
4239 # 1. A live cell with 2 or 3 live neighbors survives, otherwise it dies.
4340 # 2. A dead cell with exactly 3 live neighbors becomes alive.
4441 # These rules are implemented using logical operations on the grid.
45- self .cell_layer . data = np .logical_or (
46- np .logical_and (self .cell_layer . data , np .logical_or (neighbor_count == 2 , neighbor_count == 3 )),
42+ self .cell_layer_data = np .logical_or (
43+ np .logical_and (self .cell_layer_data , np .logical_or (neighbor_count == 2 , neighbor_count == 3 )),
4744 # Rule for live cells
48- np .logical_and (~ self .cell_layer . data , neighbor_count == 3 ) # Rule for dead cells
45+ np .logical_and (~ self .cell_layer_data , neighbor_count == 3 ) # Rule for dead cells
4946 )
5047
5148 # Metrics
52- self .alive_count = np .sum (self .cell_layer . data )
53- self .alive_fraction = self .alive_count / self .cells
49+ self .alive_count = np .sum (self .cell_layer_data )
50+ self .alive_fraction = self .alive_count / self .total_cells
5451 self .datacollector .collect (self )
0 commit comments