diff --git a/a_maze_ing.py b/a_maze_ing.py index d137ea5..5f3b7ff 100644 --- a/a_maze_ing.py +++ b/a_maze_ing.py @@ -1,3 +1,5 @@ +import os +import sys from typing import Any from numpy.typing import NDArray from AMazeIng import AMazeIng @@ -482,9 +484,10 @@ def main() -> None: """Run the maze application.""" mlx = None try: - mlx = MazeMLX(1600, 2000) + os.system("cls" if os.name == "nt" else "clear") config = Parsing.get_data_maze("config.txt") amazing = AMazeIng(**config) + mlx = MazeMLX(1600, 2000) mlx.start(amazing) amazing.export_maze() except Exception as err: diff --git a/config.txt b/config.txt index f0c23c7..9423f86 100644 --- a/config.txt +++ b/config.txt @@ -1,7 +1,7 @@ -WIDTH=4 -HEIGHT=4 +WIDTH=9 +HEIGHT=7 ENTRY=1,1 -EXIT=1,2 +EXIT=4,5 OUTPUT_FILE=con.txt PERFECT=False GENERATOR=Kruskal diff --git a/src/AMazeIng.py b/src/AMazeIng.py index 0be35ff..5d2aaa4 100644 --- a/src/AMazeIng.py +++ b/src/AMazeIng.py @@ -12,8 +12,8 @@ class AMazeIng(BaseModel): model_config = ConfigDict(arbitrary_types_allowed=True) - width: int = Field(ge=4, le=100) - height: int = Field(ge=4, le=100) + width: int = Field(ge=5, le=100) + height: int = Field(ge=5, le=100) entry: tuple[int, int] exit: tuple[int, int] output_file: str = Field(min_length=3) @@ -39,7 +39,11 @@ class AMazeIng(BaseModel): raise ValueError("Exit coordinates exceed the maze size") if self.entry == self.exit: raise ValueError("Entry and Exit coordinates cant be the same") - if self.width <= 10 or self.height <= 10: + if self.exit[0] < 1 or self.exit[1] < 1: + raise ValueError("Exit coordinates to low") + if self.entry[0] < 1 or self.entry[1] < 1: + raise ValueError("Entry coordinates to low") + if self.width < 9 or self.height < 7: print("Height or width to low for disply forty two logo") return self diff --git a/src/mazegen/MazeGenerator.py b/src/mazegen/MazeGenerator.py index b211e1f..dd8aa21 100644 --- a/src/mazegen/MazeGenerator.py +++ b/src/mazegen/MazeGenerator.py @@ -1,5 +1,6 @@ from abc import ABC, abstractmethod from typing import Generator, Any +from mazegen import Maze import numpy as np from numpy.typing import NDArray from mazegen.Cell import Cell @@ -105,10 +106,24 @@ class MazeGenerator(ABC): The modified maze. """ + def enough_wall(cell: Cell) -> bool: + nb_wall = 0 + if cell.get_est(): + nb_wall += 1 + if cell.get_north(): + nb_wall += 1 + if cell.get_west(): + nb_wall += 1 + if cell.get_south(): + nb_wall += 1 + if nb_wall == 3: + return True + return False + directions = {"N": (0, -1), "S": (0, 1), "W": (-1, 0), "E": (1, 0)} reverse = {"N": "S", "S": "N", "W": "E", "E": "W"} - min_break = 2 + min_break = 1 while True: count = 0 for y in range(height): @@ -125,7 +140,9 @@ class MazeGenerator(ABC): continue if direc in ["S", "E"]: continue - if np.random.random() < prob: + if not enough_wall(maze[y][x]): + continue + else: count += 1 cell = maze[y][x] cell_n = maze[ny][nx] @@ -136,8 +153,8 @@ class MazeGenerator(ABC): ) maze[y][x] = cell maze[ny][nx] = cell_n - yield maze - if count > min_break: + yield maze + if count >= min_break: break return maze @@ -292,7 +309,7 @@ class Kruskal(MazeGenerator): The final generated maze. """ cells_ft = None - if height > 10 and width > 10: + if height >= 7 and width >= 9: cells_ft = self.get_cell_ft(width, height) if cells_ft and (self.start in cells_ft or self.end in cells_ft): print( @@ -374,7 +391,7 @@ class DepthFirstSearch(MazeGenerator): if seed is not None: random.seed(seed) maze = self.init_maze(width, height) - if width > 10 and height > 10: + if width >= 9 and height >= 7: self.forty_two = self.get_cell_ft(width, height) visited: NDArray[np.object_] = np.zeros((height, width), dtype=bool) if ( diff --git a/src/parsing/Parsing.py b/src/parsing/Parsing.py index 15c1a21..503e2c3 100644 --- a/src/parsing/Parsing.py +++ b/src/parsing/Parsing.py @@ -6,6 +6,21 @@ from typing import Any class DataMaze: """Provide helper methods to load and validate maze configuration data.""" + @staticmethod + def test_output_file(name_file: str) -> None: + try: + with open(name_file, "r"): + while True: + res = input( + f"{name_file} already exist. Data will be erased. Continue ? (y/n)" + ) + if res == "y": + break + elif res == "n": + raise Exception("") + except FileNotFoundError: + return + @staticmethod def get_file_data(name_file: str) -> str: """Read and return the contents of a configuration file. @@ -38,7 +53,11 @@ class DataMaze: A dictionary mapping configuration keys to their string values. """ tmp = data.split("\n") - tmp2 = [value.split("=", 1) for value in tmp if "=" in value] + tmp2 = [ + value.split("=", 1) + for value in tmp + if not value.startswith("#") and "=" in value + ] data_t = {value[0]: value[1] for value in tmp2} return data_t @@ -64,6 +83,8 @@ class DataMaze: } i = 0 for key in data: + if key == "OUTPUT_FILE": + DataMaze.test_output_file(data[key]) if key in key_test: i += 1 if len(key_test) != i: @@ -187,6 +208,8 @@ class DataMaze: def test_file_format(file: str) -> None: with open(file) as data_str: for line in data_str: + if line.startswith("#"): + continue if len(line.split("=", 1)) != 2: raise Exception( "config file format not respected. excpected format : "