Dan Anglin
9bb23b6c6d
Move the path drawing functionality to the Graphics class. The Cell class no longer needs to reference an instance of the Graphics class.
165 lines
4.4 KiB
Python
165 lines
4.4 KiB
Python
from typing import Dict
|
|
from enum import Enum
|
|
from line import Point, Line
|
|
import errors
|
|
|
|
|
|
class CellWallLabels(Enum):
|
|
"""
|
|
CellWallLabel is used to label a CellWall
|
|
"""
|
|
|
|
TOP = 0
|
|
BOTTOM = 1
|
|
LEFT = 2
|
|
RIGHT = 3
|
|
|
|
|
|
class CellWall:
|
|
"""
|
|
A CellWall represents the existence (or non-existence) of
|
|
a Cell's wall.
|
|
"""
|
|
|
|
def __init__(self, line: Line) -> None:
|
|
self._exists = True
|
|
self._line = line
|
|
self._line_colour = "black"
|
|
|
|
def configure(self, build: bool) -> None:
|
|
"""
|
|
builds or destroys the cell wall.
|
|
"""
|
|
if build:
|
|
self._build_wall()
|
|
else:
|
|
self._destroy_wall()
|
|
|
|
def _build_wall(self) -> None:
|
|
"""
|
|
builds the cell wall
|
|
"""
|
|
self._exists = True
|
|
self._line_colour = "black"
|
|
|
|
def _destroy_wall(self) -> None:
|
|
"""
|
|
destroys the cell wall
|
|
"""
|
|
self._exists = False
|
|
self._line_colour = "white"
|
|
|
|
def wall_up(self) -> bool:
|
|
"""
|
|
returns true if the cell wall is up.
|
|
"""
|
|
return self._exists
|
|
|
|
def get_line(self) -> Line:
|
|
return self._line
|
|
|
|
def get_line_colour(self) -> str:
|
|
"""
|
|
returns the line colour of the wall.
|
|
"""
|
|
return self._line_colour
|
|
|
|
|
|
class Cell:
|
|
"""
|
|
A Cell represents a grid on the maze.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
x1: int, y1: int,
|
|
x2: int, y2: int,
|
|
) -> None:
|
|
# Validation
|
|
if (x2 < x1) or (y2 < y1):
|
|
raise errors.CellInvalidError(x1, y1, x2, y2)
|
|
|
|
if (x2 - x1) < 2:
|
|
raise errors.CellTooSmallError("horizontal", x2-x1)
|
|
|
|
if (y2 - y1) < 2:
|
|
raise errors.CellTooSmallError("vertical", y2-y1)
|
|
|
|
# Define the cell walls
|
|
top_wall = Line(Point(x1, y1), Point(x2, y1))
|
|
bottom_wall = Line(Point(x1, y2), Point(x2, y2))
|
|
left_wall = Line(Point(x1, y1), Point(x1, y2))
|
|
right_wall = Line(Point(x2, y1), Point(x2, y2))
|
|
|
|
self._walls: Dict[CellWallLabels, CellWall] = {
|
|
CellWallLabels.TOP: CellWall(top_wall),
|
|
CellWallLabels.BOTTOM: CellWall(bottom_wall),
|
|
CellWallLabels.LEFT: CellWall(left_wall),
|
|
CellWallLabels.RIGHT: CellWall(right_wall),
|
|
}
|
|
|
|
# Calculate the cell's central point
|
|
centre_x = x1 + ((x2 - x1) / 2)
|
|
centre_y = y1 + ((y2 - y1) / 2)
|
|
self._centre = Point(centre_x, centre_y)
|
|
|
|
self._visited: Dict[str, bool] = {
|
|
"generator": False,
|
|
"solver": False,
|
|
}
|
|
|
|
def configure_walls(
|
|
self,
|
|
top: bool = None,
|
|
bottom: bool = None,
|
|
left: bool = None,
|
|
right: bool = None,
|
|
) -> None:
|
|
"""
|
|
configure_walls configures the existence of the Cell's walls.
|
|
"""
|
|
if top is not None:
|
|
self._walls[CellWallLabels.TOP].configure(top)
|
|
if bottom is not None:
|
|
self._walls[CellWallLabels.BOTTOM].configure(bottom)
|
|
if left is not None:
|
|
self._walls[CellWallLabels.LEFT].configure(left)
|
|
if right is not None:
|
|
self._walls[CellWallLabels.RIGHT].configure(right)
|
|
|
|
def centre(self) -> Point:
|
|
"""
|
|
centre returns the Cell's central point
|
|
"""
|
|
return self._centre
|
|
|
|
def wall_exists(self, wall: CellWallLabels) -> bool:
|
|
"""
|
|
returns True if a given cell wall exists, or false otherwise.
|
|
"""
|
|
if wall not in CellWallLabels:
|
|
raise TypeError(
|
|
"The argument does not appear to be a valid cell wall."
|
|
)
|
|
return self._walls[wall].wall_up()
|
|
|
|
def was_visited_by(self, visitor: str) -> bool:
|
|
"""
|
|
returns True if the cell was visited by the
|
|
specified visitor.
|
|
"""
|
|
if visitor not in ("solver", "generator"):
|
|
raise ValueError(f"This is an unknown visitor ({visitor})")
|
|
|
|
return self._visited[visitor]
|
|
|
|
def mark_as_visited_by(self, visitor: str) -> None:
|
|
"""
|
|
marks the cell as visited by the specified visitor.
|
|
"""
|
|
if visitor not in ("solver", "generator"):
|
|
raise ValueError(f"This is an unknown visitor ({visitor})")
|
|
self._visited[visitor] = True
|
|
|
|
def get_walls(self) -> Dict[CellWallLabels, CellWall]:
|
|
return self._walls
|