93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
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: Найденный путь — список клеток от старта до выхода.
|
||
"""
|
||
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,
|
||
) |