61 lines
1.5 KiB
Python
61 lines
1.5 KiB
Python
import heapq
|
|
import itertools
|
|
|
|
from strategies.pathfinding_strategy import PathFindingStrategy
|
|
|
|
|
|
class AStarStrategy(PathFindingStrategy):
|
|
|
|
def heuristic(self, cell, exit_cell):
|
|
return abs(cell.x - exit_cell.x) + abs(cell.y - exit_cell.y)
|
|
|
|
def find_path(self, maze, start_cell, exit_cell):
|
|
|
|
open_set = []
|
|
counter = itertools.count()
|
|
|
|
heapq.heappush(open_set, (0, next(counter), start_cell))
|
|
|
|
parents = {start_cell: None}
|
|
g_score = {start_cell: 0}
|
|
|
|
visited = set()
|
|
visited_count = 0
|
|
|
|
while open_set:
|
|
|
|
_, _, current = heapq.heappop(open_set)
|
|
|
|
if current in visited:
|
|
continue
|
|
|
|
visited.add(current)
|
|
visited_count += 1
|
|
|
|
if current == exit_cell:
|
|
|
|
path = []
|
|
while current is not None:
|
|
path.append(current)
|
|
current = parents[current]
|
|
|
|
path.reverse()
|
|
return path, visited_count
|
|
|
|
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]:
|
|
|
|
parents[neighbor] = current
|
|
g_score[neighbor] = tentative_g
|
|
|
|
f_score = tentative_g + self.heuristic(neighbor, exit_cell)
|
|
|
|
heapq.heappush(
|
|
open_set,
|
|
(f_score, next(counter), neighbor)
|
|
)
|
|
|
|
return [], visited_count |