10
10
"""
11
11
12
12
import math
13
- import random
14
13
15
14
import numpy as np
15
+ from scipy .ndimage import gaussian_filter
16
16
17
17
from mesa import Model
18
18
from mesa .datacollection import DataCollector
@@ -96,38 +96,32 @@ def __init__(
96
96
97
97
self .datacollector = DataCollector (model_reporters )
98
98
99
- wall_arr = [[False ] * self .width for i in range (self .height )]
99
+ def generate_grass_regrowth_time_array (): # Using Gaussian filter to make it look like spatial distribution
100
+ rows , cols = height , width
100
101
101
- wall_coord = {
102
- (random .randrange (self .height ), random .randrange (self .width ))
103
- for i in range ((width * height ) // 10 )
104
- } # set is used because the random number gen might return the same coordinate
105
- for i , j in wall_coord :
106
- wall_arr [i ][j ] = True
102
+ seeds = np .zeros ((rows , cols ))
103
+ num_seeds = grass_regrowth_time
107
104
108
- wall_arr = np .array (wall_arr )
105
+ for _ in range (num_seeds ):
106
+ x , y = np .random .randint (0 , rows ), np .random .randint (0 , cols )
107
+ seeds [x , y ] = np .random .randint (1 , num_seeds )
109
108
110
- self .grid .add_property_layer (PropertyLayer .from_data ("wall" , wall_arr ))
109
+ # Smooth the array to create clustered patterns using SciPy's Gaussian filter
110
+ filtered_array = gaussian_filter (seeds , sigma = 10 )
111
111
112
- def is_wall (row , col ):
113
- return (
114
- True
115
- if row < 0 or col < 0 or row >= height or col >= width # corner case
116
- else wall_arr [row ][col ]
117
- )
112
+ # Normalize the array to the range [1, num_seeds]
113
+ filtered_array = (filtered_array - np .min (filtered_array )) / (
114
+ np .max (filtered_array ) - np .min (filtered_array )
115
+ ) * (num_seeds - 1 ) + 1
116
+ filtered_array = filtered_array .astype (int )
118
117
119
- def is_trapped_in_walls (row , col ):
120
- return (
121
- is_wall (row + 1 , col )
122
- and is_wall (row - 1 , col )
123
- and is_wall (row , col + 1 )
124
- and is_wall (row , col - 1 )
125
- )
118
+ return filtered_array
126
119
127
- possible_cells = self .grid .all_cells .select (
128
- lambda cell : not wall_arr [cell .coordinate [0 ]][cell .coordinate [1 ]]
129
- and not is_trapped_in_walls (cell .coordinate [0 ], cell .coordinate [1 ])
130
- ).cells # so we don't create an animal at wall cells. and make sure the animal is not trapped in walls
120
+ grass_regrowth_time_array = generate_grass_regrowth_time_array ()
121
+
122
+ self .grid .add_property_layer (
123
+ PropertyLayer .from_data ("grass_regrowth_time" , grass_regrowth_time_array )
124
+ )
131
125
132
126
# Create sheep:
133
127
Sheep .create_agents (
@@ -136,7 +130,7 @@ def is_trapped_in_walls(row, col):
136
130
energy = self .rng .random ((initial_sheep ,)) * 2 * sheep_gain_from_food ,
137
131
p_reproduce = sheep_reproduce ,
138
132
energy_from_food = sheep_gain_from_food ,
139
- cell = self .random .choices (possible_cells , k = initial_sheep ),
133
+ cell = self .random .choices (self . grid . all_cells . cells , k = initial_sheep ),
140
134
)
141
135
# Create Wolves:
142
136
Wolf .create_agents (
@@ -145,7 +139,7 @@ def is_trapped_in_walls(row, col):
145
139
energy = self .rng .random ((initial_wolves ,)) * 2 * wolf_gain_from_food ,
146
140
p_reproduce = wolf_reproduce ,
147
141
energy_from_food = wolf_gain_from_food ,
148
- cell = self .random .choices (possible_cells , k = initial_wolves ),
142
+ cell = self .random .choices (self . grid . all_cells . cells , k = initial_wolves ),
149
143
)
150
144
151
145
# Create grass patches if enabled
@@ -154,9 +148,16 @@ def is_trapped_in_walls(row, col):
154
148
for cell in self .grid :
155
149
fully_grown = self .random .choice (possibly_fully_grown )
156
150
countdown = (
157
- 0 if fully_grown else self .random .randrange (0 , grass_regrowth_time )
151
+ 0
152
+ if fully_grown
153
+ else self .random .randrange (
154
+ 0 ,
155
+ grass_regrowth_time_array [cell .coordinate [0 ]][
156
+ cell .coordinate [1 ]
157
+ ],
158
+ )
158
159
)
159
- GrassPatch (self , countdown , grass_regrowth_time , cell )
160
+ GrassPatch (self , countdown , cell )
160
161
161
162
# Collect initial data
162
163
self .running = True
0 commit comments