diff --git a/examples/conways_game_of_life_fast/app.py b/examples/conways_game_of_life_fast/app.py index a3084905..c5001821 100644 --- a/examples/conways_game_of_life_fast/app.py +++ b/examples/conways_game_of_life_fast/app.py @@ -34,9 +34,24 @@ "max": 1, "step": 0.01, }, + "randomize_new_cells": { # New parameter for manual adjustment + "type": "SliderFloat", + "value": 0.05, # The initial probability of reviving new cells + "label": "New Cells Randomization", + "min": 0, + "max": 1, + "step": 0.01, + }, } -gol = GameOfLifeModel() + +gol = GameOfLifeModel( + width=model_params["width"]["value"], + height=model_params["height"]["value"], + alive_fraction=model_params["alive_fraction"]["value"], + randomize_new_cells=model_params["randomize_new_cells"]["value"], +) + layer_viz = make_space_matplotlib(propertylayer_portrayal=propertylayer_portrayal) TotalAlivePlot = make_plot_measure("Cells alive") diff --git a/examples/conways_game_of_life_fast/model.py b/examples/conways_game_of_life_fast/model.py index 40499b64..67535ec5 100644 --- a/examples/conways_game_of_life_fast/model.py +++ b/examples/conways_game_of_life_fast/model.py @@ -7,7 +7,7 @@ # fmt: off class GameOfLifeModel(Model): - def __init__(self, width=10, height=10, alive_fraction=0.2): + def __init__(self, width=10, height=10, alive_fraction=0.2, randomize_new_cells=0.05): super().__init__() # Initialize the property layer for cell states self.cell_layer = PropertyLayer("cells", width, height, False, dtype=bool) @@ -18,6 +18,8 @@ def __init__(self, width=10, height=10, alive_fraction=0.2): self.cells = width * height self.alive_count = 0 self.alive_fraction = 0 + self.randomize_new_cells = randomize_new_cells + self.datacollector = DataCollector( model_reporters={"Cells alive": "alive_count", "Fraction alive": "alive_fraction"} @@ -25,27 +27,31 @@ def __init__(self, width=10, height=10, alive_fraction=0.2): self.datacollector.collect(self) def step(self): - # Define a kernel for counting neighbors. The kernel has 1s around the center cell (which is 0). - # This setup allows us to count the live neighbors of each cell when we apply convolution. + # Define a kernel for counting neighbors kernel = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]]) - # Count neighbors using convolution. - # convolve2d applies the kernel to each cell of the grid, summing up the values of neighbors. - # boundary="wrap" ensures that the grid wraps around, simulating a toroidal surface. + # Count neighbors using convolution neighbor_count = convolve2d(self.cell_layer.data, kernel, mode="same", boundary="wrap") - # Apply Game of Life rules: - # 1. A live cell with 2 or 3 live neighbors survives, otherwise it dies. - # 2. A dead cell with exactly 3 live neighbors becomes alive. - # These rules are implemented using logical operations on the grid. + """ Changing the behavior of cells so that they can "die from overpopulation" + if there are more than 4 living neighbors around them. """ + + # Apply Game of Life rules with overpopulation death: + # 1. A live cell with 2 or 3 live neighbors survives. + # 2. A live cell with more than 4 neighbors dies (overpopulation). + # 3. A dead cell with exactly 3 live neighbors becomes alive. self.cell_layer.data = np.logical_or( - np.logical_and(self.cell_layer.data, np.logical_or(neighbor_count == 2, neighbor_count == 3)), - # Rule for live cells - np.logical_and(~self.cell_layer.data, neighbor_count == 3) # Rule for dead cells + np.logical_and(self.cell_layer.data, np.logical_and(neighbor_count >= 2, neighbor_count <= 3)), + np.logical_and(~self.cell_layer.data, neighbor_count == 3) ) + # Оживлення нових клітин за ймовірністю randomize_new_cells + if np.random.random() < self.randomize_new_cells: + random_positions = np.random.choice([True, False], size=self.cell_layer.data.shape, p=[0.05, 0.95]) + self.cell_layer.data = np.logical_or(self.cell_layer.data, random_positions) + # Metrics self.alive_count = np.sum(self.cell_layer.data) self.alive_fraction = self.alive_count / self.cells diff --git a/examples/conways_game_of_life_fast/model_run.py b/examples/conways_game_of_life_fast/model_run.py new file mode 100644 index 00000000..a3a70131 --- /dev/null +++ b/examples/conways_game_of_life_fast/model_run.py @@ -0,0 +1,5 @@ +from model import GameOfLifeModel + +model = GameOfLifeModel(width=10, height=10, alive_fraction=0.2) +for i in range(10): + model.step()