diff --git a/stepushovgs/labyrinth/source/bububu/command.py b/stepushovgs/labyrinth/source/bububu/command.py new file mode 100644 index 0000000..e69de29 diff --git a/stepushovgs/labyrinth/source/bububu/observer.py b/stepushovgs/labyrinth/source/bububu/observer.py new file mode 100644 index 0000000..444861d --- /dev/null +++ b/stepushovgs/labyrinth/source/bububu/observer.py @@ -0,0 +1,59 @@ +from abc import ABC, abstractmethod +import os + + +class Event: + def __init__(self, event, maze, player_position, path): + self.event = event + self.maze = maze + self.player_position = player_position + self.path = path + + +class Observer(ABC): + + @abstractmethod + def update(self, event: Event): + pass + + +class ConsoleView(Observer): + + def update(self, event: Event): + if event.event == "path_found": + print("Путь найден:") + self.render( + event.maze, + event.player_position, + event.path + ) + elif event.event == "move": + self.render( + event.maze, + event.player_position, + event.path + ) + elif event.event == "maze_loaded": + print("Загружен лабиринт:") + self.render( + event.maze, + event.player_position, + event.path + ) + else: + pass + + + def render(self, maze, player_position, path): + os.system('cls' if os.name == 'nt' else 'clear') + + for line in maze.cells: + for c in line: + if c.getXY() == player_position: + print('P', end='') + elif c.getXY() in path: + print('*', end='') + else: + print(c.toStr(), end='') + + print() \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/classes/cell.py b/stepushovgs/labyrinth/source/classes/cell.py index e8a3ea1..a128510 100644 --- a/stepushovgs/labyrinth/source/classes/cell.py +++ b/stepushovgs/labyrinth/source/classes/cell.py @@ -32,7 +32,7 @@ class Cell: self.isWall = isWall self.isStart = isStart self.isExit = isExit - self.valur = value + self.__value = value pass @property @@ -54,6 +54,11 @@ class Cell: """Возвращает кортеж координат в формате `(x, y)`""" return self.__x, self.__y + @property + def value(self) -> int: + """Возвращает вес клетки""" + return self.__value + def toStr(self): """ Возвращает строчкое представление клетки @@ -77,7 +82,4 @@ class Cell: else: return ' ' - @property - def value(self) -> int: - """Возвращает вес клетки""" - return self.value \ No newline at end of file + \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/strategy/BFS.py b/stepushovgs/labyrinth/source/strategy/BFS.py index b6eb0b7..998f1bd 100644 --- a/stepushovgs/labyrinth/source/strategy/BFS.py +++ b/stepushovgs/labyrinth/source/strategy/BFS.py @@ -3,8 +3,11 @@ from source.classes.maze import Maze from source.classes.cell import Cell class BFS(PathFindingStrategy): - def findPath(self, maze: Maze, start: Cell, exit: Cell): + def findPath(self, maze: Maze): pass + + def name(self): + return "BFS" - def __BSF__(self, maze: Maze, start: Cell, exit: Cell): + def __BSF__(self, maze: Maze): pass \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/strategy/DFS.py b/stepushovgs/labyrinth/source/strategy/DFS.py index 1e5f9be..f0aef0d 100644 --- a/stepushovgs/labyrinth/source/strategy/DFS.py +++ b/stepushovgs/labyrinth/source/strategy/DFS.py @@ -3,8 +3,48 @@ from source.classes.maze import Maze from source.classes.cell import Cell class DFS(PathFindingStrategy): - def findPath(self, maze: Maze, start: Cell, exit: Cell): + def findPath(self, maze: Maze): + pass + def name(self): + return "DFS" + + def __dfs__(self, maze: Maze): + + + pass - def __dfs__(self, maze: Maze, start: Cell, exit: Cell): - pass \ No newline at end of file + +# 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 diff --git a/stepushovgs/labyrinth/source/strategy/maze_solver.py b/stepushovgs/labyrinth/source/strategy/maze_solver.py new file mode 100644 index 0000000..c32173f --- /dev/null +++ b/stepushovgs/labyrinth/source/strategy/maze_solver.py @@ -0,0 +1,35 @@ +import time + + +from source.strategy.strategy import SearchStats, PathFindingStrategy + +class MazeSolver: + def __init__(self, maze, strategy: PathFindingStrategy): + self.maze = maze + self.strategy = strategy + + def strategyName(self): + return self.strategy.name + + def setStrategy(self, strategy: PathFindingStrategy): + self.strategy = strategy + + def solve(self): + start_time = time.perf_counter() + path, visited_cells = self.strategy.findPath(self.maze) + finish_time = time.perf_counter() + + return SearchStats( + timeMs=finish_time - start_time, + visitedCells=visited_cells, + pathLength=len(path) + ) + + + +class SearchStats: + """Общая информация о тесте алгоритма""" + def __init__(self, timeMs: float, visitedCells: int, pathLength: int): + self.timeMs = timeMs + self.visitedCells = visitedCells + self.pathLength = pathLength \ No newline at end of file diff --git a/stepushovgs/labyrinth/source/strategy/strategy.py b/stepushovgs/labyrinth/source/strategy/strategy.py index e6fa8ff..b55fc2e 100644 --- a/stepushovgs/labyrinth/source/strategy/strategy.py +++ b/stepushovgs/labyrinth/source/strategy/strategy.py @@ -9,6 +9,14 @@ class PathFindingStrategy(ABC): """Интерфейс для семейства алгоритмов поиска пути от старта до выхода.""" @abstractmethod - def findPath(self, maze: Maze, start: Cell, exit: Cell): - """Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет.""" - pass \ No newline at end of file + def findPath(self, maze: Maze) -> tuple[list[Cell], int]: + """Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток.""" + pass + @property + @abstractmethod + def name(self) -> str: + """Возвращает название алгоритма""" + pass + + + diff --git a/stepushovgs/labyrinth/test.ipynb b/stepushovgs/labyrinth/test.ipynb index a58e333..00fce5a 100644 --- a/stepushovgs/labyrinth/test.ipynb +++ b/stepushovgs/labyrinth/test.ipynb @@ -56,11 +56,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "22325f68", "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Загружен лабиринт:\n", + "**P# ###\n", + "## # # E\n", + "# # #\n", + "### ## #\n", + "# #\n", + "########\n" + ] + } + ], + "source": [ + "from source.bububu.observer import ConsoleView, Event\n", + "\n", + "view = ConsoleView()\n", + "view.update(Event(\n", + " event=\"maze_loaded\",\n", + " maze=maze,\n", + " player_position=(2, 0),\n", + " path=[(0, 0), (1, 0)]\n", + "))" + ] }, { "cell_type": "code",