Skip to content

Movements

This class is used to manipulate actors' movements.

Source code in abses/move.py
def __init__(self, actor: Actor) -> None:
    self.actor = actor
    self.model = actor.model
    self.seed = actor.unique_id

layer property

layer

The current layer of the operating actor.

to

to(pos, layer=None)

Move the actor to a specific location.

Parameters:

Name Type Description Default
pos PatchCell | Coordinate | Literal['random']

The position to move to. If position is a Coordinate -a tuple of (row, col), it will be moved to the same layer. If pos

required
layer Optional[PatchModule]

The layer where the actor is located.

None

Raises:

Type Description
ABSESpyError

If the input layer is not consistent with the actor's layer. If the position is out of bounds. Or, if the pos is coordinate without layer.

Source code in abses/move.py
def to(
    self,
    pos: PatchCell | Coordinate | Literal["random"],
    layer: Optional[PatchModule] = None,
) -> None:
    """
    Move the actor to a specific location.

    Parameters:
        pos:
            The position to move to.
            If position is a Coordinate -a tuple of (row, col),
            it will be moved to the same layer.
            If pos
        layer:
            The layer where the actor is located.

    Raises:
        ABSESpyError:
            If the input layer is not consistent with the actor's layer.
            If the position is out of bounds.
            Or, if the pos is coordinate without layer.
    """
    if isinstance(pos, str) and pos == "random":
        # 随机分配一个该图层的位置
        operating_layer = self._operating_layer(layer=layer)
        assert operating_layer is not None
        pos = operating_layer.select().random.choice()
    else:
        # 检查这个位置的类型,返回图层和位置
        layer, pos = _get_layer_and_position(pos, layer=layer)
        operating_layer = self._operating_layer(layer=layer)
        assert operating_layer is not None
    move_agent_to(self.actor, layer=operating_layer, pos=pos)

off

off()

Remove the actor from the world.

Source code in abses/move.py
def off(self) -> None:
    """Remove the actor from the world."""
    if self.actor.at is None:
        raise ABSESpyError("The actor is not located on a cell.")
    if self.actor.on_earth:
        container = self.actor.at.agents
        if container is None:
            raise ABSESpyError("The actor is not located on a cell.")
        container.remove(self.actor)
    del self.actor.at

by

by(direction, distance=1)

Move the actor by a specific distance.

Parameters:

Name Type Description Default
direction MovingDirection

The direction to move. It should be a direction string such as: "left", "right", "up", "down", "up left", "up right", "down left", "down right".

required
distance int

The distance to move toward the direction.

1

Raises:

Type Description
ABSESpyError

If the actor is not located on a cell, thus cannot move.

ValueError

If the direction is invalid.

Source code in abses/move.py
def by(self, direction: MovingDirection, distance: int = 1) -> None:
    """Move the actor by a specific distance.

    Parameters:
        direction:
            The direction to move.
            It should be a direction string such as:
            "left", "right", "up", "down", "up left", "up right", "down left", "down right".
        distance:
            The distance to move toward the direction.

    Raises:
        ABSESpyError:
            If the actor is not located on a cell, thus cannot move.
        ValueError:
            If the direction is invalid.
    """
    if (self.actor.at is None) or (self.layer is None):
        raise ABSESpyError(
            "The actor is not located on a cell, thus cannot move."
        )
    old_row, old_col = self.actor.at.indices
    if direction == "left":
        new_indices = (old_row, old_col - distance)
    elif direction == "right":
        new_indices = (old_row, old_col + distance)
    elif direction == "up":
        new_indices = (old_row - distance, old_col)
    elif direction == "down":
        new_indices = (old_row + distance, old_col)
    elif direction in {"up left", "left up"}:
        new_indices = (old_row - distance, old_col - distance)
    elif direction in {"up right", "right up"}:
        new_indices = (old_row - distance, old_col + distance)
    elif direction in {"down left", "left down"}:
        new_indices = (old_row + distance, old_col - distance)
    elif direction in {"down right", "right down"}:
        new_indices = (old_row + distance, old_col + distance)
    else:
        raise ValueError(f"Invalid direction {direction}.")
    cell = self.layer.array_cells[new_indices[0]][new_indices[1]]
    self.actor.move.to(cell)

random

random(prob=None, **kwargs)

Move the actor to a random location nearby.

Parameters:

Name Type Description Default
prob Optional[str]

The probability to select a cell.

None
kwargs Any

Passing keyword args to PatchCell.neighboring, used to select neighboring cells.

{}
Source code in abses/move.py
def random(self, prob: Optional[str] = None, **kwargs: Any) -> None:
    """Move the actor to a random location nearby.

    Parameters:
        prob:
            The probability to select a cell.
        kwargs:
            Passing keyword args to `PatchCell.neighboring`,
            used to select neighboring cells.
    """
    if self.actor.at is None:
        raise ABSESpyError("The actor is not located on a cell.")
    cells = self.actor.at.neighboring(**kwargs)
    self.actor.move.to(cells.random.choice(prob=prob))