forked from UNN/2026-rff_mp
61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
import time
|
||
from typing import List, Tuple, Optional
|
||
from models import Maze, Cell
|
||
from strategies import PathFindingStrategy
|
||
|
||
|
||
class SearchStats:
|
||
def __init__(self, time_ms: float, visited: int, path_length: int):
|
||
self.time_ms = time_ms
|
||
self.visited_count = visited
|
||
self.path_length = path_length
|
||
|
||
def __str__(self):
|
||
return (f"Время: {self.time_ms:.4f} мс | "
|
||
f"Посещено: {self.visited_count} | "
|
||
f"Длина пути: {self.path_length}")
|
||
|
||
|
||
class MazeSolver:
|
||
def __init__(self, maze: Maze, strategy: Optional[PathFindingStrategy] = None):
|
||
self.maze = maze
|
||
self.strategy = strategy
|
||
self._observers = []
|
||
|
||
def setStrategy(self, strategy: PathFindingStrategy):
|
||
self.strategy = strategy
|
||
|
||
def attach(self, observer):
|
||
self._observers.append(observer)
|
||
|
||
def detach(self, observer):
|
||
self._observers.remove(observer)
|
||
|
||
def _notify(self, event: str, data=None):
|
||
for observer in self._observers:
|
||
observer.update(event, data)
|
||
|
||
def solve(self) -> Tuple[List[Cell], SearchStats]:
|
||
if not self.strategy:
|
||
raise ValueError("Стратегия поиска не установлена.")
|
||
if not self.maze.start or not self.maze.exit:
|
||
raise ValueError("В лабиринте не определены старт или выход.")
|
||
|
||
self._notify("search_started", {"strategy": type(self.strategy).__name__})
|
||
|
||
start_time = time.perf_counter()
|
||
path = self.strategy.findPath(self.maze, self.maze.start, self.maze.exit)
|
||
end_time = time.perf_counter()
|
||
|
||
elapsed_ms = (end_time - start_time) * 1000
|
||
visited = self.strategy.visited_count
|
||
path_len = len(path)
|
||
|
||
stats = SearchStats(elapsed_ms, visited, path_len)
|
||
|
||
if path:
|
||
self._notify("path_found", {"path": path, "stats": stats})
|
||
else:
|
||
self._notify("path_not_found", {"stats": stats})
|
||
|
||
return path, stats |