diff --git a/GutovVM/docs/data/lab_2_data/main.py b/GutovVM/docs/data/lab_2_data/main.py new file mode 100644 index 0000000..3da9999 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/main.py @@ -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) diff --git a/GutovVM/docs/data/lab_2_data/maze1.txt b/GutovVM/docs/data/lab_2_data/maze1.txt new file mode 100644 index 0000000..a1d1619 --- /dev/null +++ b/GutovVM/docs/data/lab_2_data/maze1.txt @@ -0,0 +1,6 @@ +## ####S# ## +# ## # ## +## # # # # + # ### # +# ## ## E +# ##### ###### \ No newline at end of file diff --git a/GutovVM/docs/~$tchet1.docx b/GutovVM/docs/~$tchet1.docx deleted file mode 100644 index 5ffeeda..0000000 Binary files a/GutovVM/docs/~$tchet1.docx and /dev/null differ