2026-rff_mp/groshevava/docs/data/solver.py

61 lines
2.1 KiB
Python
Raw Normal View History

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