checkpoint: visited methods
- Add methods to mark cells as visited and to get results of the visits. - renamed MazeDirections to MazeDirection
This commit is contained in:
parent
5c48f47a0a
commit
c809292c04
4 changed files with 63 additions and 38 deletions
24
cell.py
24
cell.py
|
@ -76,8 +76,10 @@ class Cell:
|
|||
# A reference to the root Window class for drawing purposes.
|
||||
self._window = window
|
||||
|
||||
self.visited_by_maze_generator = False
|
||||
self.visited_by_maze_solver = False
|
||||
self._visited: Dict[str, bool] = {
|
||||
"generator": False,
|
||||
"solver": False,
|
||||
}
|
||||
|
||||
def configure_walls(
|
||||
self,
|
||||
|
@ -137,3 +139,21 @@ class Cell:
|
|||
fill_colour = "grey"
|
||||
line = Line(self.centre(), to_cell.centre())
|
||||
self._window.draw_line(line, fill_colour)
|
||||
|
||||
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
|
||||
|
|
8
main.py
8
main.py
|
@ -8,10 +8,10 @@ def main():
|
|||
game = Maze(
|
||||
x_position=10,
|
||||
y_position=10,
|
||||
num_cell_rows=30,
|
||||
num_cells_per_row=30,
|
||||
cell_size_x=20,
|
||||
cell_size_y=20,
|
||||
num_cell_rows=16,
|
||||
num_cells_per_row=16,
|
||||
cell_size_x=40,
|
||||
cell_size_y=40,
|
||||
window=window
|
||||
)
|
||||
|
||||
|
|
53
maze.py
53
maze.py
|
@ -6,7 +6,7 @@ from graphics import Window
|
|||
from cell import Cell, CellWallLabels
|
||||
|
||||
|
||||
class MazeDirections(Enum):
|
||||
class MazeDirection(Enum):
|
||||
"""
|
||||
MazeDirection represents the directions you can
|
||||
take in the maze.
|
||||
|
@ -35,35 +35,35 @@ class MazePosition:
|
|||
|
||||
def get_adjacent_position(
|
||||
self,
|
||||
direction: MazeDirections
|
||||
direction: MazeDirection
|
||||
) -> 'MazePosition':
|
||||
if direction not in MazeDirections:
|
||||
if direction not in MazeDirection:
|
||||
raise TypeError(
|
||||
"The argument does not appear to be a valid maze direction."
|
||||
)
|
||||
|
||||
if direction is MazeDirections.ABOVE and (self.i-1 >= 0):
|
||||
if direction is MazeDirection.ABOVE and (self.i-1 >= 0):
|
||||
return MazePosition(
|
||||
i=self.i-1,
|
||||
j=self.j,
|
||||
max_i=self.max_i,
|
||||
max_j=self.max_j,
|
||||
)
|
||||
if direction is MazeDirections.BELOW and (self.i+1 <= self.max_i):
|
||||
if direction is MazeDirection.BELOW and (self.i+1 <= self.max_i):
|
||||
return MazePosition(
|
||||
i=self.i+1,
|
||||
j=self.j,
|
||||
max_i=self.max_i,
|
||||
max_j=self.max_j,
|
||||
)
|
||||
if direction is MazeDirections.LEFT and (self.j-1 >= 0):
|
||||
if direction is MazeDirection.LEFT and (self.j-1 >= 0):
|
||||
return MazePosition(
|
||||
i=self.i,
|
||||
j=self.j-1,
|
||||
max_i=self.max_i,
|
||||
max_j=self.max_j,
|
||||
)
|
||||
if direction is MazeDirections.RIGHT and (self.j+1 <= self.max_j):
|
||||
if direction is MazeDirection.RIGHT and (self.j+1 <= self.max_j):
|
||||
return MazePosition(
|
||||
i=self.i,
|
||||
j=self.j+1,
|
||||
|
@ -179,19 +179,21 @@ class Maze:
|
|||
cells and randomly knocking down the walls to create the maze's paths.
|
||||
"""
|
||||
|
||||
generator = "generator"
|
||||
|
||||
current_cell = self._cells[current_position.i][current_position.j]
|
||||
current_cell.visited_by_maze_generator = True
|
||||
current_cell.mark_as_visited_by(generator)
|
||||
|
||||
while True:
|
||||
possible_directions: List[MazeDirections] = []
|
||||
possible_directions: List[MazeDirection] = []
|
||||
|
||||
for direction in MazeDirections:
|
||||
for direction in MazeDirection:
|
||||
adjacent_position = current_position.get_adjacent_position(
|
||||
direction)
|
||||
if adjacent_position is None:
|
||||
continue
|
||||
adjacent_cell = self._cells[adjacent_position.i][adjacent_position.j]
|
||||
if adjacent_cell.visited_by_maze_generator:
|
||||
if adjacent_cell.was_visited_by(generator):
|
||||
continue
|
||||
possible_directions.append(direction)
|
||||
|
||||
|
@ -205,16 +207,16 @@ class Maze:
|
|||
chosen_direction)
|
||||
next_cell = self._cells[next_position.i][next_position.j]
|
||||
|
||||
if chosen_direction is MazeDirections.ABOVE:
|
||||
if chosen_direction is MazeDirection.ABOVE:
|
||||
current_cell.configure_walls(top=False)
|
||||
next_cell.configure_walls(bottom=False)
|
||||
elif chosen_direction is MazeDirections.BELOW:
|
||||
elif chosen_direction is MazeDirection.BELOW:
|
||||
current_cell.configure_walls(bottom=False)
|
||||
next_cell.configure_walls(top=False)
|
||||
elif chosen_direction is MazeDirections.LEFT:
|
||||
elif chosen_direction is MazeDirection.LEFT:
|
||||
current_cell.configure_walls(left=False)
|
||||
next_cell.configure_walls(right=False)
|
||||
elif chosen_direction is MazeDirections.RIGHT:
|
||||
elif chosen_direction is MazeDirection.RIGHT:
|
||||
current_cell.configure_walls(right=False)
|
||||
next_cell.configure_walls(left=False)
|
||||
|
||||
|
@ -248,25 +250,28 @@ class Maze:
|
|||
current_position: MazePosition,
|
||||
end_position: MazePosition,
|
||||
) -> bool:
|
||||
solver = "solver"
|
||||
|
||||
if current_position == end_position:
|
||||
return True
|
||||
current_cell = self._cells[current_position.i][current_position.j]
|
||||
current_cell.visited_by_maze_solver = True
|
||||
current_cell.mark_as_visited_by(solver)
|
||||
|
||||
wall_map: Dict[MazeDirections, CellWallLabels] = {
|
||||
MazeDirections.ABOVE: CellWallLabels.BOTTOM,
|
||||
MazeDirections.BELOW: CellWallLabels.TOP,
|
||||
MazeDirections.LEFT: CellWallLabels.RIGHT,
|
||||
MazeDirections.RIGHT: CellWallLabels.LEFT,
|
||||
wall_map: Dict[MazeDirection, CellWallLabels] = {
|
||||
MazeDirection.ABOVE: CellWallLabels.BOTTOM,
|
||||
MazeDirection.BELOW: CellWallLabels.TOP,
|
||||
MazeDirection.LEFT: CellWallLabels.RIGHT,
|
||||
MazeDirection.RIGHT: CellWallLabels.LEFT,
|
||||
}
|
||||
|
||||
for direction in MazeDirections:
|
||||
for direction in MazeDirection:
|
||||
adjacent_position = current_position.get_adjacent_position(
|
||||
direction)
|
||||
direction
|
||||
)
|
||||
if adjacent_position is None:
|
||||
continue
|
||||
adjacent_cell = self._cells[adjacent_position.i][adjacent_position.j]
|
||||
if adjacent_cell.visited_by_maze_solver or adjacent_cell.wall_exists(wall_map[direction]):
|
||||
if adjacent_cell.was_visited_by(solver) or adjacent_cell.wall_exists(wall_map[direction]):
|
||||
continue
|
||||
self._draw_path(current_cell, adjacent_cell)
|
||||
result = self._solve_r(adjacent_position, end_position)
|
||||
|
|
16
tests.py
16
tests.py
|
@ -131,42 +131,42 @@ class Tests(unittest.TestCase):
|
|||
cases = [
|
||||
{
|
||||
"position": maze.MazePosition(i=3, j=4, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.ABOVE,
|
||||
"direction": maze.MazeDirection.ABOVE,
|
||||
"expected": maze.MazePosition(i=2, j=4, max_i=10, max_j=10),
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=9, j=4, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.BELOW,
|
||||
"direction": maze.MazeDirection.BELOW,
|
||||
"expected": maze.MazePosition(i=10, j=4, max_i=10, max_j=10),
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=1, j=1, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.LEFT,
|
||||
"direction": maze.MazeDirection.LEFT,
|
||||
"expected": maze.MazePosition(i=1, j=0, max_i=10, max_j=10),
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=3, j=9, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.RIGHT,
|
||||
"direction": maze.MazeDirection.RIGHT,
|
||||
"expected": maze.MazePosition(i=3, j=10, max_i=10, max_j=10),
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=0, j=4, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.ABOVE,
|
||||
"direction": maze.MazeDirection.ABOVE,
|
||||
"expected": None,
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=10, j=4, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.BELOW,
|
||||
"direction": maze.MazeDirection.BELOW,
|
||||
"expected": None,
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=1, j=0, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.LEFT,
|
||||
"direction": maze.MazeDirection.LEFT,
|
||||
"expected": None,
|
||||
},
|
||||
{
|
||||
"position": maze.MazePosition(i=3, j=10, max_i=10, max_j=10),
|
||||
"direction": maze.MazeDirections.RIGHT,
|
||||
"direction": maze.MazeDirection.RIGHT,
|
||||
"expected": None,
|
||||
},
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue