maze generator using Python with Pygame Module GUI

introduction
In this maze generator using Python, realm of logic, problem-solving, and computer science, mazes offer a visually intuitive and exciting way to learn about recursion, pathfinding algorithms, and graph traversal techniques. This Creative maze generator using Python Generator & Solver is a fully interactive tool built using Python’s Tkinter GUI and designed specifically for execution within a Jupyter Notebook environment.
At its core, the project enables users to generate random mazes using a classic recursive backtracking algorithm and solve them visually using Breadth-First Search (BFS). But unlike basic versions, this upgraded version brings modern UI aesthetics, animation, and user control to the forefront.
Why It’s Creative
Unlike a traditional grid generator:
-
It includes dynamic size input, letting the user define maze dimensions.
-
Adds live animation while solving the maze, making the pathfinding logic come alive step-by-step.
-
Uses color-coded visuals:
-
Walls in dark shades
-
Explored paths in light gray
-
Final path in bright red
-
-
Features emoji-enhanced buttons, intuitive layout, and responsive canvas resizing.
Educational Applications
This GUI is not just fun to use, but also a powerful tool to teach or learn:
-
Recursive Backtracking for maze generation
-
Graph Traversal (Breadth-First Search)
-
Data Structures like stacks, queues, 2D matrices, and parent-pointers
-
Event-Driven GUI Programming with canvas rendering
Practical Utility
Beyond classroom demos, this can be a base for:
-
Game development (AI navigation, level design)
-
Puzzle creators and solvers
-
AI visualizations
-
Robotics path planning simulation
-
Interview prep for recursion and search logic
What the User Can Do:
-
Enter a maze size (e.g., 10×10, 20×20, etc.)
-
Click a button to generate a new maze instantly
-
Click another button to visualize the solution path
-
Watch the solver animate cell-by-cell
Tech Stack Overview
Component | Role |
---|---|
tkinter |
GUI window, canvas, buttons |
random |
Maze generation with random directions |
deque |
Queue for BFS traversal |
time.sleep() |
Animation delays |
recursive DFS |
Maze generation |
BFS |
Maze solver |
Future Extensions
This creative tool can be extended further to include:
-
Custom start/end points
-
Save maze as image or GIF
-
DFS vs BFS toggle
-
Maze with keys, coins, traps (for game dev)
-
Speed control slider for animation
This Creative Maze Generator & Solver bridges the gap between algorithm theory and visual experience. It is easy enough for beginners to understand, but powerful enough to build on for advanced use. Whether you’re learning, teaching, or experimenting—this project makes algorithms visual, fun, and interactive—all inside Jupyter Notebook.
steps to create maze solver and generator
Step 1: Open Jupyter Notebook
Launch Jupyter Notebook from Anaconda Navigator, Terminal, or VS Code.
Create a new Python notebook file (e.g.,
maze_gui.ipynb
).
Step 2: Import Required Modules
import tkinter as tk
import random
from collections import deque
import time
tkinter
: For GUI components (canvas, buttons, input fields).random
: To shuffle directions during maze generation.deque
: Used in Breadth-First Search (BFS) for solving the maze.time
: To slow down animations during pathfinding.
Step 3: Define Constants
CELL_SIZE = 25
Sets the size of each cell in the maze (affects canvas width/height).
Step 4: Create CreativeMazeApp
Class
class CreativeMazeApp:
def __init__(self, root):
...
Initializes the GUI components:
Entry to input grid size
Buttons to generate & solve maze
Canvas to draw the maze
Frame structure for layout styling
Step 5: Build generate_maze()
Function
def generate_maze(self):
...
Takes size input from Entry box
Initializes a 2D grid filled with walls (
1
)Calls Recursive Backtracking DFS to carve paths (
0
)Uses
random.shuffle()
to randomize direction
Step 6: Draw Maze on Canvas
def draw_grid(self):
...
Loops through the grid
Fills rectangles for walls (
#2c3e50
) and paths (white
)Uses
.create_rectangle()
to draw maze structure visually
Step 7: Create solve_maze()
Function
def solve_maze(self):
...
Implements BFS (Breadth-First Search) to find the shortest path
Tracks visited cells and parents using 2D lists
Calls
mark_visited()
to animate each visited node with colorAfter reaching the goal, backtracks to mark the shortest path with red ovals
Step 8: Define mark_visited()
Helper Function
def mark_visited(r, c, color):
...
Visually marks a cell as visited or part of the solution
Uses small circles (
.create_oval
) inside each cellAdds a small delay using
time.sleep(0.01)
for smooth animation
Step 9: Create and Launch the GUI
root = tk.Tk()
app = CreativeMazeApp(root)
root.mainloop()
Instantiates the app
Starts the Tkinter event loop to display GUI
Summary of Functional Components
Function | Purpose |
---|---|
__init__() | GUI setup and layout |
generate_maze() | Creates maze using DFS |
draw_grid() | Renders maze grid on canvas |
solve_maze() | Solves maze using BFS |
mark_visited() | Animates solving process |
code explanation
Step 1: Import Libraries
import tkinter as tk
import random
from collections import deque
import time
tkinter
: To create the GUI layout (canvas, buttons, input fields).random
: For shuffling directions in maze generation.deque
: For BFS queue structure (fast append/pop).time
: To add animation delay during solving.
Step 2: Set Cell Size
CELL_SIZE = 25
Each maze cell will be drawn as a 25×25 pixel square on the canvas.
Step 3: Define the App Class
class CreativeMazeApp:
Encapsulates all GUI components and logic into one class for clarity.
Step 4: Constructor __init__()
def __init__(self, root):
Initializes the interface:
Title, background, entry field for grid size.
Canvas to draw the maze.
Buttons to generate and solve.
self.grid = []
self.rows = self.cols = 20
Defaults maze to 20×20 if input is invalid.
Step 5: Generate Maze Function
def generate_maze(self):
Reads user input from entry box.
Initializes a grid filled with walls (
1
).Uses recursive DFS to carve paths (
0
) and generate the maze.
def dfs(r, c):
Recursive function that:
Marks cell as visited.
Shuffles directions (N, S, E, W).
Carves through walls between current and next cell.
Step 6: Draw the Maze
def draw_grid(self):
Iterates through grid and draws:
Walls as dark gray (
#2c3e50
)Paths as white
Each cell is drawn usingcanvas.create_rectangle()
.
Step 7: Solve the Maze
def solve_maze(self):
Implements Breadth-First Search (BFS) to find the shortest path.
Stores:
visited
: cells already checkedprev
: parent tracker to backtrace the path
queue = deque([(0, 0)])
Starts BFS from the top-left corner.
mark_visited(nr, nc, "#95a5a6")
Marks visited cells with light gray ovals to animate exploration.
while prev[r][c] is not None:
Backtracks from goal cell to the start, marking the final path in red.
Helper Function: mark_visited()
def mark_visited(r, c, color):
Draws a small filled oval inside the cell to show:
Path being explored (light gray)
Final path (red)
Launch the App
root = tk.Tk()
app = CreativeMazeApp(root)
root.mainloop()
Creates the main GUI window and starts the event loop.
Summary of Components:
Function | Role |
---|---|
generate_maze() | Uses DFS to generate a random maze |
draw_grid() | Draws grid on canvas based on 0 /1 values |
solve_maze() | Finds shortest path using BFS and animates |
mark_visited() | Visually shows exploration and solution path |
source code
import tkinter as tk
import random
from collections import deque
import time
CELL_SIZE = 25
class CreativeMazeApp:
def __init__(self, root):
self.root = root
self.root.title(" Creative Maze Generator & Solver")
self.root.configure(bg="#ecf0f1")
self.size_frame = tk.Frame(root, bg="#ecf0f1")
self.size_frame.pack(pady=5)
tk.Label(self.size_frame, text="Grid Size (e.g., 20):", bg="#ecf0f1", font=("Arial", 10)).pack(side="left")
self.grid_entry = tk.Entry(self.size_frame, width=5)
self.grid_entry.insert(0, "20")
self.grid_entry.pack(side="left", padx=5)
self.canvas = tk.Canvas(root, bg="white", width=500, height=500)
self.canvas.pack(pady=10)
self.button_frame = tk.Frame(root, bg="#ecf0f1")
self.button_frame.pack()
tk.Button(self.button_frame, text=" Generate Maze", command=self.generate_maze, bg="#27ae60", fg="white", font=("Arial", 10)).pack(side="left", padx=10)
tk.Button(self.button_frame, text=" Solve Maze", command=self.solve_maze, bg="#2980b9", fg="white", font=("Arial", 10)).pack(side="left", padx=10)
self.grid = []
self.rows = self.cols = 20
def generate_maze(self):
try:
size = int(self.grid_entry.get())
if size 40:
raise ValueError
self.rows = self.cols = size
except:
self.rows = self.cols = 20 # fallback
self.canvas.config(width=self.cols * CELL_SIZE, height=self.rows * CELL_SIZE)
self.grid = [[1 for _ in range(self.cols)] for _ in range(self.rows)]
visited = [[False for _ in range(self.cols)] for _ in range(self.rows)]
def dfs(r, c):
visited[r][c] = True
self.grid[r][c] = 0
dirs = [(0, 2), (0, -2), (2, 0), (-2, 0)]
random.shuffle(dirs)
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < self.rows and 0 <= nc < self.cols and not visited[nr][nc]:
self.grid[r + dr // 2][c + dc // 2] = 0
dfs(nr, nc)
dfs(0, 0)
self.draw_grid()
def draw_grid(self):
self.canvas.delete("all")
for r in range(self.rows):
for c in range(self.cols):
x1, y1 = c * CELL_SIZE, r * CELL_SIZE
x2, y2 = x1 + CELL_SIZE, y1 + CELL_SIZE
color = "#2c3e50" if self.grid[r][c] == 1 else "white"
self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="gray")
def solve_maze(self):
visited = [[False for _ in range(self.cols)] for _ in range(self.rows)]
prev = [[None for _ in range(self.cols)] for _ in range(self.rows)]
queue = deque([(0, 0)])
visited[0][0] = True
def mark_visited(r, c, color):
x1, y1 = c * CELL_SIZE + 6, r * CELL_SIZE + 6
x2, y2 = x1 + 12, y1 + 12
self.canvas.create_oval(x1, y1, x2, y2, fill=color, outline=color)
self.root.update()
time.sleep(0.01)
found = False
while queue:
r, c = queue.popleft()
if (r, c) == (self.rows - 1, self.cols - 1):
found = True
break
for dr, dc in [(0,1), (1,0), (0,-1), (-1,0)]:
nr, nc = r + dr, c + dc
if 0 <= nr < self.rows and 0 <= nc < self.cols and not visited[nr][nc] and self.grid[nr][nc] == 0:
queue.append((nr, nc))
visited[nr][nc] = True
prev[nr][nc] = (r, c)
mark_visited(nr, nc, "#95a5a6") # path visited color
if found:
# Backtrack and mark solution
r, c = self.rows - 1, self.cols - 1
while prev[r][c] is not None:
mark_visited(r, c, "#e74c3c") # final path color
r, c = prev[r][c]
else:
tk.messagebox.showinfo("No Path", "Maze has no solution!")
# Run in Jupyter
root = tk.Tk()
app = CreativeMazeApp(root)
root.mainloop()
output


