diff --git a/raskatovia/docs/data/task2/solver.py b/raskatovia/docs/data/task2/solver.py index 1f22173..ad20457 100644 --- a/raskatovia/docs/data/task2/solver.py +++ b/raskatovia/docs/data/task2/solver.py @@ -1,3 +1,7 @@ +from collections import deque +import heapq +from maze import MazeBuilder + from collections import deque from maze import MazeBuilder @@ -67,6 +71,41 @@ class DfsStrategy: "visited": visited_count, "length": len(path) } +def distance(first, second): + return abs(first[0] - second[0]) + abs(first[1] - second[1]) + +class AstarStrategy: + def solve(self, maze): + start = maze.start + finish = maze.finish + queue = [] + heapq.heappush(queue, (0, start)) + previous = {start: None} + costs = {start: 0} + visited_count = 0 + + while queue: + current = heapq.heappop(queue)[1] + visited_count += 1 + + if current == finish: + break + + for next_cell in maze.neighbors(current[0], current[1]): + new_cost = costs[current] + 1 + if next_cell not in costs or new_cost < costs[next_cell]: + costs[next_cell] = new_cost + priority = new_cost + distance(next_cell, finish) + heapq.heappush(queue, (priority, next_cell)) + previous[next_cell] = current + + path = build_path(previous, start, finish) + return { + "name": "A*", + "path": path, + "visited": visited_count, + "length": len(path) + } class MazeSolver: def __init__(self, strategy): @@ -77,7 +116,7 @@ class MazeSolver: if __name__ == "__main__": maze = MazeBuilder().from_file("raskatovia/docs/data/task2/maps/simple.txt").build() - strategies = [BfsStrategy(), DfsStrategy()] + strategies = [BfsStrategy(), DfsStrategy(), AstarStrategy()] for strategy in strategies: solver = MazeSolver(strategy)