lab_2 builder, BFS, DFS

This commit is contained in:
gutovvm 2026-05-24 22:12:39 +03:00
parent f62aa21088
commit 3d7c072106
3 changed files with 234 additions and 0 deletions

View File

@ -0,0 +1,228 @@
import numpy as np
import abc
from collections import deque
#Классы клетки и лабиринта
class Cell:
def __init__(self, coords, isWall = False, isStart = False,
isExit = False):
self.coords = coords
self.isWall = isWall
self.isStart = isStart
self.isExit = isExit
def isPassable(self):
if self.isWall:
return False
return True
class Maze:
def __init__(self, cells, width, height, st, ex):
self.cells = cells
self.width = width
self.height = height
self.st = st
self.ex = ex
def getCell(self,x,y):
try:
return self.cells[x][y]
except:
return None
def getNeighbors(self,cell):
x,y = cell.coords
res = []
for i,j in (x,y+1),(x,y-1),(x-1,y),(x+1,y):
cellij = self.getCell(i,j)
if i <= self.width-1 and j <= self.height-1 and 0 <= i and 0 <= j and cellij is not None:
if cellij.isPassable():
res.append(cellij)
else:
res.append(None)
else:
res.append(None)
return res
#Тестирование классов клетки и лабиринта
cell1 = Cell((1,2), isExit = True, isWall = True, isStart = False)
print(cell1.isPassable())
print(cell1.isStart)
print(cell1.coords)
width, height = 3,3
cells = np.full((width,height), None, dtype=object)
for x in range(width):
for y in range(height):
if x != 0 and x != width-1 and y != 0 and y != height-1:
cells[x][y] = Cell((x,y), isWall = False)
else:
cells[x][y] = Cell((x,y), isWall = True)
print(cells)
maze1 = Maze(cells, width, height, cells[0], cells[-1])
for column in cells:
for cell in column:
print(cell.coords)
print(maze1.getNeighbors(cell))
print('\n')
#Интерфейс постройки лабиринта
class MazeBuilder(abc.ABC):
@abc.abstractmethod
def buildFromFile(filename): pass
#Наследуем от него класс постройки из текстового файла
class TextFileMazeBuilder(MazeBuilder):
def buildFromFile(filename):
with open(filename, "r") as file:
rows = file.read().splitlines()
print(rows)
width = 0
height = 0
for row in rows:
height += 1
if len(row) > width:
width = len(row)
print(width, height)
st = (0,0)
ex = (width,height)
cells = np.full((width,height), None, dtype=object)
for y in range(height):
for x in range(width):
isWall = False
isStart = False
isExit = False
if rows[-(y+1)][x] == '#':
isWall = True
elif rows[-(y+1)][x] == 'S':
isStart = True
st = (x,y)
print('Старт в',x,y)
elif rows[-(y+1)][x] == 'E':
isExit = True
ex = (x,y)
print('Выход в',x,y)
elif rows[-(y+1)][x] != ' ':
raise ValueError("Неверный формат лабиринта! Пожалуйста, используйте только символы #,S,E и пробелы")
cells[x][y] = Cell((x,y), isWall, isStart, isExit)
return Maze(cells, width, height, cells[st[0]][st[1]], cells[ex[0]][ex[1]])
builder = TextFileMazeBuilder
maze = builder.buildFromFile('maze1.txt')
print(maze)
#Интерфейс поиска пути
class PathFindingStrategy(abc.ABC):
@abc.abstractmethod
def findPath(maze, st, ex): pass
#Поиск в глубину
class DFS(PathFindingStrategy):
def findPath(maze,st,ex):
stack = [st]
visited = {st.coords} #по координатам надёжнее, а то вдруг адрес изменится
pathmap = {}
while stack:
cell = stack.pop()
if cell == ex:
#маршрут выстраивается в обратном порядке и разворачивается
path = []
while cell.coords != st.coords:
path.append(cell)
cell = pathmap[cell.coords]
path.append(st)
path = path[::-1]
return path
for n in maze.getNeighbors(cell):
if n != None and n.coords not in visited:
visited.add(n.coords)
pathmap[n.coords] = cell
stack.append(n)
return None
path = DFS.findPath(maze,maze.st,maze.ex)
print('путь поиском в глубину:')
for cell in path:
print(cell.coords)
class BFS(PathFindingStrategy):
def findPath(maze,st,ex):
queue = deque([st])
visited = {st.coords} #по координатам надёжнее, а то вдруг адрес изменится
pathmap = {}
while queue:
cell = queue.popleft()
if cell == ex:
#маршрут выстраивается в обратном порядке и разворачивается
path = []
while cell.coords != st.coords:
path.append(cell)
cell = pathmap[cell.coords]
path.append(st)
path = path[::-1]
return path
for n in maze.getNeighbors(cell):
if n != None and n.coords not in visited:
visited.add(n.coords)
pathmap[n.coords] = cell
queue.append(n)
return None
path = BFS.findPath(maze,maze.st,maze.ex)
print('путь поиском в ширину:')
for cell in path:
print(cell.coords)

View File

@ -0,0 +1,6 @@
## ####S# ##
# ## # ##
## # # # #
# ### #
# ## ## E
# ##### ######

Binary file not shown.