2026-rff_mp/skorohodovsa/task_2/source/strategy/solver.py

95 lines
3.2 KiB
Python
Raw Normal View History

import time
from dataclasses import dataclass
from source.models.base import Maze, Cell
from source.strategy import PathFindingStrategy
@dataclass
class SearchStats:
"""Статистика выполнения поиска пути.
Attributes:
elapsed_ms: Время выполнения в миллисекундах.
visited_count: Количество посещённых клеток.
path_length: Длина найденного пути (0 если путь не найден).
path: Найденный путь список клеток от старта до выхода.
"""
2026-05-25 07:23:00 +00:00
elapsed_ms: float
visited_count: int
path_length: int
path: list[Cell]
def __str__(self) -> str:
return (
f"Время: {self.elapsed_ms:.3f} мс | "
f"Посещено клеток: {self.visited_count} | "
f"Длина пути: {self.path_length}"
)
class MazeSolver:
"""Оркестратор поиска пути в лабиринте.
Принимает лабиринт и стратегию поиска, выполняет поиск
и возвращает результат вместе со статистикой выполнения.
Example:
solver = MazeSolver(maze, BFSStrategy())
stats = solver.solve()
print(stats)
solver.set_strategy(AStarStrategy())
stats = solver.solve()
"""
def __init__(self, maze: Maze, strategy: PathFindingStrategy) -> None:
"""Инициализирует солвер с лабиринтом и стратегией поиска.
Args:
maze: Объект лабиринта.
strategy: Стратегия поиска пути.
"""
self._maze = maze
self._strategy = strategy
def set_strategy(self, strategy: PathFindingStrategy) -> None:
"""Заменяет текущую стратегию поиска.
Args:
strategy: Новая стратегия поиска пути.
"""
self._strategy = strategy
def solve(
self,
start: Cell = None,
exit: Cell = None,
) -> SearchStats:
"""Выполняет поиск пути и собирает статистику.
Если start или exit не переданы явно, стратегия найдёт
их самостоятельно по флагам is_start / is_exit в лабиринте.
Args:
start: Стартовая клетка (опционально).
exit: Конечная клетка (опционально).
Returns:
Объект SearchStats с временем выполнения, количеством
посещённых клеток и длиной найденного пути.
"""
t_start = time.perf_counter()
path = self._strategy.find_path(self._maze, start, exit)
t_end = time.perf_counter()
elapsed_ms = (t_end - t_start) * 1000
return SearchStats(
elapsed_ms=elapsed_ms,
visited_count=len(path),
path_length=len(path),
path=path,
2026-05-25 07:23:00 +00:00
)