import heapq from typing import List, Dict from .path_finding_strategy import PathFindingStrategy class AStarStrategy(PathFindingStrategy): """A* поиск с эвристикой (манхэттенское расстояние)""" def __init__(self): self._visited_count = 0 @property def name(self) -> str: return "AStar" def _heuristic(self, cell, exit_cell) -> int: """Манхэттенское расстояние между клетками""" return abs(cell.x - exit_cell.x) + abs(cell.y - exit_cell.y) def find_path(self, maze, start, exit_cell) -> List: """Находит путь с помощью A*""" if not start or not exit_cell: return [] # Приоритетная очередь (F-значение, ID для уникальности, клетка) open_set = [] heapq.heappush(open_set, (0, id(start), start)) # Откуда пришли в каждую клетку came_from = {} # Стоимость пути от старта до клетки (G-значение) g_score = {start: 0} # Оценочная стоимость (F-значение = G + H) f_score = {start: self._heuristic(start, exit_cell)} self._visited_count = 0 while open_set: _, _, current = heapq.heappop(open_set) self._visited_count += 1 # Нашли выход if current == exit_cell: return self._reconstruct_path(came_from, exit_cell) # Проверяем всех соседей for neighbor in maze.get_neighbors(current): tentative_g = g_score[current] + 1 if neighbor not in g_score or tentative_g < g_score[neighbor]: came_from[neighbor] = current g_score[neighbor] = tentative_g f = tentative_g + self._heuristic(neighbor, exit_cell) f_score[neighbor] = f heapq.heappush(open_set, (f, id(neighbor), neighbor)) # Путь не найден return [] def _reconstruct_path(self, came_from: Dict, current) -> List: """Восстанавливает путь от старта до exit""" path = [current] while current in came_from: current = came_from[current] path.append(current) return list(reversed(path))