Some fix:

- entry/exit negatif
- checker if output file already exist
- config.txt commentary
- maze min size for ft logo generation
- unperfect maze compliance
This commit is contained in:
2026-04-04 21:18:42 +02:00
parent 21e9aba95f
commit e137389216
5 changed files with 61 additions and 14 deletions
+4 -1
View File
@@ -1,3 +1,5 @@
import os
import sys
from typing import Any from typing import Any
from numpy.typing import NDArray from numpy.typing import NDArray
from AMazeIng import AMazeIng from AMazeIng import AMazeIng
@@ -482,9 +484,10 @@ def main() -> None:
"""Run the maze application.""" """Run the maze application."""
mlx = None mlx = None
try: try:
mlx = MazeMLX(1600, 2000) os.system("cls" if os.name == "nt" else "clear")
config = Parsing.get_data_maze("config.txt") config = Parsing.get_data_maze("config.txt")
amazing = AMazeIng(**config) amazing = AMazeIng(**config)
mlx = MazeMLX(1600, 2000)
mlx.start(amazing) mlx.start(amazing)
amazing.export_maze() amazing.export_maze()
except Exception as err: except Exception as err:
+3 -3
View File
@@ -1,7 +1,7 @@
WIDTH=4 WIDTH=9
HEIGHT=4 HEIGHT=7
ENTRY=1,1 ENTRY=1,1
EXIT=1,2 EXIT=4,5
OUTPUT_FILE=con.txt OUTPUT_FILE=con.txt
PERFECT=False PERFECT=False
GENERATOR=Kruskal GENERATOR=Kruskal
+7 -3
View File
@@ -12,8 +12,8 @@ class AMazeIng(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True) model_config = ConfigDict(arbitrary_types_allowed=True)
width: int = Field(ge=4, le=100) width: int = Field(ge=5, le=100)
height: int = Field(ge=4, le=100) height: int = Field(ge=5, le=100)
entry: tuple[int, int] entry: tuple[int, int]
exit: tuple[int, int] exit: tuple[int, int]
output_file: str = Field(min_length=3) output_file: str = Field(min_length=3)
@@ -39,7 +39,11 @@ class AMazeIng(BaseModel):
raise ValueError("Exit coordinates exceed the maze size") raise ValueError("Exit coordinates exceed the maze size")
if self.entry == self.exit: if self.entry == self.exit:
raise ValueError("Entry and Exit coordinates cant be the same") 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") print("Height or width to low for disply forty two logo")
return self return self
+23 -6
View File
@@ -1,5 +1,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Generator, Any from typing import Generator, Any
from mazegen import Maze
import numpy as np import numpy as np
from numpy.typing import NDArray from numpy.typing import NDArray
from mazegen.Cell import Cell from mazegen.Cell import Cell
@@ -105,10 +106,24 @@ class MazeGenerator(ABC):
The modified maze. 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)} directions = {"N": (0, -1), "S": (0, 1), "W": (-1, 0), "E": (1, 0)}
reverse = {"N": "S", "S": "N", "W": "E", "E": "W"} reverse = {"N": "S", "S": "N", "W": "E", "E": "W"}
min_break = 2 min_break = 1
while True: while True:
count = 0 count = 0
for y in range(height): for y in range(height):
@@ -125,7 +140,9 @@ class MazeGenerator(ABC):
continue continue
if direc in ["S", "E"]: if direc in ["S", "E"]:
continue continue
if np.random.random() < prob: if not enough_wall(maze[y][x]):
continue
else:
count += 1 count += 1
cell = maze[y][x] cell = maze[y][x]
cell_n = maze[ny][nx] cell_n = maze[ny][nx]
@@ -136,8 +153,8 @@ class MazeGenerator(ABC):
) )
maze[y][x] = cell maze[y][x] = cell
maze[ny][nx] = cell_n maze[ny][nx] = cell_n
yield maze yield maze
if count > min_break: if count >= min_break:
break break
return maze return maze
@@ -292,7 +309,7 @@ class Kruskal(MazeGenerator):
The final generated maze. The final generated maze.
""" """
cells_ft = None cells_ft = None
if height > 10 and width > 10: if height >= 7 and width >= 9:
cells_ft = self.get_cell_ft(width, height) cells_ft = self.get_cell_ft(width, height)
if cells_ft and (self.start in cells_ft or self.end in cells_ft): if cells_ft and (self.start in cells_ft or self.end in cells_ft):
print( print(
@@ -374,7 +391,7 @@ class DepthFirstSearch(MazeGenerator):
if seed is not None: if seed is not None:
random.seed(seed) random.seed(seed)
maze = self.init_maze(width, height) 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) self.forty_two = self.get_cell_ft(width, height)
visited: NDArray[np.object_] = np.zeros((height, width), dtype=bool) visited: NDArray[np.object_] = np.zeros((height, width), dtype=bool)
if ( if (
+24 -1
View File
@@ -6,6 +6,21 @@ from typing import Any
class DataMaze: class DataMaze:
"""Provide helper methods to load and validate maze configuration data.""" """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 @staticmethod
def get_file_data(name_file: str) -> str: def get_file_data(name_file: str) -> str:
"""Read and return the contents of a configuration file. """Read and return the contents of a configuration file.
@@ -38,7 +53,11 @@ class DataMaze:
A dictionary mapping configuration keys to their string values. A dictionary mapping configuration keys to their string values.
""" """
tmp = data.split("\n") 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} data_t = {value[0]: value[1] for value in tmp2}
return data_t return data_t
@@ -64,6 +83,8 @@ class DataMaze:
} }
i = 0 i = 0
for key in data: for key in data:
if key == "OUTPUT_FILE":
DataMaze.test_output_file(data[key])
if key in key_test: if key in key_test:
i += 1 i += 1
if len(key_test) != i: if len(key_test) != i:
@@ -187,6 +208,8 @@ class DataMaze:
def test_file_format(file: str) -> None: def test_file_format(file: str) -> None:
with open(file) as data_str: with open(file) as data_str:
for line in data_str: for line in data_str:
if line.startswith("#"):
continue
if len(line.split("=", 1)) != 2: if len(line.split("=", 1)) != 2:
raise Exception( raise Exception(
"config file format not respected. excpected format : " "config file format not respected. excpected format : "