import time from dataclasses import dataclass from maze_model import Maze, Cell from strategies import PathFindingStrategy from observer import Observer @dataclass class SearchStats: time_ms: float visited_cells: int path_length: int path: list[Cell] class MazeSolver: def __init__(self, maze: Maze, strategy: PathFindingStrategy | None = None): self.maze = maze self.strategy = strategy self._observers: list[Observer] = [] def set_strategy(self, strategy: PathFindingStrategy) -> None: self.strategy = strategy def add_observer(self, observer: Observer) -> None: self._observers.append(observer) def remove_observer(self, observer: Observer) -> None: self._observers.remove(observer) def _notify(self, event: dict) -> None: for obs in self._observers: obs.update(event) def solve(self) -> SearchStats: if self.strategy is None: raise RuntimeError("Стратегия не задана. Используйте set_strategy().") self._notify({"type": "maze_loaded", "maze": self.maze}) t_start = time.perf_counter() path = self.strategy.find_path(self.maze, self.maze.start, self.maze.exit) t_end = time.perf_counter() time_ms = (t_end - t_start) * 1000 visited = getattr(self.strategy, "visited_count", 0) stats = SearchStats( time_ms=time_ms, visited_cells=visited, path_length=len(path), path=path, ) if path: self._notify({"type": "path_found", "maze": self.maze, "path": path}) else: self._notify({"type": "no_path"}) return stats