8
8
Center for Connected Learning and Computer-Based Modeling,
9
9
Northwestern University, Evanston, IL.
10
10
"""
11
+ import math
11
12
12
- import mesa
13
+ from mesa import Model , Agent
13
14
from mesa .space import MultiGrid
14
15
from mesa .time import RandomActivationByType
15
16
16
- from .agents import GrassPatch , Sheep , Wolf
17
17
18
+ class Animal (Agent ):
18
19
19
- class WolfSheep (mesa .Model ):
20
+ def __init__ (self , unique_id , model , moore , energy , p_reproduce , energy_from_food ):
21
+ super ().__init__ (unique_id , model )
22
+ self .energy = energy
23
+ self .p_reproduce = p_reproduce
24
+ self .energy_from_food = energy_from_food
25
+ self .moore = moore
26
+
27
+ def random_move (self ):
28
+ next_moves = self .model .grid .get_neighborhood (self .pos , self .moore , True )
29
+ next_move = self .random .choice (next_moves )
30
+ # Now move:
31
+ self .model .grid .move_agent (self , next_move )
32
+
33
+ def spawn_offspring (self ):
34
+ self .energy /= 2
35
+ offspring = self .__class__ (
36
+ self .model .next_id (), self .model , self .moore , self .energy , self .p_reproduce , self .energy_from_food
37
+ )
38
+ self .model .grid .place_agent (offspring , self .pos )
39
+ self .model .schedule .add (offspring )
40
+
41
+ def feed (self ):
42
+ ...
43
+
44
+ def die (self ):
45
+ self .model .grid .remove_agent (self )
46
+ self .remove ()
47
+
48
+ def step (self ):
49
+ self .random_move ()
50
+ self .energy -= 1
51
+
52
+ self .feed ()
53
+
54
+ if self .energy < 0 :
55
+ self .die ()
56
+ elif self .random .random () < self .p_reproduce :
57
+ self .spawn_offspring ()
58
+
59
+
60
+ class Sheep (Animal ):
61
+ """
62
+ A sheep that walks around, reproduces (asexually) and gets eaten.
63
+
64
+ The init is the same as the RandomWalker.
65
+ """
66
+
67
+ def feed (self ):
68
+ # If there is grass available, eat it
69
+ agents = self .model .grid .get_cell_list_contents (self .pos )
70
+ grass_patch = next (obj for obj in agents if isinstance (obj , GrassPatch ))
71
+ if grass_patch .fully_grown :
72
+ self .energy += self .energy_from_food
73
+ grass_patch .fully_grown = False
74
+
75
+ class Wolf (Animal ):
76
+ """
77
+ A wolf that walks around, reproduces (asexually) and eats sheep.
78
+ """
79
+
80
+ def feed (self ):
81
+ agents = self .model .grid .get_cell_list_contents (self .pos )
82
+ sheep = [obj for obj in agents if isinstance (obj , Sheep )]
83
+ if len (sheep ) > 0 :
84
+ sheep_to_eat = self .random .choice (sheep )
85
+ self .energy += self .energy
86
+
87
+ # Kill the sheep
88
+ sheep_to_eat .die ()
89
+
90
+
91
+ class GrassPatch (Agent ):
92
+ """
93
+ A patch of grass that grows at a fixed rate and it is eaten by sheep
94
+ """
95
+
96
+ def __init__ (self , unique_id , model , fully_grown , countdown ):
97
+ """
98
+ Creates a new patch of grass
99
+
100
+ Args:
101
+ grown: (boolean) Whether the patch of grass is fully grown or not
102
+ countdown: Time for the patch of grass to be fully grown again
103
+ """
104
+ super ().__init__ (unique_id , model )
105
+ self .fully_grown = fully_grown
106
+ self .countdown = countdown
107
+
108
+ def step (self ):
109
+ if not self .fully_grown :
110
+ if self .countdown <= 0 :
111
+ # Set as fully grown
112
+ self .fully_grown = True
113
+ self .countdown = self .model .grass_regrowth_time
114
+ else :
115
+ self .countdown -= 1
116
+
117
+
118
+ class WolfSheep (Model ):
20
119
"""
21
120
Wolf-Sheep Predation Model
22
121
23
122
A model for simulating wolf and sheep (predator-prey) ecosystem modelling.
24
123
"""
25
124
26
125
def __init__ (
27
- self ,
28
- seed ,
29
- height ,
30
- width ,
31
- initial_sheep ,
32
- initial_wolves ,
33
- sheep_reproduce ,
34
- wolf_reproduce ,
35
- grass_regrowth_time ,
36
- wolf_gain_from_food = 13 ,
37
- sheep_gain_from_food = 5 ,
126
+ self ,
127
+ seed ,
128
+ height ,
129
+ width ,
130
+ initial_sheep ,
131
+ initial_wolves ,
132
+ sheep_reproduce ,
133
+ wolf_reproduce ,
134
+ grass_regrowth_time ,
135
+ wolf_gain_from_food = 13 ,
136
+ sheep_gain_from_food = 5 ,
137
+ moore = False
38
138
):
39
139
"""
40
140
Create a new Wolf-Sheep model with the given parameters.
@@ -49,41 +149,37 @@ def __init__(
49
149
grass_regrowth_time: How long it takes for a grass patch to regrow
50
150
once it is eaten
51
151
sheep_gain_from_food: Energy sheep gain from grass, if enabled.
152
+ moore:
52
153
"""
53
154
super ().__init__ (seed = seed )
54
155
# Set parameters
55
156
self .height = height
56
157
self .width = width
57
158
self .initial_sheep = initial_sheep
58
159
self .initial_wolves = initial_wolves
59
- self .sheep_reproduce = sheep_reproduce
60
- self .wolf_reproduce = wolf_reproduce
61
- self .wolf_gain_from_food = wolf_gain_from_food
62
160
self .grass_regrowth_time = grass_regrowth_time
63
- self .sheep_gain_from_food = sheep_gain_from_food
64
161
65
162
self .schedule = RandomActivationByType (self )
66
163
self .grid = MultiGrid (self .height , self .width , torus = False )
67
164
68
- # Create sheep:
69
- for _i in range (self .initial_sheep ):
165
+ for _ in range (self .initial_sheep ):
70
166
pos = (
71
167
self .random .randrange (self .width ),
72
168
self .random .randrange (self .height ),
73
169
)
74
- energy = self .random .randrange (2 * self . sheep_gain_from_food )
75
- sheep = Sheep (self .next_id (), pos , self , True , energy )
170
+ energy = self .random .randrange (2 * sheep_gain_from_food )
171
+ sheep = Sheep (self .next_id (), self , moore , energy , sheep_reproduce , sheep_gain_from_food )
76
172
self .grid .place_agent (sheep , pos )
77
173
self .schedule .add (sheep )
78
174
79
175
# Create wolves
80
- for _i in range (self .initial_wolves ):
176
+ for _ in range (self .initial_wolves ):
81
177
pos = (
82
178
self .random .randrange (self .width ),
83
179
self .random .randrange (self .height ),
84
180
)
85
- energy = self .random .randrange (2 * self . wolf_gain_from_food )
86
- wolf = Wolf (self .next_id (), pos , self , True , energy )
181
+ energy = self .random .randrange (2 * wolf_gain_from_food )
182
+ wolf = Wolf (self .next_id (), self , moore , energy , wolf_reproduce , wolf_gain_from_food )
87
183
self .grid .place_agent (wolf , pos )
88
184
self .schedule .add (wolf )
89
185
@@ -95,9 +191,20 @@ def __init__(
95
191
countdown = self .grass_regrowth_time
96
192
else :
97
193
countdown = self .random .randrange (self .grass_regrowth_time )
98
- patch = GrassPatch (self .next_id (), pos , self , fully_grown , countdown )
194
+ patch = GrassPatch (self .next_id (), self , fully_grown , countdown )
99
195
self .grid .place_agent (patch , pos )
100
196
self .schedule .add (patch )
101
197
102
198
def step (self ):
103
199
self .schedule .step ()
200
+
201
+
202
+ if __name__ == "__main__" :
203
+ import time
204
+
205
+ model = WolfSheep (15 , 25 , 25 , 60 , 40 , 0.2 , 0.1 , 20 )
206
+
207
+ start_time = time .perf_counter ()
208
+ for _ in range (100 ):
209
+ model .step ()
210
+ print ("Time:" , time .perf_counter () - start_time )
0 commit comments