Generator class rework

This commit is contained in:
2026-03-19 14:59:18 +01:00
parent 84c4b63a6c
commit c6c7e6e47e
2 changed files with 77 additions and 74 deletions
+76 -74
View File
@@ -1,87 +1,89 @@
from abc import ABC, abstractmethod
from typing import Generator from typing import Generator
import numpy as np import numpy as np
from .classes.Cell import Cell from .classes.Cell import Cell
import math import math
class MazeGenerator: class MazeGenerator(ABC):
class Kruskal: @abstractmethod
@staticmethod @classmethod
def walls_to_maze( def generator(
walls: list[tuple[int, int]], height: int, width: int cls, height: int, width: int
) -> np.ndarray: ) -> Generator[np.ndarray, None, np.ndarray]: ...
maze: np.ndarray = np.array(
[[Cell(value=0) for _ in range(width)] for _ in range(height)]
)
for wall in walls:
x, y = wall
match y - x:
case 1:
maze[math.trunc((x / width))][x % width].set_est(True)
maze[math.trunc((y / width))][y % width].set_west(True)
case width:
maze[math.trunc((x / width))][x % width].set_south(
True
)
maze[math.trunc((y / width))][y % width].set_north(
True
)
for x in range(height):
for y in range(width):
if x == 0:
maze[x][y].set_north(True)
if x == height - 1:
maze[x][y].set_south(True)
if y == 0:
maze[x][y].set_est(True)
if y == width - 1:
maze[x][y].set_west(True)
return maze
@staticmethod
def is_in_same_set(
sets: list[list[int]], wall: tuple[int, int]
) -> bool:
a, b = wall
for set in sets:
if a in set and b in set:
return True
if a in set or b in set:
return False
return False
@staticmethod class Kruskal(MazeGenerator):
def merge_sets(sets: list[list[int]], wall: tuple[int, int]) -> None: @staticmethod
a, b = wall def walls_to_maze(
base_set = None walls: list[tuple[int, int]], height: int, width: int
for set in sets: ) -> np.ndarray:
if base_set is None and (a in set or b in set): maze: np.ndarray = np.array(
base_set = set [[Cell(value=0) for _ in range(width)] for _ in range(height)]
elif base_set and (a in set or b in set): )
base_set += set for wall in walls:
sets.remove(set) x, y = wall
match y - x:
case 1:
maze[math.trunc((x / width))][x % width].set_est(True)
maze[math.trunc((y / width))][y % width].set_west(True)
case width:
maze[math.trunc((x / width))][x % width].set_south(True)
maze[math.trunc((y / width))][y % width].set_north(True)
for x in range(height):
for y in range(width):
if x == 0:
maze[x][y].set_north(True)
if x == height - 1:
maze[x][y].set_south(True)
if y == 0:
maze[x][y].set_est(True)
if y == width - 1:
maze[x][y].set_west(True)
return maze
@classmethod @staticmethod
def kruskal( def is_in_same_set(sets: list[list[int]], wall: tuple[int, int]) -> bool:
cls, height: int, width: int a, b = wall
) -> Generator[np.ndarray, None, np.ndarray]: for set in sets:
sets = [[i] for i in range(height * width)] if a in set and b in set:
walls = [] return True
for h in range(height): if a in set or b in set:
for w in range(width - 1): return False
walls += [(w + (width * h), w + (width * h) + 1)] return False
for w in range(width):
for h in range(height - 1):
walls += [(w + (width * h), w + (width * h) + width)]
np.random.shuffle(walls)
yield cls.walls_to_maze(walls, height, width) @staticmethod
for wall in walls: def merge_sets(sets: list[list[int]], wall: tuple[int, int]) -> None:
if not cls.is_in_same_set(sets, wall): a, b = wall
cls.merge_sets(sets, wall) base_set = None
walls.remove(wall) for set in sets:
yield cls.walls_to_maze(walls, height, width) if base_set is None and (a in set or b in set):
return cls.walls_to_maze(walls, height, width) base_set = set
elif base_set and (a in set or b in set):
base_set += set
sets.remove(set)
@classmethod
def generator(
cls, height: int, width: int
) -> Generator[np.ndarray, None, np.ndarray]:
sets = [[i] for i in range(height * width)]
walls = []
for h in range(height):
for w in range(width - 1):
walls += [(w + (width * h), w + (width * h) + 1)]
for w in range(width):
for h in range(height - 1):
walls += [(w + (width * h), w + (width * h) + width)]
np.random.shuffle(walls)
yield cls.walls_to_maze(walls, height, width)
for wall in walls:
if not cls.is_in_same_set(sets, wall):
cls.merge_sets(sets, wall)
walls.remove(wall)
yield cls.walls_to_maze(walls, height, width)
return cls.walls_to_maze(walls, height, width)
def main(): def main():
+1
View File
@@ -2,6 +2,7 @@ from dataclasses import dataclass
import numpy import numpy
from .Cell import Cell from .Cell import Cell
from ..MazeGenerator import MazeGenerator
@dataclass @dataclass