diff --git a/mesa/examples/advanced/wolf_sheep/agents.py b/mesa/examples/advanced/wolf_sheep/agents.py index fc22fbf829c..a2505c2e436 100644 --- a/mesa/examples/advanced/wolf_sheep/agents.py +++ b/mesa/examples/advanced/wolf_sheep/agents.py @@ -40,13 +40,6 @@ def step(self): """Execute one step of the animal's behavior.""" # Move to random neighboring cell self.move() - is_cliff = self.model.grid.cliff.data[self.cell.coordinate[0]][ - self.cell.coordinate[1] - ] - if is_cliff: # if the cell is a cliff, then the animal dies - self.remove() - return - self.energy -= 1 # Try to feed @@ -80,6 +73,15 @@ def move(self): if len(cells_without_wolves) == 0: return + target_cells_not_walls = cells_without_wolves.select( + lambda cell: not self.model.grid.wall.data[cell.coordinate[0]][ + cell.coordinate[1] + ] + ) + + if len(target_cells_not_walls) == 0: + return + # Among safe cells, prefer those with grown grass cells_with_grass = cells_without_wolves.select( lambda cell: any( diff --git a/mesa/examples/advanced/wolf_sheep/model.py b/mesa/examples/advanced/wolf_sheep/model.py index f80fc19a8b6..739b465772c 100644 --- a/mesa/examples/advanced/wolf_sheep/model.py +++ b/mesa/examples/advanced/wolf_sheep/model.py @@ -22,6 +22,29 @@ from mesa.experimental.devs import ABMSimulator +def is_trapped_in_wall( + cell, wall_coord, width, height +): # true if cell is trapped of walls + north = (cell.coordinate[0] - 1, cell.coordinate[1]) + south = (cell.coordinate[0] + 1, cell.coordinate[1]) + west = (cell.coordinate[0], cell.coordinate[1] - 1) + east = (cell.coordinate[0], cell.coordinate[1] + 1) + + coord = (cell.coordinate[0], cell.coordinate[1]) + + # 'corner' cases (pun intended) + if coord == (0, 0): # top left corner + return {east, south}.issubset(wall_coord) + if coord == (height - 1, 0): # bottom left corner + return {north, east}.issubset(wall_coord) + if coord == (0, width - 1): # top right corner + return {west, south}.issubset(wall_coord) + if coord == (height - 1, width - 1): # bottom right corner + return {north, west}.issubset(wall_coord) + + return {north, south, west, east}.issubset(wall_coord) + + class WolfSheep(Model): """Wolf-Sheep Predation Model. @@ -96,25 +119,29 @@ def __init__( self.datacollector = DataCollector(model_reporters) - cliff_arr = [[False] * self.width for i in range(self.height)] + wall_arr = [[False] * self.width for i in range(self.height)] - cliff_coord = { + wall_coord = { (random.randrange(self.height), random.randrange(self.width)) - for i in range((width * height) // 3) + for i in range((width * height) // 10) } # set is used because the random number gen might return the same coordinate - for i, j in cliff_coord: - cliff_arr[i][j] = True + for i, j in wall_coord: + wall_arr[i][j] = True - cliff_arr = np.array(cliff_arr) + wall_arr = np.array(wall_arr) - self.grid.add_property_layer(PropertyLayer.from_data("cliff", cliff_arr)) + self.grid.add_property_layer(PropertyLayer.from_data("wall", wall_arr)) possible_cells = [] for cell in self.grid.all_cells.cells: if ( - cell.coordinate[0], - cell.coordinate[1], - ) not in cliff_coord: # so we don't create wolf or sheep on cliff cells + ( + cell.coordinate[0], + cell.coordinate[1], + ) + not in wall_coord + and not is_trapped_in_wall(cell, wall_coord, width, height) + ): # so we don't create an animal at wall cells. and make sure the animal is not trapped in walls possible_cells.append(cell) # Create sheep: