From 498d1250b950e15442b5d4875b11a133365642c6 Mon Sep 17 00:00:00 2001 From: GordStep Date: Thu, 21 May 2026 22:06:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20dfs,?= =?UTF-8?q?=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D1=83=D1=8E=D1=89=D0=B5=D0=B9=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../labyrinth/source/bububu/observer.py | 23 ++++- stepushovgs/labyrinth/source/classes/maze.py | 2 +- stepushovgs/labyrinth/source/strategy/DFS.py | 85 +++++++++---------- .../labyrinth/source/strategy/maze_solver.py | 11 ++- .../labyrinth/source/strategy/strategy.py | 20 +++++ stepushovgs/labyrinth/test.ipynb | 64 +++++++++++++- 6 files changed, 151 insertions(+), 54 deletions(-) diff --git a/stepushovgs/labyrinth/source/bububu/observer.py b/stepushovgs/labyrinth/source/bububu/observer.py index 444861d..56314b1 100644 --- a/stepushovgs/labyrinth/source/bububu/observer.py +++ b/stepushovgs/labyrinth/source/bububu/observer.py @@ -1,6 +1,8 @@ from abc import ABC, abstractmethod import os +from source.classes.cell import Cell + class Event: def __init__(self, event, maze, player_position, path): @@ -45,7 +47,27 @@ class ConsoleView(Observer): def render(self, maze, player_position, path): + if path and isinstance(path[0], tuple): + self.render_xy(maze=maze, player_position=player_position, path=path) + return os.system('cls' if os.name == 'nt' else 'clear') + + path_xy = [cell.getXY() for cell in path] + + for line in maze.cells: + for c in line: + if c.getXY() == player_position: + print('P', end='') + elif c.getXY() in path_xy: + print('*', end='') + else: + print(c.toStr(), end='') + + print() + + def render_xy(self, maze, player_position, path: list[tuple[int, int]]): + os.system('cls' if os.name == 'nt' else 'clear') + # path_xy = [cell.getXY() for cell in path] for line in maze.cells: for c in line: @@ -55,5 +77,4 @@ class ConsoleView(Observer): print('*', end='') else: print(c.toStr(), end='') - print() \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/classes/maze.py b/stepushovgs/labyrinth/source/classes/maze.py index 6e3277d..2be2594 100644 --- a/stepushovgs/labyrinth/source/classes/maze.py +++ b/stepushovgs/labyrinth/source/classes/maze.py @@ -2,7 +2,7 @@ from source.classes.cell import Cell class Maze: """Лабиринт""" - def __init__(self, cells, width, height, start, exit): + def __init__(self, cells, width: int, height: int, start: Cell, exit: Cell): self.cells = cells self.width = width self.height = height diff --git a/stepushovgs/labyrinth/source/strategy/DFS.py b/stepushovgs/labyrinth/source/strategy/DFS.py index f0aef0d..b195ca8 100644 --- a/stepushovgs/labyrinth/source/strategy/DFS.py +++ b/stepushovgs/labyrinth/source/strategy/DFS.py @@ -1,50 +1,47 @@ -from source.strategy.strategy import PathFindingStrategy +from source.strategy.strategy import PathFindingStrategy, reconstruct_path from source.classes.maze import Maze from source.classes.cell import Cell class DFS(PathFindingStrategy): - def findPath(self, maze: Maze): - pass - def name(self): + @property + def name(self) -> str: return "DFS" - - def __dfs__(self, maze: Maze): - - - - pass - - -# public static Cell SearchInDepth(Cell entry, Cell target) -# { -# Dictionary visited = new Dictionary(); -# Stack toVisit = new Stack(); -# entry.DistanceLeft = (target.Position - entry.Position).magnitude; -# toVisit.Push(entry); -# visualise(target, VisualAction.Target); -# visualise(entry, VisualAction.ToVisit); -# while (toVisit.Count > 0) -# { -# Cell current = toVisit.Pop(); -# visualise(current, VisualAction.Visiting); -# if (current.Equals(target)) -# { -# return current; -# } -# visited.Add(current.GetHashCode(), current); -# List neighbours = GetNeighbours(current); -# foreach (Cell neighbour in neighbours) -# { -# if (!visited.ContainsKey(neighbour.GetHashCode()) && !toVisit.Contains(neighbour)) -# { -# neighbour.DistanceLeft = (target.Position - neighbour.Position).magnitude; -# toVisit.Push(neighbour); -# visualise(neighbour, VisualAction.ToVisit); -# } -# } - -# visualise(current, VisualAction.Visited); -# } -# return null; -# } \ No newline at end of file + def findPath(self, maze: Maze) -> tuple[list[Cell], int]: + start_cell = maze.start + exit_cell = maze.exit + + print(f"Старт: {start_cell.getXY()}") + print(f"Выход: {exit_cell.getXY()}") + print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}") + + stack = [start_cell] + + parents = {start_cell.getXY(): Cell(-1, -1)} + visited = {start_cell.getXY()} + count_visited = 0 + + while stack: + current = stack.pop() + + if current.getXY() == exit_cell.getXY(): + return reconstruct_path( + came_from=parents, + start=start_cell, + end=current + ), count_visited + + neigbours = maze.getNeighbors(current) + print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}") + + for neighbor in maze.getNeighbors(current): + neig_xy = neighbor.getXY() + + if neig_xy not in visited: + visited.add(neig_xy) + parents[neig_xy] = current + count_visited += 1 + # new_path = current_path + [neigbour] + stack.append(neighbor) + + return [], count_visited \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/strategy/maze_solver.py b/stepushovgs/labyrinth/source/strategy/maze_solver.py index c32173f..fb94199 100644 --- a/stepushovgs/labyrinth/source/strategy/maze_solver.py +++ b/stepushovgs/labyrinth/source/strategy/maze_solver.py @@ -1,7 +1,8 @@ import time -from source.strategy.strategy import SearchStats, PathFindingStrategy +from source.strategy.strategy import PathFindingStrategy +from source.classes.cell import Cell class MazeSolver: def __init__(self, maze, strategy: PathFindingStrategy): @@ -22,14 +23,16 @@ class MazeSolver: return SearchStats( timeMs=finish_time - start_time, visitedCells=visited_cells, - pathLength=len(path) + pathLength=len(path), + path=path ) class SearchStats: """Общая информация о тесте алгоритма""" - def __init__(self, timeMs: float, visitedCells: int, pathLength: int): + def __init__(self, timeMs: float, visitedCells: int, pathLength: int, path: list[Cell]): self.timeMs = timeMs self.visitedCells = visitedCells - self.pathLength = pathLength \ No newline at end of file + self.pathLength = pathLength + self.path = path \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/strategy/strategy.py b/stepushovgs/labyrinth/source/strategy/strategy.py index b55fc2e..ed90cfd 100644 --- a/stepushovgs/labyrinth/source/strategy/strategy.py +++ b/stepushovgs/labyrinth/source/strategy/strategy.py @@ -20,3 +20,23 @@ class PathFindingStrategy(ABC): +class CellAlgorithm(Cell): + def __init__(self, x: int, y: int, parent: Cell, exitDist: float, isWall=False, isStart=False, isExit=False, value=1): + super().__init__(x, y, isWall, isStart, isExit, value) + self.parent = parent + self.ExitDist = exitDist + self.weight = self.value + exitDist + + +def reconstruct_path(came_from: dict, start: Cell, end: Cell) -> list[Cell]: + """Восстановление пути по словарю предшественников""" + path = [] + current = end + + # Идём от конца к началу по цепочке came_from + while current.getXY() != start.getXY(): + path.append(current) + current = came_from[current.getXY()] + + path.append(start) + return path[::-1] \ No newline at end of file diff --git a/stepushovgs/labyrinth/test.ipynb b/stepushovgs/labyrinth/test.ipynb index 00fce5a..1a04544 100644 --- a/stepushovgs/labyrinth/test.ipynb +++ b/stepushovgs/labyrinth/test.ipynb @@ -65,7 +65,7 @@ "output_type": "stream", "text": [ "Загружен лабиринт:\n", - "**P# ###\n", + "\u001b[H\u001b[2J**P# ###\n", "## # # E\n", "# # #\n", "### ## #\n", @@ -89,10 +89,66 @@ { "cell_type": "code", "execution_count": null, - "id": "857c5c04", + "id": "19840429", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "from source.strategy.DFS import DFS\n", + "from source.strategy.maze_solver import MazeSolver\n", + "\n", + "strat = MazeSolver(maze, DFS())\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "857c5c04", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "2\n", + "1\n", + "3\n", + "4\n" + ] + }, + { + "data": { + "text/plain": [ + "{'0', '1', '2', '3', '4'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def dfs(graph, start, visited=None):\n", + " if visited is None:\n", + " visited = set()\n", + " visited.add(start)\n", + "\n", + " print(start)\n", + "\n", + " for next in graph[start] - visited:\n", + " dfs(graph, next, visited)\n", + " return visited\n", + "\n", + "\n", + "graph = {'0': set(['1', '2']),\n", + " '1': set(['0', '3', '4']),\n", + " '2': set(['0']),\n", + " '3': set(['1']),\n", + " '4': set(['2', '3'])}\n", + "\n", + "dfs(graph, '0')" + ] } ], "metadata": { @@ -111,7 +167,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.14.4" } }, "nbformat": 4,