2026-rff_mp/MininaVD/docs2/data2/solverMaze_solver.py

103 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# coding: utf-8
# In[ ]:
import time
from typing import List, Optional
from dataclasses import dataclass, field
from modelsMaze import Maze
from modelsCell import Cell
from strategiesPathfinding_strategy import PathFindingStrategy
from visualizationObserver import Observer
@dataclass
class SearchStats:
"""Статистика поиска."""
algorithm_name: str
time_ms: float
visited_cells: int
path_length: int
path_found: bool = True
class MazeSolver:
"""
Оркестратор для решения лабиринта.
Использует паттерн Strategy для алгоритмов поиска.
Поддерживает Observer для уведомлений.
"""
def __init__(self, maze: Maze, strategy: Optional[PathFindingStrategy] = None):
self.maze = maze
self._strategy = strategy
self._observers: List[Observer] = []
self._last_path: List[Cell] = []
self._last_stats: Optional[SearchStats] = None
def set_strategy(self, strategy: PathFindingStrategy) -> None:
"""Динамическая смена стратегии."""
self._strategy = strategy
self._notify(f"Стратегия изменена на {strategy.name}")
def attach(self, observer: Observer) -> None:
"""Подписать наблюдателя."""
self._observers.append(observer)
def detach(self, observer: Observer) -> None:
"""Отписать наблюдателя."""
if observer in self._observers:
self._observers.remove(observer)
def _notify(self, event: str) -> None:
"""Уведомить всех наблюдателей."""
for observer in self._observers:
observer.update(event)
def solve(self) -> List[Cell]:
"""
Выполнить поиск пути с текущей стратегией.
Возвращает путь (список клеток).
"""
if self._strategy is None:
raise ValueError("Стратегия не установлена")
if not self.maze.start_cell or not self.maze.exit_cell:
raise ValueError("Лабиринт не имеет старта или выхода")
self._notify(f"Начинаем поиск пути с использованием {self._strategy.name}...")
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()
time_ms = (end_time - start_time) * 1000
# Получаем количество посещённых клеток из стратегии
visited_cells = getattr(self._strategy, 'last_visited_count', 0)
self._last_path = path
self._last_stats = SearchStats(
algorithm_name=self._strategy.name,
time_ms=time_ms,
visited_cells=visited_cells,
path_length=len(path),
path_found=len(path) > 0
)
if path:
self._notify(f"Путь найден! Длина: {len(path)}, время: {time_ms:.2f} мс, посещено: {visited_cells}")
else:
self._notify(f"Путь не найден! Время: {time_ms:.2f} мс, посещено: {visited_cells}")
return path
@property
def last_path(self) -> List[Cell]:
return self._last_path
@property
def last_stats(self) -> Optional[SearchStats]:
return self._last_stats