Source code for donjuan.space

from abc import ABC
from typing import List, Optional, Sequence, Set, Tuple, Union

from donjuan.cell import Cell
from donjuan.edge import Edge


[docs]class Space(ABC): """ A space is a section of a dungeon composed of `Cell`s. This object contains these cells in a ``set`` under the property :attr:`cells`. It also has a :attr:`name` and knows about any entrances to the room (a list of `Edge` objects) via the :attr:`entrances` property. Args: cells (Optional[Set[Cell]]): cells that make up this space name (Union[int, str], optional): defaults to '', the room name """ def __init__(self, cells: Optional[Set[Cell]] = None, name: Union[int, str] = ""): assert isinstance(name, (int, str)) self._name = name self._cells = cells or set() self.entrances: List[Edge] = [] self.assign_space_to_cells() self.reset_cell_coordinates()
[docs] def assign_space_to_cells(self) -> None: """Set the :attr:`space` attribute for each `Cell` to ``self``.""" for cell in self.cells: cell.set_space(self)
[docs] def reset_cell_coordinates(self) -> None: self._cell_coordinates = set(cell.coordinates for cell in self.cells)
@property def cells(self) -> Set[Cell]: return self._cells @property def cell_coordinates(self) -> Set[Tuple[int, int]]: return self._cell_coordinates @property def name(self) -> Union[int, str]: return str(self._name)
[docs] def add_cells(self, cells: Sequence[Cell]) -> None: """ Add cells to the set of cells in this space. Cells are added to both the :attr:`cells` set and the cell coordinates to the :attr:`cell_coordinates` set. Args: cells (Sequence[Cell]): any iterable collection of cells """ for cell in cells: self.cells.add(cell) self.cell_coordinates.add(cell.coordinates) return
[docs] def overlaps(self, other: "Space") -> bool: """ Compare the cells of this space to the other space to determine whether they overlap or not. Note, this algorithm is ``O(N)`` where ``N`` is the number of cells in this space, since set lookup is ``O(1)``. Args: other (Space): other space to check against Returns: ``True`` if they overlap, ``False`` if not """ # Loop over all of this space's cells for cell in self.cells: if cell.coordinates in other.cell_coordinates: return True # No overlap return False
[docs] def set_name(self, name: Union[int, str]) -> None: assert isinstance(name, (int, str)) self._name = name
[docs] def shift_vertical(self, n: int) -> None: """ Change the ``y`` coordinates of all :attr:`cells` by ``n``. Args: n (int): number to increment vertical position of cells """ for cell in self.cells: cell.set_y(cell.y + int(n)) self.reset_cell_coordinates() return
[docs] def shift_horizontal(self, n: int) -> None: """ Change the ``x`` coordinates of all :attr:`cells` by ``n``. Args: n (int): number to increment horizontal position of cells """ for cell in self.cells: cell.set_x(cell.x + int(n)) self.reset_cell_coordinates() return