forked from UNN/2026-rff_mp
71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
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 |