forked from UNN/2026-rff_mp
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
import time
|
|
from typing import Optional, List
|
|
from maze_core import Cell, Maze
|
|
from pathfinding import SearchStrategy
|
|
|
|
class SearchStats:
|
|
def __init__(self, time_ms: float, visited: int, path_len: int):
|
|
self.time_ms = time_ms
|
|
self.visited_cells = visited
|
|
self.path_length = path_len
|
|
|
|
def __repr__(self):
|
|
return f"Stats({self.time_ms:.2f}ms, {self.visited_cells} cells, {self.path_length} steps)"
|
|
|
|
class MazeSolver:
|
|
def __init__(self, maze: Maze, strategy: Optional[SearchStrategy] = None):
|
|
self.maze = maze
|
|
self.strategy = strategy
|
|
self._path = []
|
|
self._observers = []
|
|
|
|
def set_strategy(self, strategy: SearchStrategy):
|
|
self.strategy = strategy
|
|
|
|
def add_observer(self, observer):
|
|
self._observers.append(observer)
|
|
|
|
def _notify(self, msg: str):
|
|
for obs in self._observers:
|
|
obs.update(msg)
|
|
|
|
def solve(self) -> SearchStats:
|
|
if not self.strategy:
|
|
raise ValueError("Стратегия не выбрана")
|
|
|
|
self._notify("Начинаю поиск")
|
|
|
|
t0 = time.perf_counter()
|
|
path = self.strategy.find_path(self.maze, self.maze.start_cell, self.maze.exit_cell)
|
|
t1 = time.perf_counter()
|
|
|
|
self._path = path
|
|
ms = (t1 - t0) * 1000
|
|
|
|
self._notify(f"Найден путь: {len(path)} шагов" if path else "Пути не найдено!")
|
|
|
|
return SearchStats(ms, self.strategy.visited_count, len(path))
|
|
|
|
@property
|
|
def last_path(self) -> List[Cell]:
|
|
return self._path |