forked from UNN/2026-rff_mp
Реализован этап 2
This commit is contained in:
parent
b002e85958
commit
c7c181f30b
72
MusinAA/task2/mazeBuilder.py
Normal file
72
MusinAA/task2/mazeBuilder.py
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@ class Cell:
|
||||||
"""Хранит координаты (x, y)
|
"""Хранит координаты (x, y)
|
||||||
флаги isWall, isStart, isExit
|
флаги isWall, isStart, isExit
|
||||||
метод isPassable() (возвращает True для прохода, если не стена)."""
|
метод isPassable() (возвращает True для прохода, если не стена)."""
|
||||||
def __init__(self, x: int, y: int, isWall = False, isStart = False, isExit = False):
|
def __init__(self, x: int = 0, y: int = 0, isWall:bool = False, isStart:bool = False, isExit:bool = False):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.isWall = isWall
|
self.isWall = isWall
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user