Сделал 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.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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
# 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
|
||||
def findPath(self, maze: Maze, start: Cell, exit: Cell):
|
||||
"""Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет."""
|
||||
pass
|
||||
def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
|
||||
"""Возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет и количество посещённых клеток."""
|
||||
pass
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
"""Возвращает название алгоритма"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user