Skip to content

Commit 58fac6b

Browse files
EwoutHquaquel
authored andcommitted
examples/wolf_sheep: Don't allow dump moves (#2503)
Agents now move completely random in WolfSheep. That makes no sense whatsoever, so this PR makes them move a little bit less dump. - Wolf moves to random cell with sheep on them, if available (otherwise completely random) - Sheep move to a random cell without a wolf (if available), and preferably with grass. This enables sheep to actually "search" for grass, wolfs to search for sheep and sheep to not move to a cell with wolves. More importantly, it shows of some nice selection mechanics with the cell space.
1 parent 72e3c4c commit 58fac6b

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

mesa/examples/advanced/wolf_sheep/agents.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def feed(self):
3939
def step(self):
4040
"""Execute one step of the animal's behavior."""
4141
# Move to random neighboring cell
42-
self.cell = self.cell.neighborhood.select_random_cell()
42+
self.move()
43+
4344
self.energy -= 1
4445

4546
# Try to feed
@@ -64,6 +65,27 @@ def feed(self):
6465
self.energy += self.energy_from_food
6566
grass_patch.fully_grown = False
6667

68+
def move(self):
69+
"""Move towards a cell where there isn't a wolf, and preferably with grown grass."""
70+
cells_without_wolves = self.cell.neighborhood.select(
71+
lambda cell: not any(isinstance(obj, Wolf) for obj in cell.agents)
72+
)
73+
# If all surrounding cells have wolves, stay put
74+
if len(cells_without_wolves) == 0:
75+
return
76+
77+
# Among safe cells, prefer those with grown grass
78+
cells_with_grass = cells_without_wolves.select(
79+
lambda cell: any(
80+
isinstance(obj, GrassPatch) and obj.fully_grown for obj in cell.agents
81+
)
82+
)
83+
# Move to a cell with grass if available, otherwise move to any safe cell
84+
target_cells = (
85+
cells_with_grass if len(cells_with_grass) > 0 else cells_without_wolves
86+
)
87+
self.cell = target_cells.select_random_cell()
88+
6789

6890
class Wolf(Animal):
6991
"""A wolf that walks around, reproduces (asexually) and eats sheep."""
@@ -76,6 +98,16 @@ def feed(self):
7698
self.energy += self.energy_from_food
7799
sheep_to_eat.remove()
78100

101+
def move(self):
102+
"""Move to a neighboring cell, preferably one with sheep."""
103+
cells_with_sheep = self.cell.neighborhood.select(
104+
lambda cell: any(isinstance(obj, Sheep) for obj in cell.agents)
105+
)
106+
target_cells = (
107+
cells_with_sheep if len(cells_with_sheep) > 0 else self.cell.neighborhood
108+
)
109+
self.cell = target_cells.select_random_cell()
110+
79111

80112
class GrassPatch(FixedAgent):
81113
"""A patch of grass that grows at a fixed rate and can be eaten by sheep."""

0 commit comments

Comments
 (0)