Skip to content

Commit 062f46a

Browse files
quaqueltpike3
authored andcommitted
more pythonic implementation of wolf sheep
1 parent 2837cc1 commit 062f46a

File tree

4 files changed

+133
-188
lines changed

4 files changed

+133
-188
lines changed

benchmarks/WolfSheep/__init__.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +0,0 @@
1-
from .wolf_sheep import WolfSheep
2-
3-
if __name__ == "__main__":
4-
# for profiling this benchmark model
5-
import time
6-
7-
# model = WolfSheep(15, 25, 25, 60, 40, 0.2, 0.1, 20)
8-
model = WolfSheep(15, 100, 100, 1000, 500, 0.4, 0.2, 20)
9-
10-
start_time = time.perf_counter()
11-
for _ in range(100):
12-
model.step()
13-
14-
print(time.perf_counter() - start_time)

benchmarks/WolfSheep/agents.py

Lines changed: 0 additions & 111 deletions
This file was deleted.

benchmarks/WolfSheep/random_walk.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

benchmarks/WolfSheep/wolf_sheep.py

Lines changed: 133 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,133 @@
88
Center for Connected Learning and Computer-Based Modeling,
99
Northwestern University, Evanston, IL.
1010
"""
11+
import math
1112

12-
import mesa
13+
from mesa import Model, Agent
1314
from mesa.space import MultiGrid
1415
from mesa.time import RandomActivationByType
1516

16-
from .agents import GrassPatch, Sheep, Wolf
1717

18+
class Animal(Agent):
1819

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):
20119
"""
21120
Wolf-Sheep Predation Model
22121
23122
A model for simulating wolf and sheep (predator-prey) ecosystem modelling.
24123
"""
25124

26125
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
38138
):
39139
"""
40140
Create a new Wolf-Sheep model with the given parameters.
@@ -49,41 +149,37 @@ def __init__(
49149
grass_regrowth_time: How long it takes for a grass patch to regrow
50150
once it is eaten
51151
sheep_gain_from_food: Energy sheep gain from grass, if enabled.
152+
moore:
52153
"""
53154
super().__init__(seed=seed)
54155
# Set parameters
55156
self.height = height
56157
self.width = width
57158
self.initial_sheep = initial_sheep
58159
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
62160
self.grass_regrowth_time = grass_regrowth_time
63-
self.sheep_gain_from_food = sheep_gain_from_food
64161

65162
self.schedule = RandomActivationByType(self)
66163
self.grid = MultiGrid(self.height, self.width, torus=False)
67164

68-
# Create sheep:
69-
for _i in range(self.initial_sheep):
165+
for _ in range(self.initial_sheep):
70166
pos = (
71167
self.random.randrange(self.width),
72168
self.random.randrange(self.height),
73169
)
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)
76172
self.grid.place_agent(sheep, pos)
77173
self.schedule.add(sheep)
78174

79175
# Create wolves
80-
for _i in range(self.initial_wolves):
176+
for _ in range(self.initial_wolves):
81177
pos = (
82178
self.random.randrange(self.width),
83179
self.random.randrange(self.height),
84180
)
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)
87183
self.grid.place_agent(wolf, pos)
88184
self.schedule.add(wolf)
89185

@@ -95,9 +191,20 @@ def __init__(
95191
countdown = self.grass_regrowth_time
96192
else:
97193
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)
99195
self.grid.place_agent(patch, pos)
100196
self.schedule.add(patch)
101197

102198
def step(self):
103199
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

Comments
 (0)