import time from typing import List, Optional from dataclasses import dataclass from maze_model import Maze, Cell from pathfinding_strategies import PathFindingStrategy @dataclass class SearchStats: algorithm_name: str path_length: int execution_time_ms: float path_found: bool def __post_init__(self): self.execution_time_ms = round(self.execution_time_ms, 3) def summary(self) -> str: if self.path_found: return f"{self.algorithm_name}: путь найден | длина={self.path_length} | время={self.execution_time_ms} мс" return f"{self.algorithm_name}: путь НЕ найден | время={self.execution_time_ms} мс" def detailed_report(self) -> str: separator = "=" * 50 report = f"\n{separator}\nОтчёт о поиске пути\n{separator}\n" report += f"Алгоритм: {self.algorithm_name}\n" report += f"Путь найден: {'Да' if self.path_found else 'Нет'}\n" if self.path_found: report += f"Длина пути: {self.path_length} шагов\n" report += f"Время выполнения: {self.execution_time_ms} мс\n{separator}" return report class MazeSolver: def __init__(self, maze: Maze, strategy: PathFindingStrategy = None): self._maze = maze self._strategy = strategy self._last_stats: Optional[SearchStats] = None self._validate_maze() def _validate_maze(self): if not self._maze.start_cell: raise ValueError("Лабиринт не имеет стартовой клетки") if not self._maze.exit_cell: raise ValueError("Лабиринт не имеет выходной клетки") def set_strategy(self, strategy: PathFindingStrategy) -> None: self._strategy = strategy def solve(self) -> List[Cell]: if self._strategy is None: raise ValueError("Стратегия не установлена") start_time = time.perf_counter() path = self._strategy.find_path(self._maze, self._maze.start_cell, self._maze.exit_cell) end_time = time.perf_counter() self._last_stats = SearchStats( algorithm_name=self._strategy.get_name(), path_length=len(path), execution_time_ms=(end_time - start_time) * 1000, path_found=len(path) > 0 ) return path def solve_with_stats(self) -> tuple: path = self.solve() return path, self._last_stats def get_last_stats(self) -> Optional[SearchStats]: return self._last_stats