diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/amaz-lib/generators/kruskal.py b/src/amaz-lib/generators/kruskal.py deleted file mode 100644 index e1737e7..0000000 --- a/src/amaz-lib/generators/kruskal.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Generator -import numpy as np -from .. import Cell - - -def kraskal( - height: int, width: int -) -> Generator[np.ndarray, None, np.ndarray]: - maze = np.array([[Cell(value=15) for _ in range(height)] * width]) - cells_checked = np.array([[False for _ in range(height)] * width]) - excepted_end = np.array([[True for _ in range(height)] * width]) - - while cells_checked != excepted_end: - yield maze - return maze diff --git a/src/amaz-lib/__init__.py b/src/amaz_lib/__init__.py similarity index 100% rename from src/amaz-lib/__init__.py rename to src/amaz_lib/__init__.py diff --git a/src/amaz-lib/classes/Cell.py b/src/amaz_lib/classes/Cell.py similarity index 75% rename from src/amaz-lib/classes/Cell.py rename to src/amaz_lib/classes/Cell.py index d62639b..83a6483 100644 --- a/src/amaz-lib/classes/Cell.py +++ b/src/amaz_lib/classes/Cell.py @@ -14,8 +14,8 @@ class Cell(BaseModel): return self.value def set_north(self, is_wall: bool) -> None: - if (is_wall and self.value | 14 == 15) or ( - not is_wall and self.value | 14 != 15 + if (not is_wall and self.value | 14 == 15) or ( + is_wall and self.value | 14 != 15 ): self.value = self.value ^ (1) @@ -23,8 +23,8 @@ class Cell(BaseModel): return self.value & 1 == 1 def set_est(self, is_wall: bool) -> None: - if (is_wall and self.value | 13 == 15) or ( - not is_wall and self.value | 13 != 15 + if (not is_wall and self.value | 13 == 15) or ( + is_wall and self.value | 13 != 15 ): self.value = self.value ^ (2) @@ -32,8 +32,8 @@ class Cell(BaseModel): return self.value & 2 == 2 def set_south(self, is_wall: bool) -> None: - if (is_wall and self.value | 11 == 15) or ( - not is_wall and self.value | 11 != 15 + if (not is_wall and self.value | 11 == 15) or ( + is_wall and self.value | 11 != 15 ): self.value = self.value ^ (4) @@ -41,8 +41,8 @@ class Cell(BaseModel): return self.value & 4 == 4 def set_west(self, is_wall: bool) -> None: - if (is_wall and self.value | 8 == 15) or ( - not is_wall and self.value | 8 != 15 + if (not is_wall and self.value | 8 == 15) or ( + is_wall and self.value | 8 != 15 ): self.value = self.value ^ (8) diff --git a/src/amaz-lib/classes/Maze.py b/src/amaz_lib/classes/Maze.py similarity index 100% rename from src/amaz-lib/classes/Maze.py rename to src/amaz_lib/classes/Maze.py diff --git a/src/amaz_lib/generators/kruskal.py b/src/amaz_lib/generators/kruskal.py new file mode 100644 index 0000000..2a62752 --- /dev/null +++ b/src/amaz_lib/generators/kruskal.py @@ -0,0 +1,83 @@ +from typing import Generator +import numpy as np +from ..classes.Cell import Cell +import math + + +def walls_to_maze( + walls: list[tuple[int, int]], + height: int, + width: int, +) -> 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 5: + maze[math.trunc((x / width))][x % width].set_south(True) + maze[math.trunc((y / width))][y % width].set_north(True) + return maze + + +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 + + +def merge_sets(sets: list[list[int]], wall: tuple[int, int]) -> None: + a, b = wall + base_set = None + for set in sets: + if base_set is None and (a in set or b in set): + base_set = set + elif base_set and (a in set or b in set): + base_set += set + sets.remove(set) + + +def kraskal( + 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 walls_to_maze(walls, height, width) + for wall in walls: + if not is_in_same_set(sets, wall): + merge_sets(sets, wall) + walls.remove(wall) + yield walls_to_maze(walls, height, width) + return walls_to_maze(walls, height, width) + + +def main(): + try: + for alg in kraskal(10, 10): + maze = alg + # print(maze) + # print() + print(maze) + + except GeneratorExit as maze: + print(maze) + + +if __name__ == "__main__": + main()