|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 |
| -from typing import TYPE_CHECKING |
| 3 | +from typing import TYPE_CHECKING, Protocol, runtime_checkable |
4 | 4 |
|
5 |
| -from mesa import Agent, Model |
| 5 | +from mesa.experimental.cell_space.discrete_space import DiscreteSpace |
6 | 6 |
|
7 | 7 | if TYPE_CHECKING:
|
8 |
| - from mesa.experimental.cell_space.cell import Cell |
| 8 | + from mesa.experimental.cell_space import Cell, Grid |
9 | 9 |
|
10 | 10 |
|
11 |
| -class CellAgent(Agent): |
12 |
| - """Cell Agent is an extension of the Agent class and adds behavior for moving in discrete spaces |
| 11 | +@runtime_checkable |
| 12 | +class CellHolder(Protocol): |
| 13 | + cell: Cell | None |
13 | 14 |
|
14 | 15 |
|
15 |
| - Attributes: |
16 |
| - unique_id (int): A unique identifier for this agent. |
17 |
| - model (Model): The model instance to which the agent belongs |
18 |
| - pos: (Position | None): The position of the agent in the space |
19 |
| - cell: (Cell | None): the cell which the agent occupies |
20 |
| - """ |
| 16 | +class CellAgent: |
| 17 | + cell: Cell | None |
| 18 | + space: DiscreteSpace[Cell] |
| 19 | + """Cell Agent is an extension of the Agent class and adds behavior for moving in discrete spaces""" |
21 | 20 |
|
22 |
| - def __init__(self, model: Model) -> None: |
23 |
| - """ |
24 |
| - Create a new agent. |
25 |
| -
|
26 |
| - Args: |
27 |
| - unique_id (int): A unique identifier for this agent. |
28 |
| - model (Model): The model instance in which the agent exists. |
29 |
| - """ |
30 |
| - super().__init__(model) |
31 |
| - self.cell: Cell | None = None |
32 |
| - |
33 |
| - def move_to(self, cell) -> None: |
| 21 | + def move_to(self: CellHolder, cell: Cell) -> None: |
34 | 22 | if self.cell is not None:
|
35 | 23 | self.cell.remove_agent(self)
|
36 | 24 | self.cell = cell
|
37 | 25 | cell.add_agent(self)
|
| 26 | + |
| 27 | + def move_relative(self, directions: tuple[int, ...], distance: int = 1): |
| 28 | + new_position = tuple( |
| 29 | + self.cell.coordinate[i] + directions[i] * distance |
| 30 | + for i in range(len(directions)) |
| 31 | + if self.cell |
| 32 | + ) |
| 33 | + new_cell = self.space[new_position] |
| 34 | + self.move_to(new_cell) |
| 35 | + |
| 36 | + |
| 37 | +class Grid2DMovingAgent(CellAgent): |
| 38 | + grid: Grid[Cell] |
| 39 | + |
| 40 | + def move(self, direction: str, distance: int = 1): |
| 41 | + match direction: |
| 42 | + case "N" | "North" | "Up": |
| 43 | + self.move_relative((-1, 0), distance) |
| 44 | + case "S" | "South" | "Down": |
| 45 | + self.move_relative((1, 0), distance) |
| 46 | + case "E" | "East" | "Right": |
| 47 | + self.move_relative((0, 1), distance) |
| 48 | + case "W" | "West" | "Left": |
| 49 | + self.move_relative((0, -1), distance) |
| 50 | + case "NE" | "NorthEast" | "UpRight": |
| 51 | + self.move_relative((-1, 1), distance) |
| 52 | + case "NW" | "NorthWest" | "UpLeft": |
| 53 | + self.move_relative((-1, -1), distance) |
| 54 | + case "SE" | "SouthEast" | "DownRight": |
| 55 | + self.move_relative((1, 1), distance) |
| 56 | + case "SW" | "SouthWest" | "DownLeft": |
| 57 | + self.move_relative((1, -1), distance) |
| 58 | + case _: |
| 59 | + raise ValueError(f"Invalid direction: {direction}") |
0 commit comments