forked from UNN/2026-rff_mp
Сделал ConsoleView и MazeSolver
This commit is contained in:
parent
e5493a5439
commit
0f5089fb24
0
stepushovgs/labyrinth/source/bububu/command.py
Normal file
0
stepushovgs/labyrinth/source/bububu/command.py
Normal file
59
stepushovgs/labyrinth/source/bububu/observer.py
Normal file
59
stepushovgs/labyrinth/source/bububu/observer.py
Normal file
|
|
@ -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()
|
||||||
|
|
@ -32,7 +32,7 @@ class Cell:
|
||||||
self.isWall = isWall
|
self.isWall = isWall
|
||||||
self.isStart = isStart
|
self.isStart = isStart
|
||||||
self.isExit = isExit
|
self.isExit = isExit
|
||||||
self.valur = value
|
self.__value = value
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -54,6 +54,11 @@ class Cell:
|
||||||
"""Возвращает кортеж координат в формате `(x, y)`"""
|
"""Возвращает кортеж координат в формате `(x, y)`"""
|
||||||
return self.__x, self.__y
|
return self.__x, self.__y
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self) -> int:
|
||||||
|
"""Возвращает вес клетки"""
|
||||||
|
return self.__value
|
||||||
|
|
||||||
def toStr(self):
|
def toStr(self):
|
||||||
"""
|
"""
|
||||||
Возвращает строчкое представление клетки
|
Возвращает строчкое представление клетки
|
||||||
|
|
@ -77,7 +82,4 @@ class Cell:
|
||||||
else:
|
else:
|
||||||
return ' '
|
return ' '
|
||||||
|
|
||||||
@property
|
|
||||||
def value(self) -> int:
|
|
||||||
"""Возвращает вес клетки"""
|
|
||||||
return self.value
|
|
||||||
|
|
@ -3,8 +3,11 @@ from source.classes.maze import Maze
|
||||||
from source.classes.cell import Cell
|
from source.classes.cell import Cell
|
||||||
|
|
||||||
class BFS(PathFindingStrategy):
|
class BFS(PathFindingStrategy):
|
||||||
def findPath(self, maze: Maze, start: Cell, exit: Cell):
|
def findPath(self, maze: Maze):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __BSF__(self, maze: Maze, start: Cell, exit: Cell):
|
def name(self):
|
||||||
|
return "BFS"
|
||||||
|
|
||||||
|
def __BSF__(self, maze: Maze):
|
||||||
pass
|
pass
|
||||||
|
|
@ -3,8 +3,48 @@ from source.classes.maze import Maze
|
||||||
from source.classes.cell import Cell
|
from source.classes.cell import Cell
|
||||||
|
|
||||||
class DFS(PathFindingStrategy):
|
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
|
pass
|
||||||
|
|
||||||
def __dfs__(self, maze: Maze, start: Cell, exit: Cell):
|
|
||||||
pass
|
# public static Cell SearchInDepth(Cell entry, Cell target)
|
||||||
|
# {
|
||||||
|
# Dictionary<int, Cell> visited = new Dictionary<int, Cell>();
|
||||||
|
# Stack<Cell> toVisit = new Stack<Cell>();
|
||||||
|
# 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<Cell> 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;
|
||||||
|
# }
|
||||||
35
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
35
stepushovgs/labyrinth/source/strategy/maze_solver.py
Normal file
|
|
@ -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
|
||||||
|
|
@ -9,6 +9,14 @@ class PathFindingStrategy(ABC):
|
||||||
"""Интерфейс для семейства алгоритмов поиска пути от старта до выхода."""
|
"""Интерфейс для семейства алгоритмов поиска пути от старта до выхода."""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def findPath(self, maze: Maze, start: Cell, exit: Cell):
|
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||||
"""Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет."""
|
"""Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток."""
|
||||||
pass
|
pass
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def name(self) -> str:
|
||||||
|
"""Возвращает название алгоритма"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,35 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 3,
|
||||||
"id": "22325f68",
|
"id": "22325f68",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
"source": []
|
{
|
||||||
|
"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",
|
"cell_type": "code",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user