From dabd0acd9eeb54e0b645e658f9f3449d5e73a17e Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 18 May 2026 13:39:13 +0300 Subject: [PATCH] strategies --- romanovpv/task 2/docs/data/main.py | 18 ++- romanovpv/task 2/docs/data/strategies.py | 174 +++++++++++++++++++++++ 2 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 romanovpv/task 2/docs/data/strategies.py diff --git a/romanovpv/task 2/docs/data/main.py b/romanovpv/task 2/docs/data/main.py index fca2567..98b53cc 100644 --- a/romanovpv/task 2/docs/data/main.py +++ b/romanovpv/task 2/docs/data/main.py @@ -1,12 +1,16 @@ import model from builders import (TextFileMazeBuilder) +from strategies import ( + BFSStrategy, + DFSStrategy, + AStarStrategy + ) builder = TextFileMazeBuilder() maze = builder.buildFromFile("maze.txt") -maze.printMaze() -print() -print("Старт:") -print(maze.start) -print() -print("Выход:") -print(maze.exit) \ No newline at end of file +strategy = DFSStrategy() +path = strategy.findPath(maze, maze.start, maze.exit) +print(f"Метод: {strategy}") +print("Путь:\n") +for cell in path: + print(f"({cell.x},{cell.y})") \ No newline at end of file diff --git a/romanovpv/task 2/docs/data/strategies.py b/romanovpv/task 2/docs/data/strategies.py new file mode 100644 index 0000000..fdca4ed --- /dev/null +++ b/romanovpv/task 2/docs/data/strategies.py @@ -0,0 +1,174 @@ +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 + ) + for neighbor in maze.getNeighbors(current): + if neighbor not in visited: + visited.add( + neighbor + ) + parent[ + neighbor + ] = current + queue.append( + neighbor + ) + return [] + +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 + ) + for neighbor in maze.getNeighbors(current): + if neighbor not in visited: + visited.add( + neighbor + ) + parent[ + neighbor + ] = current + + stack.append( + neighbor + ) + return [] + +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 + ) + 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 [] \ No newline at end of file