4 Commits

Author SHA1 Message Date
Maoake TERIIEROOITERAI 8eb46f601f fixing the DFS and modify the main 2026-03-24 20:47:13 +01:00
da7e 991cdead51 Merge branch 'main' of github.com:maoakeEnterprise/amazing 2026-03-24 16:12:19 +01:00
da7e 6730ebcdb5 It's aliiiive! 2026-03-24 16:10:57 +01:00
da7e a79d4e5c3b algorithm edited but nothing better 2026-03-24 15:33:50 +01:00
4 changed files with 78 additions and 79 deletions
+4 -2
View File
@@ -7,11 +7,13 @@ import src.amaz_lib as g
def main(maze_gen: MazeGenerator) -> None: def main(maze_gen: MazeGenerator) -> None:
# try: # try:
maze = Maze(maze=None) maze = Maze(maze=None)
gen = maze_gen.generator(100, 100) for alg in maze_gen.generator(30, 10):
for alg in gen:
maze.set_maze(alg) maze.set_maze(alg)
os.system("clear") os.system("clear")
maze.ascii_print() maze.ascii_print()
# solver = AStar((1, 1), (14, 18))
# print(solver.solve(maze))
# except Exception as err: # except Exception as err:
# print(err) # print(err)
+7 -8
View File
@@ -26,15 +26,14 @@ class Maze:
return res return res
def ascii_print(self) -> None: def ascii_print(self) -> None:
for cell in self.maze[0]:
print("_", end="")
if cell.get_north():
print("__", end="")
else:
print(" ", end="")
print("_")
for line in self.maze: for line in self.maze:
if line is self.maze[0]:
for cell in line:
print("_", end="")
if cell.get_north():
print("__", end="")
else:
print(" ", end="")
print()
for cell in line: for cell in line:
if cell is line[0] and cell.get_west(): if cell is line[0] and cell.get_west():
print("|", end="") print("|", end="")
+53 -42
View File
@@ -1,5 +1,5 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Generator from typing import Generator, Set
import numpy as np import numpy as np
from .Cell import Cell from .Cell import Cell
import math import math
@@ -13,9 +13,17 @@ class MazeGenerator(ABC):
class Kruskal(MazeGenerator): class Kruskal(MazeGenerator):
class Set:
def __init__(self, cells: list[int]) -> None:
self.cells: list[int] = cells
class Sets:
def __init__(self, sets: list[Set]) -> None:
self.sets = sets
@staticmethod @staticmethod
def walls_to_maze( def walls_to_maze(
walls: list[tuple[int, int]], height: int, width: int walls: np.ndarray, height: int, width: int
) -> np.ndarray: ) -> np.ndarray:
maze: np.ndarray = np.array( maze: np.ndarray = np.array(
[[Cell(value=0) for _ in range(width)] for _ in range(height)] [[Cell(value=0) for _ in range(width)] for _ in range(height)]
@@ -36,58 +44,70 @@ class Kruskal(MazeGenerator):
if x == height - 1: if x == height - 1:
maze[x][y].set_south(True) maze[x][y].set_south(True)
if y == 0: if y == 0:
maze[x][y].set_est(True)
if y == width - 1:
maze[x][y].set_west(True) maze[x][y].set_west(True)
if y == width - 1:
maze[x][y].set_est(True)
return maze return maze
@staticmethod @staticmethod
def is_in_same_set(sets: list[list[int]], wall: tuple[int, int]) -> bool: def is_in_same_set(sets: Sets, wall: tuple[int, int]) -> bool:
a, b = wall a, b = wall
for set in sets: for set in sets.sets:
if a in set and b in set: if a in set.cells and b in set.cells:
return True return True
if a in set or b in set: elif a in set.cells or b in set.cells:
return False return False
return False return False
@staticmethod @staticmethod
def merge_sets(sets: list[list[int]], wall: tuple[int, int]) -> None: def merge_sets(sets: Sets, wall: tuple[int, int]) -> None:
a, b = wall a, b = wall
base_set = None base_set = None
for set in sets: for i in range(len(sets.sets)):
if base_set is None and (a in set or b in set): if base_set is None and (
base_set = set a in sets.sets[i].cells or b in sets.sets[i].cells
elif base_set and (a in set or b in set): ):
base_set += set base_set = sets.sets[i]
sets.remove(set) elif base_set and (
a in sets.sets[i].cells or b in sets.sets[i].cells
):
base_set.cells += sets.sets[i].cells
sets.sets.pop(i)
return
raise Exception("two sets not found")
def generator( def generator(
self, height: int, width: int self, height: int, width: int
) -> Generator[np.ndarray, None, np.ndarray]: ) -> Generator[np.ndarray, None, np.ndarray]:
sets = [[i] for i in range(height * width)] sets = self.Sets([self.Set([i]) for i in range(height * width)])
walls = [] walls = []
for h in range(height): for h in range(height):
for w in range(width - 1): for w in range(width - 1):
walls += [(w + (width * h), w + (width * h) + 1)] walls += [(w + (width * h), w + (width * h) + 1)]
for w in range(width): for h in range(height - 1):
for h in range(height - 1): for w in range(width):
walls += [(w + (width * h), w + (width * h) + width)] walls += [(w + (width * h), w + (width * (h + 1)))]
print(walls)
np.random.shuffle(walls) np.random.shuffle(walls)
yield self.walls_to_maze(walls, height, width) yield self.walls_to_maze(walls, height, width)
for wall in walls: while len(sets.sets) > 1:
if not self.is_in_same_set(sets, wall): for wall in walls:
self.merge_sets(sets, wall) if not self.is_in_same_set(sets, wall):
walls.remove(wall) self.merge_sets(sets, wall)
yield self.walls_to_maze(walls, height, width) walls.remove(wall)
yield self.walls_to_maze(walls, height, width)
if len(sets.sets) == 1:
break
print(f"nb sets: {len(sets.sets)}")
return self.walls_to_maze(walls, height, width) return self.walls_to_maze(walls, height, width)
class DepthFirstSearch(MazeGenerator): class DepthFirstSearch(MazeGenerator):
def generator(self, width: int, height: int def generator(
) -> Generator[np.ndarray, None, np.ndarray]: self, height: int, width: int
) -> Generator[np.ndarray, None, np.ndarray]:
maze = DepthFirstSearch.init_maze(width, height) maze = DepthFirstSearch.init_maze(width, height)
visited = np.zeros((height, width), dtype=bool) visited = np.zeros((height, width), dtype=bool)
path = list() path = list()
@@ -122,8 +142,9 @@ class DepthFirstSearch(MazeGenerator):
@staticmethod @staticmethod
def init_maze(width: int, height: int) -> np.ndarray: def init_maze(width: int, height: int) -> np.ndarray:
maze = np.array([[Cell(value=15) for _ in range(width)] maze = np.array(
for _ in range(height)]) [[Cell(value=15) for _ in range(width)] for _ in range(height)]
)
return maze return maze
@staticmethod @staticmethod
@@ -168,34 +189,24 @@ class DepthFirstSearch(MazeGenerator):
@staticmethod @staticmethod
def next_cell(x: int, y: int, next: str) -> tuple: def next_cell(x: int, y: int, next: str) -> tuple:
next_step = { next_step = {"N": (0, -1), "S": (0, 1), "W": (-1, 0), "E": (1, 0)}
"N": (0, -1),
"S": (0, 1),
"W": (-1, 0),
"E": (1, 0)
}
add_x, add_y = next_step[next] add_x, add_y = next_step[next]
return (x + add_x, y + add_y) return (x + add_x, y + add_y)
@staticmethod @staticmethod
def reverse_path(next: str) -> str: def reverse_path(next: str) -> str:
reverse = { reverse = {"N": "S", "S": "N", "W": "E", "E": "W"}
"N": "S",
"S": "N",
"W": "E",
"E": "W"
}
return reverse[next] return reverse[next]
@staticmethod @staticmethod
def back_on_step(path: list, w_h: tuple, visited: np.array) -> list: def back_on_step(path: list, w_h: tuple, visited: np.array) -> list:
last = path[-1] last = path[-1]
r_cells = DepthFirstSearch.random_cells(visited, last, w_h) r_cells = DepthFirstSearch.random_cells(visited, last, w_h)
while len(path) > 0: while len(path) > 0:
path.pop() path.pop()
if path: if path:
last = path[-1] last = path[-1]
r_cells = DepthFirstSearch.random_cells(visited, last, w_h) r_cells = DepthFirstSearch.random_cells(visited, last, w_h)
if r_cells: if r_cells:
break break
return path return path
+14 -27
View File
@@ -53,25 +53,25 @@ class AStar(MazeSolver):
print(actual) print(actual)
path = { path = {
"N": ( "N": (
self.f((actual[0], actual[1] - 1)) self.f((actual[1] - 1, actual[0]))
if not maze[actual[0]][actual[1]].get_north() and actual[1] > 0 if not maze[actual[1]][actual[0]].get_north() and actual[0] > 0
else None else None
), ),
"E": ( "E": (
self.f((actual[0] + 1, actual[1])) self.f((actual[1], actual[0] + 1))
if not maze[actual[0]][actual[1]].get_est() if not maze[actual[1]][actual[0]].get_est()
and actual[0] < len(maze) - 1 and actual[1] < len(maze) - 1
else None else None
), ),
"S": ( "S": (
self.f((actual[0], actual[1] + 1)) self.f((actual[1] + 1, actual[0]))
if not maze[actual[0]][actual[1]].get_south() if not maze[actual[1]][actual[0]].get_south()
and actual[1] < len(maze[0]) - 1 and actual[0] < len(maze) - 1
else None else None
), ),
"W": ( "W": (
self.f((actual[0] - 1, actual[1])) self.f((actual[1], actual[0] - 1))
if not maze[actual[0]][actual[1]].get_west() and actual[0] > 0 if not maze[actual[1]][actual[0]].get_west() and actual[1] > 0
else None else None
), ),
} }
@@ -107,23 +107,10 @@ class AStar(MazeSolver):
case _: case _:
return actual return actual
def get_path( def get_path(self, maze: np.ndarray) -> str | None:
self, actual: tuple[int, int], maze: np.ndarray, pre: str | None actual = self.start
) -> str | None: path = ""
if actual == self.end:
return ""
paths = self.best_path(maze, actual)
for path in paths:
if paths[path] is None:
continue
if path != pre:
temp = self.get_path(
self.get_next_pos(path, actual),
maze,
self.get_opposit(path),
)
if not temp is None:
return path + temp
return None return None
def solve(self, maze: Maze) -> str: def solve(self, maze: Maze) -> str: