forked from UNN/2026-rff_mp
Compare commits
No commits in common. "c7c181f30b7c5611e88d806f6117aa1fa66bfb3f" and "94a9cba182e11561f22180a4b77c0f3d001a7fc9" have entirely different histories.
c7c181f30b
...
94a9cba182
|
|
@ -1,72 +0,0 @@
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
from itertools import product
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from task2.mazeObjects.maze import Maze
|
|
||||||
from task2.mazeObjects.cell import Cell
|
|
||||||
|
|
||||||
class MazeBuilder(ABC):
|
|
||||||
"""Интерфейс MazeBuilder с методом buildFromFile(filename)"""
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def buildFromFile(self, filename: str):
|
|
||||||
"""Создание лабиринта из файла."""
|
|
||||||
|
|
||||||
|
|
||||||
class TextFileMazeBuilder(MazeBuilder):
|
|
||||||
"""Читает файл, парсит символы,
|
|
||||||
создаёт объекты Cell,
|
|
||||||
задаёт координаты и флаги,
|
|
||||||
после чего возвращает готовый Maze."""
|
|
||||||
|
|
||||||
start = {'x': 0, 'y': 0}
|
|
||||||
end = {'x': 0, 'y': 0}
|
|
||||||
|
|
||||||
def cellStrategy(self, letter: str) -> Cell:
|
|
||||||
if letter == '#':
|
|
||||||
return Cell(isWall=True)
|
|
||||||
elif letter == ' ':
|
|
||||||
return Cell()
|
|
||||||
elif letter == 'S':
|
|
||||||
return Cell(isStart=True)
|
|
||||||
elif letter == 'E':
|
|
||||||
return Cell(isExit=True)
|
|
||||||
else:
|
|
||||||
sys.stderr.write(f"Неизвестный символ '{letter}' при загрузке из файла\n")
|
|
||||||
return Cell()
|
|
||||||
|
|
||||||
def updateStartEnd(self, letter: str, x:int, y:int) -> None:
|
|
||||||
if letter == 'S':
|
|
||||||
self.start = {'x': x, 'y': y}
|
|
||||||
elif letter == 'E':
|
|
||||||
self.end = {'x': x, 'y': y}
|
|
||||||
|
|
||||||
def generate_row_from_txt(self, filename: str) -> list[str]:
|
|
||||||
with open(filename) as file:
|
|
||||||
text = file.read()
|
|
||||||
text = text.strip()
|
|
||||||
if not text:
|
|
||||||
raise ValueError(f"Файл \"{filename}\" пуст")
|
|
||||||
text = text.split('\n')
|
|
||||||
return text
|
|
||||||
|
|
||||||
def buildFromFile(self, filename: str):
|
|
||||||
rows = self.generate_row_from_txt(filename)
|
|
||||||
height = len(rows)
|
|
||||||
width = len(rows[0])
|
|
||||||
array = [[Cell() for j in range(width)] for i in range(height)]
|
|
||||||
|
|
||||||
# Здесь x и y где-то перепутаны, но мне лень это чинить
|
|
||||||
try:
|
|
||||||
for x, y in product(range(width), range(height)):
|
|
||||||
cell = self.cellStrategy(rows[y][x])
|
|
||||||
self.updateStartEnd(rows[y][x], x, y)
|
|
||||||
cell.x = x
|
|
||||||
cell.y = y
|
|
||||||
array[y][x] = cell
|
|
||||||
except IndexError:
|
|
||||||
raise ValueError(f"Строка {x+1} имеет длину {len(rows[x])}, ожидалось {width}")
|
|
||||||
|
|
||||||
return Maze(array, self.start, self.end)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
class Cell:
|
|
||||||
"""Хранит координаты (x, y)
|
|
||||||
флаги isWall, isStart, isExit
|
|
||||||
метод isPassable() (возвращает True для прохода, если не стена)."""
|
|
||||||
def __init__(self, x: int = 0, y: int = 0, isWall:bool = False, isStart:bool = False, isExit:bool = False):
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
self.isWall = isWall
|
|
||||||
self.isStart = isStart
|
|
||||||
self.isExit = isExit
|
|
||||||
|
|
||||||
def isPassable(self):
|
|
||||||
return not self.isWall
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
from task2.mazeObjects.cell import Cell
|
|
||||||
|
|
||||||
class Maze:
|
|
||||||
"""Хранит двумерный массив клеток,
|
|
||||||
ширину, высоту, ссылки на стартовую и выходную клетку.
|
|
||||||
Методы:
|
|
||||||
getCell(x, y), getNeighbors(cell) – возвращает список соседних проходимых клеток
|
|
||||||
(вверх, вниз, влево, вправо, если в пределах границ и не стена)."""
|
|
||||||
|
|
||||||
def __init__(self, mazeArray: list[list[Cell]], start: dict, end: dict) -> None:
|
|
||||||
self.mazeArray = mazeArray
|
|
||||||
self.width = len(mazeArray)
|
|
||||||
self.height = len(mazeArray[0])
|
|
||||||
|
|
||||||
self.startCell = self.getCell(start['x'], start['y'])
|
|
||||||
self.endCell = self.getCell(end['x'], end['y'])
|
|
||||||
|
|
||||||
def getCell(self, x: int, y: int):
|
|
||||||
return self.mazeArray[y][x]
|
|
||||||
|
|
||||||
def checkCell(self, x: int, y: int):
|
|
||||||
if not(0 <= x and x < self.width):
|
|
||||||
return False
|
|
||||||
if not(0 <= y and y < self.height):
|
|
||||||
return False
|
|
||||||
return self.getCell(x, y).isPassable()
|
|
||||||
|
|
||||||
def getNeighbors(self, cell: Cell):
|
|
||||||
point = (cell.x, cell.y)
|
|
||||||
offsets = ((0, 1),
|
|
||||||
(0, -1),
|
|
||||||
(-1, 0),
|
|
||||||
(1, 0))
|
|
||||||
passableCells = []
|
|
||||||
for ofst in offsets:
|
|
||||||
x = point[0]+ofst[0]
|
|
||||||
y = point[1]+ofst[1]
|
|
||||||
if self.checkCell(x, y):
|
|
||||||
passableCells.append(self.getCell(x, y))
|
|
||||||
return passableCells
|
|
||||||
Loading…
Reference in New Issue
Block a user