2026-rff_mp/skorohodovsa/task_2/source/strategy/solver.py
2026-05-25 10:23:00 +03:00

95 lines
3.2 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.

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,
)