Skip to content

Commit

Permalink
examples/wolf_sheep: Don't allow dump moves (projectmesa#2503)
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 authored Dec 22, 2024
1 parent 393f6a0 commit dd77c0a
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 @@ -39,7 +39,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 @@ -64,6 +65,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 @@ -76,6 +98,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 dd77c0a

Please sign in to comment.