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 color

  • After 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 cell

  • Adds 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

FunctionPurpose
__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 using canvas.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 checked

    • prev: 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:

FunctionRole
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

More java Pojects
Get Huge Discounts