import time from dataclasses import dataclass from typing import List, Optional @dataclass #Статистика поиска пути class SearchStats: time_ms: float #Время выполнения в миллисекундах visited_cells: int #Количество посещенных клеток path_length: int #Длина найденного пути (0 если путь не найден) path_found: bool #Найден ли путь def __repr__(self): status = "Найден" if self.path_found else "Не найден" return f"Stats({status}, время={self.time_ms:.2f}мс, посещено={self.visited_cells}, длина={self.path_length})" def to_dict(self): """Преобразует статистику в словарь для CSV""" return { 'time_ms': f"{self.time_ms:.2f}", 'visited_cells': self.visited_cells, 'path_length': self.path_length, 'path_found': self.path_found } class MazeSolver: """Оркестратор для решения лабиринта""" #Инициализация решателя лабиринта def __init__(self, maze, strategy=None): self.maze = maze self._strategy = strategy self._last_path = None #Динамическая смена стратегии поиска def set_strategy(self, strategy): self._strategy = strategy print(f"Стратегия изменена на: {strategy.name}") def solve(self) -> SearchStats: if self._strategy is None: raise ValueError("Стратегия не установлена! Используйте set_strategy()") if self.maze.start is None: raise ValueError("В лабиринте нет стартовой клетки!") if self.maze.exit is None: raise ValueError("В лабиринте нет выходной клетки!") # Замер времени start_time = time.perf_counter() # Поиск пути path = self._strategy.find_path(self.maze, self.maze.start, self.maze.exit) end_time = time.perf_counter() time_ms = (end_time - start_time) * 1000 self._last_path = path return SearchStats( time_ms=time_ms, visited_cells=self._strategy.visited_count, path_length=len(path), path_found=len(path) > 0 ) def get_path(self) -> Optional[List]: """Возвращает последний найденный путь""" return self._last_path #Выводит лабиринт с найденным путем def print_maze_with_path(self): if not self._last_path: print("Путь еще не найден. Сначала вызовите solve()") return path_set = set(self._last_path) print(f"\n {' ' * 4}", end="") for x in range(self.maze.width): print(f"{x} ", end="") print() for y in range(self.maze.height): print(f" {y} │ ", end="") for x in range(self.maze.width): cell = self.maze.get_cell(x, y) if cell == self.maze.start: print("S ", end="") elif cell == self.maze.exit: print("E ", end="") elif cell in path_set: print("● ", end="") elif cell.is_wall: print("# ", end="") else: print("· ", end="") print() print("\n Условные обозначения:") print(" # - стена · - проход ● - путь") print(" S - старт E - выход") #Сравнивает несколько стратегий на одном лабиринте def compare_strategies(self, strategies: List) -> dict: results = {} print(f"СРАВНЕНИЕ СТРАТЕГИЙ") print(f"Лабиринт: {self.maze.width}x{self.maze.height}") for strategy in strategies: self.set_strategy(strategy) stats = self.solve() results[strategy.name] = { 'stats': stats, 'path': self.get_path() } # Вывод результатов status = "OK" if stats.path_found else "BULLSHIT" print(f"\n {status} {strategy.name}:") print(f" Время: {stats.time_ms:.2f} мс") print(f" Посещено клеток: {stats.visited_cells}") print(f" Длина пути: {stats.path_length}") return results