Сделал ConsoleView и MazeSolver

This commit is contained in:
GordStep 2026-05-20 23:07:51 +03:00
parent e5493a5439
commit 0f5089fb24
8 changed files with 187 additions and 16 deletions

View 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()

View File

@ -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

View File

@ -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

View File

@ -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;
# }

View 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

View File

@ -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

View File

@ -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",