2026-rff_mp/MusinAA/task2/mazeBuilder.py

72 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from abc import ABC, abstractmethod
from itertools import product
import sys
import os.path as path
from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell
from task2.observerSubject import MazeEvent, MazeEventType, Subject
class MazeBuilder(ABC):
"""Интерфейс MazeBuilder с методом buildFromFile(filename)"""
@abstractmethod
def buildFromFile(self, filename: str):
"""Создание лабиринта из файла."""
class TextFileMazeBuilder(MazeBuilder):
"""Читает файл, парсит символы,
создаёт объекты Cell,
задаёт координаты и флаги,
после чего возвращает готовый Maze."""
start:dict
end:dict
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)]
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"В файле {filename}: Строка {y+1} имеет длину {len(rows[y])}, ожидалось {width}")
maze_name, _ = path.splitext(path.basename(filename))
return Maze(array, self.start, self.end, name=maze_name)