Files
python-maze/src/generators/kruskal.py
2025-11-20 22:58:11 -05:00

90 lines
2.6 KiB
Python

"""Kruskal's Algorithm for maze generation."""
import random
from typing import Dict, List, Tuple
from ..core.cell import Cell
from ..core.maze import Maze
from .base import BaseGenerator
class KruskalGenerator(BaseGenerator):
"""Generates mazes using Kruskal's Algorithm.
This algorithm treats the maze as a graph and uses a union-find structure
to create a minimum spanning tree. Creates mazes with many short paths.
Time Complexity: O(E log E) where E is number of edges
Space Complexity: O(V) where V is number of vertices
"""
def __init__(self):
"""Initialize the Kruskal generator."""
super().__init__("Kruskal's Algorithm")
def _generate_maze(self, maze: Maze) -> None:
"""Generate maze using Kruskal's algorithm.
Args:
maze: Maze instance to generate
"""
# Initialize union-find structure
parent: Dict[Cell, Cell] = {}
for row in maze.grid:
for cell in row:
parent[cell] = cell
# Create list of all possible walls (edges)
walls = self._get_all_walls(maze)
random.shuffle(walls)
# Process each wall
for cell1, cell2 in walls:
# Find roots of both cells
root1 = self._find(parent, cell1)
root2 = self._find(parent, cell2)
# If cells are in different sets, remove wall and union
if root1 != root2:
maze.remove_wall_between(cell1, cell2)
parent[root2] = root1
def _get_all_walls(self, maze: Maze) -> List[Tuple[Cell, Cell]]:
"""Get all possible walls between cells.
Args:
maze: The maze
Returns:
List of (cell1, cell2) tuples representing walls
"""
walls = []
for row in maze.grid:
for cell in row:
# Add wall to the south
south_cell = maze.get_cell(cell.row + 1, cell.col)
if south_cell:
walls.append((cell, south_cell))
# Add wall to the east
east_cell = maze.get_cell(cell.row, cell.col + 1)
if east_cell:
walls.append((cell, east_cell))
return walls
def _find(self, parent: Dict[Cell, Cell], cell: Cell) -> Cell:
"""Find the root of a cell's set with path compression.
Args:
parent: Union-find parent dictionary
cell: Cell to find root for
Returns:
Root cell of the set
"""
if parent[cell] != cell:
parent[cell] = self._find(parent, parent[cell])
return parent[cell]