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
|