fix: only draw the graphics if the window exists

Optionally pass in the reference of the Window to the Maze and
Cell classes, and only draw the graphics if the reference exists.

Use a single underscore instead of the double underscore for private
Class members.
This commit is contained in:
Dan Anglin 2024-02-13 13:39:25 +00:00
parent 30792f25b0
commit 2ebb555bac
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
3 changed files with 77 additions and 75 deletions

44
cell.py
View file

@ -10,7 +10,7 @@ class Cell:
self, self,
x1: int, y1: int, x1: int, y1: int,
x2: int, y2: int, x2: int, y2: int,
window: Window window: Window = None,
) -> None: ) -> None:
# Define the cell walls # Define the cell walls
top_wall = Line(Point(x1, y1), Point(x2, y1)) top_wall = Line(Point(x1, y1), Point(x2, y1))
@ -18,18 +18,18 @@ class Cell:
left_wall = Line(Point(x1, y1), Point(x1, y2)) left_wall = Line(Point(x1, y1), Point(x1, y2))
right_wall = Line(Point(x2, y1), Point(x2, y2)) right_wall = Line(Point(x2, y1), Point(x2, y2))
self.__top_wall = CellWall(top_wall) self._top_wall = CellWall(top_wall)
self.__bottom_wall = CellWall(bottom_wall) self._bottom_wall = CellWall(bottom_wall)
self.__left_wall = CellWall(left_wall) self._left_wall = CellWall(left_wall)
self.__right_wall = CellWall(right_wall) self._right_wall = CellWall(right_wall)
# Calculate the cell's central point # Calculate the cell's central point
centre_x = x1 + ((x2 - x1) / 2) centre_x = x1 + ((x2 - x1) / 2)
centre_y = y1 + ((y2 - y1) / 2) centre_y = y1 + ((y2 - y1) / 2)
self.__centre = Point(centre_x, centre_y) self._centre = Point(centre_x, centre_y)
# A reference to the root Window class for drawing purposes. # A reference to the root Window class for drawing purposes.
self.__window = window self._window = window
def configure_walls( def configure_walls(
self, self,
@ -41,40 +41,42 @@ class Cell:
""" """
configure_walls configures the existence of the Cell's walls. configure_walls configures the existence of the Cell's walls.
""" """
self.__top_wall.exists = top self._top_wall.exists = top
self.__bottom_wall.exists = bottom self._bottom_wall.exists = bottom
self.__left_wall.exists = left self._left_wall.exists = left
self.__right_wall.exists = right self._right_wall.exists = right
def centre(self) -> Point: def centre(self) -> Point:
""" """
centre returns the Cell's central point centre returns the Cell's central point
""" """
return self.__centre return self._centre
def draw(self) -> None: def draw(self) -> None:
""" """
draw draws the cell onto the canvas draw draws the cell onto the canvas
""" """
if self.__top_wall.exists: if self._window:
self.__window.draw_line(self.__top_wall.line) if self._top_wall.exists:
if self.__bottom_wall.exists: self._window.draw_line(self._top_wall.line)
self.__window.draw_line(self.__bottom_wall.line) if self._bottom_wall.exists:
if self.__left_wall.exists: self._window.draw_line(self._bottom_wall.line)
self.__window.draw_line(self.__left_wall.line) if self._left_wall.exists:
if self.__right_wall.exists: self._window.draw_line(self._left_wall.line)
self.__window.draw_line(self.__right_wall.line) if self._right_wall.exists:
self._window.draw_line(self._right_wall.line)
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:
fill_colour = "red" fill_colour = "red"
if undo: if undo:
fill_colour = "grey" fill_colour = "grey"
line = Line(self.centre(), to_cell.centre()) line = Line(self.centre(), to_cell.centre())
self.__window.draw_line(line, fill_colour) self._window.draw_line(line, fill_colour)
class CellWall: class CellWall:

View file

@ -38,51 +38,51 @@ class Window:
""" """
def __init__(self, width: int, height: int) -> None: def __init__(self, width: int, height: int) -> None:
self.__root = Tk() self._root = Tk()
self.__root.title("Maze Solver") self._root.title("Maze Solver")
self.__root.protocol("WM_DELETE_WINDOW", self.close) self._root.protocol("WM_DELETE_WINDOW", self.close)
# Position the window to the centre of the screen # Position the window to the centre of the screen
screen_width = self.__root.winfo_screenwidth() screen_width = self._root.winfo_screenwidth()
screen_height = self.__root.winfo_screenheight() screen_height = self._root.winfo_screenheight()
centre_x = int(screen_width/2 - width/2) centre_x = int(screen_width/2 - width/2)
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}")
self.__canvas = Canvas(self.__root) self._canvas = Canvas(self._root)
self.__canvas.config( self._canvas.config(
bg="white", bg="white",
height=height, height=height,
width=width, width=width,
) )
self.__canvas.pack() self._canvas.pack()
self.__is_running = False self._running = False
def redraw(self) -> None: def redraw(self) -> None:
""" """
redraw redraws all the graphics in the window. redraw redraws all the graphics in the window.
""" """
self.__root.update_idletasks() self._root.update_idletasks()
self.__root.update() self._root.update()
def wait_for_close(self) -> None: def wait_for_close(self) -> None:
""" """
wait_for_close continuously redraws the window until wait_for_close continuously redraws the window until
it is set to close. it is set to close.
""" """
self.__is_running = True self._running = True
while self.__is_running: while self._running:
self.redraw() self.redraw()
def draw_line(self, line: Line, fill_colour: str = "black") -> None: def draw_line(self, line: Line, fill_colour: str = "black") -> None:
""" """
draw_line draws a line on the canvas. draw_line draws a line on the canvas.
""" """
line.draw(self.__canvas, fill_colour) line.draw(self._canvas, fill_colour)
def close(self) -> None: def close(self) -> None:
""" """
close sets the window to close. close sets the window to close.
""" """
self.__is_running = False self._running = False

68
maze.py
View file

@ -17,51 +17,51 @@ class Maze:
num_columns: int, num_columns: int,
cell_size_x: int, cell_size_x: int,
cell_size_y: int, cell_size_y: int,
window: Window, window: Window = None,
): ) -> None:
self.__x_position = x_position self._x_position = x_position
self.__y_position = y_position self._y_position = y_position
self.__num_rows = num_rows self._num_rows = num_rows
self.__num_columns = num_columns self._num_columns = num_columns
self.__cell_size_x = cell_size_x self._cell_size_x = cell_size_x
self.__cell_size_y = cell_size_y self._cell_size_y = cell_size_y
self.__window = window self._window = window
# Create the Maze's cells # Create the Maze's cells
self.__cells: List[List[Cell]] = [None for i in range(self.__num_rows)] self._cells: List[List[Cell]] = [None for i in range(self._num_rows)]
self.__create_cells() self._create_cells()
def __create_cells(self): def _create_cells(self):
cursor_x = self.__x_position cursor_x = self._x_position
cursor_y = self.__y_position cursor_y = self._y_position
for i in range(self.__num_rows): for i in range(self._num_rows):
column: List[Cell] = [None for j in range(self.__num_columns)] column: List[Cell] = [None for j in range(self._num_columns)]
for j in range(self.__num_columns): for j in range(self._num_columns):
cell = Cell( cell = Cell(
cursor_x, cursor_x,
cursor_y, cursor_y,
(cursor_x + self.__cell_size_x), (cursor_x + self._cell_size_x),
(cursor_y + self.__cell_size_y), (cursor_y + self._cell_size_y),
self.__window self._window
) )
column[j] = cell column[j] = cell
if j == self.__num_columns - 1: if j == self._num_columns - 1:
cursor_x = self.__x_position cursor_x = self._x_position
else: else:
cursor_x += self.__cell_size_x cursor_x += self._cell_size_x
self.__cells[i] = column self._cells[i] = column
cursor_y += self.__cell_size_y cursor_y += self._cell_size_y
# Draw the maze in a dramatic way. if self._window:
self.__draw_cells() self._draw_cells()
def __draw_cells(self): def _draw_cells(self):
for i in range(self.__num_rows): for i in range(self._num_rows):
for j in range(self.__num_columns): for j in range(self._num_columns):
self.__cells[i][j].draw() self._cells[i][j].draw()
self.__animate() self._animate()
def __animate(self): def _animate(self):
self.__window.redraw() self._window.redraw()
sleep(0.05) sleep(0.05)