Skip to content

Commit

Permalink
examples/wolf_sheep: Don't allow dump moves
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
EwoutH committed Nov 13, 2024
1 parent 54d7e28 commit dcaf243
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion mesa/examples/advanced/wolf_sheep/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def feed(self):
def step(self):
"""Execute one step of the animal's behavior."""
# Move to random neighboring cell
self.cell = self.cell.neighborhood.select_random_cell()
self.move()

self.energy -= 1

# Try to feed
Expand All @@ -62,6 +63,27 @@ def feed(self):
self.energy += self.energy_from_food
grass_patch.fully_grown = False

def move(self):
"""Move towards a cell where there isn't a wolf, and preferably with grown grass."""
cells_without_wolves = self.cell.neighborhood.select(
lambda cell: not any(isinstance(obj, Wolf) for obj in cell.agents)
)
# If all surrounding cells have wolves, stay put
if len(cells_without_wolves) == 0:
return

# Among safe cells, prefer those with grown grass
cells_with_grass = cells_without_wolves.select(
lambda cell: any(
isinstance(obj, GrassPatch) and obj.fully_grown for obj in cell.agents
)
)
# Move to a cell with grass if available, otherwise move to any safe cell
target_cells = (
cells_with_grass if len(cells_with_grass) > 0 else cells_without_wolves
)
self.cell = target_cells.select_random_cell()


class Wolf(Animal):
"""A wolf that walks around, reproduces (asexually) and eats sheep."""
Expand All @@ -74,6 +96,16 @@ def feed(self):
self.energy += self.energy_from_food
sheep_to_eat.remove()

def move(self):
"""Move to a neighboring cell, preferably one with sheep."""
cells_with_sheep = self.cell.neighborhood.select(
lambda cell: any(isinstance(obj, Sheep) for obj in cell.agents)
)
target_cells = (
cells_with_sheep if len(cells_with_sheep) > 0 else self.cell.neighborhood
)
self.cell = target_cells.select_random_cell()


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

0 comments on commit dcaf243

Please sign in to comment.