from abc import ABC, abstractmethod from collections import deque import heapq class PathFindingStrategy(ABC): @abstractmethod def findPath(self, maze, start, exit_cell): pass def restorePath(self, parent, start, exit_cell): path = [] current = exit_cell while current != start: path.append(current) current = parent[current] path.append(start) path.reverse() return path class BFSStrategy(PathFindingStrategy): def findPath( self, maze, start, exit_cell): queue = deque([start]) visited = {start} parent = {} while queue: current = queue.popleft() if current == exit_cell: return (self.restorePath(parent, start, exit_cell), len(visited)) for neighbor in maze.getNeighbors(current): if neighbor not in visited: visited.add(neighbor) parent[neighbor] = current queue.append(neighbor) return [], len(visited) class DFSStrategy(PathFindingStrategy): def findPath(self, maze, start, exit_cell): stack = [start] visited = {start} parent = {} while stack: current = stack.pop() if current == exit_cell: return (self.restorePath(parent,start,exit_cell),len(visited)) for neighbor in maze.getNeighbors(current): if neighbor not in visited: visited.add(neighbor) parent[neighbor] = current stack.append(neighbor) return [], len(visited) class AStarStrategy(PathFindingStrategy): def heuristic(self,cell,exit_cell): return (abs(cell.x - exit_cell.x) + abs(cell.y - exit_cell.y)) def findPath(self, maze, start, exit_cell): pq = [] heapq.heappush(pq,(0, id(start), start)) parent = {} g_score = {start: 0} visited = set() while pq: _, _, current = (heapq.heappop(pq)) if current in visited: continue visited.add(current) if current == exit_cell: return (self.restorePath(parent, start, exit_cell), len(visited)) for neighbor in maze.getNeighbors(current): new_cost = (g_score[current]+ 1) if (neighbor not in g_score or new_cost < g_score[neighbor] ): g_score[neighbor] = new_cost parent[neighbor] = current priority = (new_cost + self.heuristic(neighbor, exit_cell)) heapq.heappush(pq,(priority,id(neighbor),neighbor)) return [], len(visited)