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:
parent
70175b3afd
commit
536711f808
6 changed files with 111 additions and 30 deletions
17
.github/workflows/workflow.yaml
vendored
Normal file
17
.github/workflows/workflow.yaml
vendored
Normal 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
65
cell.py
|
@ -1,6 +1,17 @@
|
||||||
from graphics import Window, Point, Line
|
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:
|
class Cell:
|
||||||
"""
|
"""
|
||||||
A Cell represents a grid on the maze.
|
A Cell represents a grid on the maze.
|
||||||
|
@ -56,35 +67,39 @@ class Cell:
|
||||||
"""
|
"""
|
||||||
draw draws the cell onto the canvas
|
draw draws the cell onto the canvas
|
||||||
"""
|
"""
|
||||||
if self._window:
|
if not self._window:
|
||||||
if self._top_wall.exists:
|
return
|
||||||
self._window.draw_line(self._top_wall.line)
|
|
||||||
if self._bottom_wall.exists:
|
if self._top_wall.exists:
|
||||||
self._window.draw_line(self._bottom_wall.line)
|
self._window.draw_line(self._top_wall.line, fill_colour=self._window.cell_grid_colour)
|
||||||
if self._left_wall.exists:
|
else:
|
||||||
self._window.draw_line(self._left_wall.line)
|
self._window.draw_line(self._top_wall.line, fill_colour=self._window.background_colour)
|
||||||
if self._right_wall.exists:
|
|
||||||
self._window.draw_line(self._right_wall.line)
|
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:
|
def draw_move(self, to_cell: 'Cell', undo: bool = False) -> None:
|
||||||
"""
|
"""
|
||||||
draw_move draws a path between the centre of this cell and
|
draw_move draws a path between the centre of this cell and
|
||||||
the centre of the given cell.
|
the centre of the given cell.
|
||||||
"""
|
"""
|
||||||
if self._window:
|
if not self._window:
|
||||||
fill_colour = "red"
|
return
|
||||||
if undo:
|
|
||||||
fill_colour = "grey"
|
|
||||||
line = Line(self.centre(), to_cell.centre())
|
|
||||||
self._window.draw_line(line, fill_colour)
|
|
||||||
|
|
||||||
|
fill_colour = "red"
|
||||||
class CellWall:
|
if undo:
|
||||||
"""
|
fill_colour = "grey"
|
||||||
A CellWall represents the existence (or non-existence) of
|
line = Line(self.centre(), to_cell.centre())
|
||||||
a Cell's wall.
|
self._window.draw_line(line, fill_colour)
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, line: Line) -> None:
|
|
||||||
self.exists = True
|
|
||||||
self.line = line
|
|
||||||
|
|
|
@ -49,9 +49,13 @@ class Window:
|
||||||
centre_y = int(screen_height/2 - height/2)
|
centre_y = int(screen_height/2 - height/2)
|
||||||
self._root.geometry(f"{width}x{height}+{centre_x}+{centre_y}")
|
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 = Canvas(self._root)
|
||||||
self._canvas.config(
|
self._canvas.config(
|
||||||
bg="white",
|
bg=self.background_colour,
|
||||||
height=height,
|
height=height,
|
||||||
width=width,
|
width=width,
|
||||||
)
|
)
|
||||||
|
|
2
main.py
2
main.py
|
@ -5,7 +5,7 @@ from maze import Maze
|
||||||
def main():
|
def main():
|
||||||
window = Window(800, 800)
|
window = Window(800, 800)
|
||||||
|
|
||||||
_ = Maze(10, 10, 39, 39, 20, 20, window)
|
_ = Maze(10, 10, 3, 39, 20, 20, window)
|
||||||
|
|
||||||
window.wait_for_close()
|
window.wait_for_close()
|
||||||
|
|
||||||
|
|
9
maze.py
9
maze.py
|
@ -30,6 +30,7 @@ class Maze:
|
||||||
# Create the Maze's cells
|
# Create the Maze's cells
|
||||||
self._cells: List[List[Cell]] = [None for i in range(self._num_cell_rows)]
|
self._cells: List[List[Cell]] = [None for i in range(self._num_cell_rows)]
|
||||||
self._create_cells()
|
self._create_cells()
|
||||||
|
self._break_entrance_and_exit()
|
||||||
|
|
||||||
def _create_cells(self):
|
def _create_cells(self):
|
||||||
cursor_x = self._x_position
|
cursor_x = self._x_position
|
||||||
|
@ -56,6 +57,14 @@ class Maze:
|
||||||
if self._window:
|
if self._window:
|
||||||
self._draw_cells()
|
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):
|
def _draw_cells(self):
|
||||||
for i in range(self._num_cell_rows):
|
for i in range(self._num_cell_rows):
|
||||||
for j in range(self._num_cells_per_row):
|
for j in range(self._num_cells_per_row):
|
||||||
|
|
42
tests.py
42
tests.py
|
@ -4,6 +4,9 @@ from maze import Maze
|
||||||
|
|
||||||
class Tests(unittest.TestCase):
|
class Tests(unittest.TestCase):
|
||||||
def test_maze_create_cell_grid(self):
|
def test_maze_create_cell_grid(self):
|
||||||
|
"""
|
||||||
|
test_maze_create_cell_grid tests that the maze is constructed properly.
|
||||||
|
"""
|
||||||
cases = [
|
cases = [
|
||||||
{
|
{
|
||||||
"number_of_cell_rows": 12,
|
"number_of_cell_rows": 12,
|
||||||
|
@ -20,9 +23,42 @@ class Tests(unittest.TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
for case in cases:
|
for case in cases:
|
||||||
maze = Maze(0, 0, case["number_of_cell_rows"], case["number_of_cells_per_row"], 2, 2)
|
maze = Maze(
|
||||||
self.assertEqual(len(maze._cells), case["number_of_cell_rows"])
|
0,
|
||||||
self.assertEqual(len(maze._cells[0]), case["number_of_cells_per_row"])
|
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__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue