2026-rff_mp/NeklyudovMS/task2/mazeSolver.py
2026-09-05 10:15:13 +03:00

70 lines
2.8 KiB
Python

from typing import Optional
from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell
from task2.observerSubject import MazeEvent, MazeEventType, Subject
from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy
from task2.strategyObjects.BFS import BFS
import time
class SearchStats:
maze_name:str = "None"
"""Время выполнения в миллисекундах, количество посещённых клеток, длина найденного пути"""
def __init__(self, path: Optional[list[Cell]], duration:float, visited_cells:int, path_len:int, strategy_name:str):
self.duration = duration
self.visited_cells = visited_cells
self.path_len = path_len
self.path = path
self.strategy_name = strategy_name
def toDict(self,):
return {
"strategy_name" : self.strategy_name,
"maze_name" : self.maze_name,
"duration" : self.duration,
"visited_cells" : self.visited_cells,
"path_len" : self.path_len
}
class MazeSolver(Subject):
"""
MazeSolver содержит поля maze и strategy.
Метод setStrategy(strategy) для динамической смены алгоритма.
Метод solve() вызывает strategy.findPath(...) и возвращает объект SearchStats (время выполнения в миллисекундах,
количество посещённых клеток, длина найденного пути).
Для замера времени используйте time.perf_counter() до и после вызова стратегии.
"""
def __init__(self, strategy:PathFindingStrategy, maze:Optional[Maze]=None):
super().__init__()
self._maze = maze
self.strategy = strategy
def setMaze(self, maze: Optional[Maze]):
self._maze = maze
self.notify(MazeEvent(MazeEventType.MAZE_LOADED, data=maze))
def setStrategy(self, strategy:PathFindingStrategy):
self.strategy = strategy
def getStrategyName(self):
return self.strategy.__class__.__name__
def solve(self):
if not self._maze:
raise ValueError
if not self._maze.startCell or not self._maze.endCell:
return SearchStats(None, 0.0, 0, -1, self.getStrategyName())
t_start = time.perf_counter()
path = self.strategy.findPath(self._maze, self._maze.startCell, self._maze.endCell)
duration = (time.perf_counter() - t_start) * 1000
path_len = len(path.array) if path.array else -1
strategy_name = self.getStrategyName()
stats = SearchStats(path.array, duration, path.visited_cells, path_len, strategy_name)
self.notify(MazeEvent(MazeEventType.PATH_FOUND, data=path))
return stats