2026-rff_mp/osipovamd/maze_project/maze_solver.py

71 lines
2.6 KiB
Python
Raw Normal View History

2026-05-27 19:49:24 +00:00
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