From 03b5f9e6fde3b0f0f50ebd603d673fac390203d7 Mon Sep 17 00:00:00 2001 From: Maoake Teriierooiterai Date: Wed, 1 Apr 2026 14:12:39 +0200 Subject: [PATCH] fix mypy strict on MazeSolver and Maze Generator --- Makefile | 2 +- a_maze_ing.py | 2 +- config.txt | 4 +-- src/amaz_lib/MazeGenerator.py | 66 ++++++++++++++++++++--------------- src/amaz_lib/MazeSolver.py | 56 ++++++++++++++++------------- 5 files changed, 73 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 258d000..1e67f70 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ lint: uv run mypy . --warn-return-any --warn-unused-ignores --ignore-missing-imports --disallow-untyped-defs --check-untyped-defs lint-strict: - uv run flake8 . + uv run flake8 . --exclude=.venv uv run mypy . --strict run_test_parsing: diff --git a/a_maze_ing.py b/a_maze_ing.py index 99c2178..8edccee 100644 --- a/a_maze_ing.py +++ b/a_maze_ing.py @@ -330,7 +330,7 @@ class MazeMLX: self.mlx.mlx_loop_hook(self.mlx_ptr, self.draw_image, amazing) self.mlx.mlx_hook(self.win_ptr, 33, 0, self.close_loop, None) self.mlx.mlx_hook( - self.win_ptr, 2, 1 << 0, self.handle_key_press_mteriier, amazing + self.win_ptr, 2, 1 << 0, self.handle_key_press, amazing ) self.mlx.mlx_loop(self.mlx_ptr) diff --git a/config.txt b/config.txt index d3cd73e..eeb9713 100644 --- a/config.txt +++ b/config.txt @@ -1,5 +1,5 @@ -WIDTH=13 -HEIGHT=13 +WIDTH=15 +HEIGHT=15 ENTRY=1,1 EXIT=5,5 OUTPUT_FILE=maze.txt diff --git a/src/amaz_lib/MazeGenerator.py b/src/amaz_lib/MazeGenerator.py index 66a29ea..f10c192 100644 --- a/src/amaz_lib/MazeGenerator.py +++ b/src/amaz_lib/MazeGenerator.py @@ -1,12 +1,15 @@ from abc import ABC, abstractmethod -from typing import Generator, Set +from typing import Generator, Any import numpy as np +from numpy.typing import NDArray from .Cell import Cell import math +import random class MazeGenerator(ABC): - def __init__(self, start: tuple, end: tuple, perfect: bool) -> None: + def __init__(self, start: tuple[int, int], end: tuple[int, int], + perfect: bool) -> None: self.start = (start[0] - 1, start[1] - 1) self.end = (end[0] - 1, end[1] - 1) self.perfect = perfect @@ -14,10 +17,10 @@ class MazeGenerator(ABC): @abstractmethod def generator( self, height: int, width: int, seed: int | None = None - ) -> Generator[np.ndarray, None, np.ndarray]: ... + ) -> Generator[NDArray[Any], None, NDArray[Any]]: ... @staticmethod - def get_cell_ft(width: int, height: int) -> set: + def get_cell_ft(width: int, height: int) -> set[tuple[int, int]]: forty_two = set() y, x = (int(height / 2), int(width / 2)) forty_two.add((y, x - 1)) @@ -42,9 +45,10 @@ class MazeGenerator(ABC): @staticmethod def unperfect_maze(width: int, height: int, - maze: np.ndarray, forty_two: set | None, + maze: NDArray[Any], + forty_two: set[tuple[int, int]] | None, prob: float = 0.1 - ) -> Generator[np.ndarray, None, np.ndarray]: + ) -> Generator[NDArray[Any], None, NDArray[Any]]: directions = { "N": (0, -1), "S": (0, 1), @@ -94,19 +98,19 @@ class MazeGenerator(ABC): class Kruskal(MazeGenerator): - class Set: + class KruskalSet: def __init__(self, cells: list[int]) -> None: self.cells: list[int] = cells class Sets: - def __init__(self, sets: list[Set]) -> None: + def __init__(self, sets: list['Kruskal.KruskalSet']) -> None: self.sets = sets @staticmethod def walls_to_maze( - walls: np.ndarray, height: int, width: int - ) -> np.ndarray: - maze: np.ndarray = np.array( + walls: list[tuple[int, int]], height: int, width: int + ) -> NDArray[Any]: + maze: NDArray[Any] = np.array( [[Cell(value=0) for _ in range(width)] for _ in range(height)] ) for wall in walls: @@ -171,7 +175,7 @@ class Kruskal(MazeGenerator): def generator( self, height: int, width: int, seed: int | None = None - ) -> Generator[np.ndarray, None, np.ndarray]: + ) -> Generator[NDArray[Any], None, NDArray[Any]]: cells_ft = None if height > 10 and width > 10: cells_ft = self.get_cell_ft(width, height) @@ -180,7 +184,7 @@ class Kruskal(MazeGenerator): if seed is not None: np.random.seed(seed) - sets = self.Sets([self.Set([i]) for i in range(height * width)]) + sets = self.Sets([self.KruskalSet([i]) for i in range(height * width)]) walls = [] for h in range(height): for w in range(width - 1): @@ -217,28 +221,29 @@ class Kruskal(MazeGenerator): class DepthFirstSearch(MazeGenerator): - def __init__(self, start: bool, end: bool, perfect: bool) -> None: + def __init__(self, start: tuple[int, int], end: tuple[int, int], + perfect: bool) -> None: self.start = (start[0] - 1, start[1] - 1) self.end = (end[0] - 1, end[1] - 1) self.perfect = perfect - self.forty_two: set | None = None + self.forty_two: set[tuple[int, int]] | None = None def generator( - self, height: int, width: int, seed: int = None - ) -> Generator[np.ndarray, None, np.ndarray]: + self, height: int, width: int, seed: int | None = None + ) -> Generator[NDArray[Any], None, NDArray[Any]]: if seed is not None: np.random.seed(seed) maze = self.init_maze(width, height) if width > 9 and height > 9: self.forty_two = self.get_cell_ft(width, height) - visited = np.zeros((height, width), dtype=bool) + visited: NDArray[np.object_] = np.zeros((height, width), dtype=bool) if ( self.forty_two and self.start not in self.forty_two and self.end not in self.forty_two ): visited = self.lock_cell_ft(visited, self.forty_two) - path = list() + path: list[tuple[int, int]] = list() w_h = (width, height) coord = (0, 0) x, y = coord @@ -277,20 +282,22 @@ class DepthFirstSearch(MazeGenerator): return maze @staticmethod - def init_maze(width: int, height: int) -> np.ndarray: + def init_maze(width: int, height: int) -> NDArray[Any]: maze = np.array( [[Cell(value=15) for _ in range(width)] for _ in range(height)] ) return maze @staticmethod - def add_cell_visited(coord: tuple, path: set) -> list: + def add_cell_visited(coord: tuple[int, int], path: list[tuple[int, int]] + ) -> list[tuple[int, int]]: path.append(coord) return path @staticmethod - def random_cells(visited: np.array, coord: tuple, w_h: tuple) -> list: - rand_cell = [] + def random_cells(visited: NDArray[Any], coord: tuple[int, int], + w_h: tuple[int, int]) -> list[str]: + rand_cell: list[str] = [] x, y = coord width, height = w_h @@ -308,8 +315,8 @@ class DepthFirstSearch(MazeGenerator): return rand_cell @staticmethod - def next_step(rand_cell: list) -> str: - return np.random.choice(rand_cell) + def next_step(rand_cell: list[str]) -> str: + return random.choice(rand_cell) @staticmethod def broken_wall(cell: Cell, wall: str) -> Cell: @@ -324,7 +331,7 @@ class DepthFirstSearch(MazeGenerator): return cell @staticmethod - def next_cell(x: int, y: int, next: str) -> tuple: + def next_cell(x: int, y: int, next: str) -> tuple[int, int]: next_step = {"N": (0, -1), "S": (0, 1), "W": (-1, 0), "E": (1, 0)} add_x, add_y = next_step[next] return (x + add_x, y + add_y) @@ -334,7 +341,8 @@ class DepthFirstSearch(MazeGenerator): return {"N": "S", "S": "N", "W": "E", "E": "W"}[direction] @staticmethod - def back_on_step(path: list, w_h: tuple, visited: np.ndarray) -> list: + def back_on_step(path: list[tuple[int, int]], w_h: tuple[int, int], + visited: NDArray[Any]) -> list[tuple[int, int]]: while path: last = path[-1] if DepthFirstSearch.random_cells(visited, last, w_h): @@ -344,8 +352,8 @@ class DepthFirstSearch(MazeGenerator): @staticmethod def lock_cell_ft( - visited: np.ndarray, forty_two: set[tuple[int]] - ) -> np.ndarray: + visited: NDArray[Any], forty_two: set[tuple[int, int]] + ) -> NDArray[Any]: tab = [cell for cell in forty_two] for cell in tab: visited[cell] = True diff --git a/src/amaz_lib/MazeSolver.py b/src/amaz_lib/MazeSolver.py index c77bffb..01ba2d2 100644 --- a/src/amaz_lib/MazeSolver.py +++ b/src/amaz_lib/MazeSolver.py @@ -2,6 +2,8 @@ from abc import ABC, abstractmethod from .Maze import Maze from typing import Any import numpy as np +from numpy.typing import NDArray +import random class MazeSolver(ABC): @@ -36,7 +38,6 @@ class AStar(MazeSolver): def __init__(self, start: tuple[int, int], end: tuple[int, int]) -> None: super().__init__(start, end) - self.path = [] def h(self, n: tuple[int, int]) -> int: return ( @@ -48,9 +49,9 @@ class AStar(MazeSolver): def get_paths( self, - maze: np.ndarray, + maze: NDArray[Any], actual: tuple[int, int], - close: list, + close: list['Node'], ) -> list[tuple[int, int]]: path = [ ( @@ -88,7 +89,7 @@ class AStar(MazeSolver): ] return [p for p in path if p is not None] - def get_path(self, maze: np.ndarray) -> list: + def get_path(self, maze: NDArray[Any]) -> list['Node']: open: list[AStar.Node] = [] close: list[AStar.Node] = [] @@ -145,7 +146,7 @@ class AStar(MazeSolver): else: raise Exception("Translate error: AStar path not found") - def translate(self, close: list) -> str: + def translate(self, close: list['Node']) -> str: current = close[-1] res = "" while True: @@ -158,28 +159,35 @@ class AStar(MazeSolver): def solve( self, maze: Maze, height: int | None = None, width: int | None = None ) -> str: - path = self.get_path(maze.get_maze()) + maze_arr = maze.get_maze() + if maze_arr is None: + raise Exception("Maze is not initialized") + path: list[AStar.Node] = self.get_path(maze_arr) return self.translate(path) class DepthFirstSearchSolver(MazeSolver): - def __init__(self, start, end): + def __init__(self, start: tuple[int, int], end: tuple[int, int]): super().__init__(start, end) def solve( self, maze: Maze, height: int | None = None, width: int | None = None ) -> str: path_str = "" - visited = np.zeros((height, width), dtype=bool) - path = list() - move = list() + if height is None or width is None: + raise Exception("We need Height and Width in the arg") + visited: NDArray[Any] = np.zeros((height, width), dtype=bool) + path: list[tuple[int, int]] = list() + move: list[str] = list() maze_s = maze.get_maze() + if maze_s is None: + raise Exception("Maze is not initializef") coord = self.start - h_w = (height, width) + h_w: tuple[int, int] = (height, width) while coord != self.end: visited[coord] = True path.append(coord) - rand_p = self.random_path(visited, coord, maze_s, h_w) + rand_p: list[str] = self.random_path(visited, coord, maze_s, h_w) if not rand_p: path, move = self.back_on_step( @@ -199,9 +207,9 @@ class DepthFirstSearchSolver(MazeSolver): return path_str @staticmethod - def random_path( - visited: np.ndarray, coord: tuple, maze: np.ndarray, h_w: tuple - ) -> list: + def random_path(visited: NDArray[Any], coord: tuple[int, int], + maze: NDArray[Any], h_w: tuple[int, int] + ) -> list[str]: random_p = [] h, w = h_w y, x = coord @@ -220,17 +228,17 @@ class DepthFirstSearchSolver(MazeSolver): return random_p @staticmethod - def next_path(rand_path: list) -> str: - return np.random.choice(rand_path) + def next_path(rand_path: list[str]) -> str: + return random.choice(rand_path) @staticmethod def back_on_step( - path: list, - visited: np.ndarray, - maze: np.ndarray, - h_w: tuple, - move: list, - ) -> list: + path: list[tuple[int, int]], + visited: NDArray[Any], + maze: NDArray[Any], + h_w: tuple[int, int], + move: list[str], + ) -> tuple[list[Any], list[Any]]: while path: last = path[-1] if DepthFirstSearchSolver.random_path(visited, last, maze, h_w): @@ -240,7 +248,7 @@ class DepthFirstSearchSolver(MazeSolver): return path, move @staticmethod - def next_cell(coord: tuple, next: str) -> tuple: + def next_cell(coord: tuple[int, int], next: str) -> tuple[int, int]: y, x = coord next_step = {"N": (-1, 0), "S": (1, 0), "W": (0, -1), "E": (0, 1)} add_y, add_x = next_step[next]