This is a maze generator and solver. It is a simple deskptop app that uses python and tkinter. Here is some documentation of the functions
this will redraw all the graphics in the window. Tkinter is not a reactive framework like React or Vue - we need to tell the window when it render to visuals.
The redraw()
method on the window class simply call the root widget's update_idletasks()
and update()
methods. Each time this is called, the window will redraw itself.
It draws a line from the center of one cell to another. The method definition look something like this:
def draw_move(self, to_cell, undo=False):
The undo
flag is not set, the line to draw is "red"
. Otherwise make it "gray"
. This is so that when we go to draw the path, whenever we backtrack we can show that in a different color to better visualize what's happening.
Use the x/y coordinates of the 2 cells in question to decide how to draw the line connecting the two cells.
The recursive break_walls_r
method is a breadth-first traversal through the cells, breaking down walls as it goes. I'll describe the algorithm I used,
- Mark the current cell as visited
- In a loop:
- Create a new empty list which will hold the
i
andj
values you need to visit - Check the cells that are directly adjacent to the current cell. If one isn't visited, keep track of it as a "possible direction" that you can move in.
- If there are no directions you can go from the current cell, then draw the current cell and
return
to break out of the loop - Otherwise, pick a random direction.
- Knock down the walls between the current cell and the chosen cell.
- Move to the chosen cell by recursively calling
_break_walls_r
- Create a new empty list which will hold the
The solve()
method on the Maze
class simply calls the _solve_r
method starting at i=0
and j=0
. It return True
if the maze was solved, False
otherwise. This is the same return value as _solve_r
.
This is a depth-first first solution to the maze. Here were my steps.
The _solve_r
method returns True
if the current cell is an end cell, OR if it leads to the end cell. It returns False
if the current cell is a loser cell.
- Call the
_animate
method. - Mark the current cell as visited
- If you are at the "end" cell (the goal) then return
True
. - For each direction:
- If there is a cell in that direction, there is no wall blocking you, and that cell hasn't been visited:
- Draw a move between the current cell and that cell
- Call
_solve_r
recursively to move to that cell. If that cell returnsTrue
, then just returnTrue
and don't worry about the other directions. - Otherwise, draw an "undo" move between the current cell and the next cell
- If there is a cell in that direction, there is no wall blocking you, and that cell hasn't been visited:
- If none of the directions worked out, return
False
.
Call maze.solve()
in the main function and watch your algorithm do its work!
This code is written by Lane Wagner who gave permission to use it for this exercise. It was originally produced for boot.dev