feat: add entrance, exit to the maze.

- Add an entrance and exit to the maze. The entrance will always
  be on the top left and the exit will always be on the bottom
  right.
- Add a simple GitHub actions workflow to run the Python tests.
This commit is contained in:
Dan Anglin 2024-02-13 15:52:28 +00:00
parent 70175b3afd
commit 536711f808
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
6 changed files with 111 additions and 30 deletions

17
.github/workflows/workflow.yaml vendored Normal file
View file

@ -0,0 +1,17 @@
---
name: test
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Python 3
uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python tests.py

65
cell.py
View file

@ -1,6 +1,17 @@
from graphics import Window, Point, Line
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
class Cell:
"""
A Cell represents a grid on the maze.
@ -56,35 +67,39 @@ class Cell:
"""
draw draws the cell onto the canvas
"""
if self._window:
if self._top_wall.exists:
self._window.draw_line(self._top_wall.line)
if self._bottom_wall.exists:
self._window.draw_line(self._bottom_wall.line)
if self._left_wall.exists:
self._window.draw_line(self._left_wall.line)
if self._right_wall.exists:
self._window.draw_line(self._right_wall.line)
if not self._window:
return
if self._top_wall.exists:
self._window.draw_line(self._top_wall.line, fill_colour=self._window.cell_grid_colour)
else:
self._window.draw_line(self._top_wall.line, fill_colour=self._window.background_colour)
if self._bottom_wall.exists:
self._window.draw_line(self._bottom_wall.line, fill_colour=self._window.cell_grid_colour)
else:
self._window.draw_line(self._bottom_wall.line, fill_colour=self._window.background_colour)
if self._left_wall.exists:
self._window.draw_line(self._left_wall.line, fill_colour=self._window.cell_grid_colour)
else:
self._window.draw_line(self._left_wall.line, fill_colour=self._window.background_colour)
if self._right_wall.exists:
self._window.draw_line(self._right_wall.line, fill_colour=self._window.cell_grid_colour)
else:
self._window.draw_line(self._right_wall.line, fill_colour=self._window.background_colour)
def draw_move(self, to_cell: 'Cell', undo: bool = False) -> None:
"""
draw_move draws a path between the centre of this cell and
the centre of the given cell.
"""
if self._window:
fill_colour = "red"
if undo:
fill_colour = "grey"
line = Line(self.centre(), to_cell.centre())
self._window.draw_line(line, fill_colour)
if not self._window:
return
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
fill_colour = "red"
if undo:
fill_colour = "grey"
line = Line(self.centre(), to_cell.centre())
self._window.draw_line(line, fill_colour)

View file

@ -49,9 +49,13 @@ class Window:
centre_y = int(screen_height/2 - height/2)
self._root.geometry(f"{width}x{height}+{centre_x}+{centre_y}")
# Styling
self.background_colour = "white"
self.cell_grid_colour = "black"
self._canvas = Canvas(self._root)
self._canvas.config(
bg="white",
bg=self.background_colour,
height=height,
width=width,
)

View file

@ -5,7 +5,7 @@ from maze import Maze
def main():
window = Window(800, 800)
_ = Maze(10, 10, 39, 39, 20, 20, window)
_ = Maze(10, 10, 3, 39, 20, 20, window)
window.wait_for_close()

View file

@ -30,6 +30,7 @@ class Maze:
# Create the Maze's cells
self._cells: List[List[Cell]] = [None for i in range(self._num_cell_rows)]
self._create_cells()
self._break_entrance_and_exit()
def _create_cells(self):
cursor_x = self._x_position
@ -56,6 +57,14 @@ class Maze:
if self._window:
self._draw_cells()
def _break_entrance_and_exit(self):
# break entrance and draw
self._cells[0][0].configure_walls(top=False)
self._cells[0][0].draw()
# break exit and draw
self._cells[self._num_cell_rows - 1][self._num_cells_per_row - 1].configure_walls(bottom=False)
self._cells[self._num_cell_rows - 1][self._num_cells_per_row - 1].draw()
def _draw_cells(self):
for i in range(self._num_cell_rows):
for j in range(self._num_cells_per_row):

View file

@ -4,6 +4,9 @@ from maze import Maze
class Tests(unittest.TestCase):
def test_maze_create_cell_grid(self):
"""
test_maze_create_cell_grid tests that the maze is constructed properly.
"""
cases = [
{
"number_of_cell_rows": 12,
@ -20,9 +23,42 @@ class Tests(unittest.TestCase):
]
for case in cases:
maze = Maze(0, 0, case["number_of_cell_rows"], case["number_of_cells_per_row"], 2, 2)
self.assertEqual(len(maze._cells), case["number_of_cell_rows"])
self.assertEqual(len(maze._cells[0]), case["number_of_cells_per_row"])
maze = Maze(
0,
0,
case["number_of_cell_rows"],
case["number_of_cells_per_row"],
2,
2,
)
self.assertEqual(
len(maze._cells),
case["number_of_cell_rows"],
)
self.assertEqual(
len(maze._cells[0]),
case["number_of_cells_per_row"],
)
def test_break_entrance_and_exit(self):
"""
test_break_entrance_and_exit tests to ensure that the Maze's entry and
exit Cells are open.
"""
number_of_cell_rows = 5
number_of_cells_per_row = 20
maze = Maze(
0,
0,
number_of_cell_rows,
number_of_cells_per_row,
2,
2,
)
print(f"entrance: {maze._cells[0][0]._top_wall}")
self.assertFalse(maze._cells[0][0]._top_wall.exists)
self.assertFalse(
maze._cells[number_of_cell_rows - 1][number_of_cells_per_row - 1]._bottom_wall.exists)
if __name__ == "__main__":