forked from UNN/2026-rff_mp
61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
|
|
from typing import List, Tuple
|
|||
|
|
from buildersMaze_builder import MazeBuilder
|
|||
|
|
from modelsMaze import Maze
|
|||
|
|
from modelsCell import Cell
|
|||
|
|
|
|||
|
|
class TextFieldMazeBuilder(MazeBuilder):
|
|||
|
|
"""Загрузчик лабиринта из текстового файла."""
|
|||
|
|
|
|||
|
|
# Символы в файле
|
|||
|
|
WALL_CHAR = '#'
|
|||
|
|
PASS_CHAR = ' '
|
|||
|
|
START_CHAR = 'S'
|
|||
|
|
EXIT_CHAR = 'E'
|
|||
|
|
|
|||
|
|
def build_from_file(self, filename: str) -> Maze:
|
|||
|
|
"""Загрузить лабиринт из текстового файла."""
|
|||
|
|
with open(filename, 'r', encoding='utf-8') as f:
|
|||
|
|
lines = [line.rstrip('\n') for line in f.readlines()]
|
|||
|
|
|
|||
|
|
if not lines:
|
|||
|
|
raise ValueError("Файл пуст")
|
|||
|
|
|
|||
|
|
height = len(lines)
|
|||
|
|
width = max(len(line) for line in lines)
|
|||
|
|
|
|||
|
|
maze = Maze(width, height)
|
|||
|
|
start_cell = None
|
|||
|
|
exit_cell = None
|
|||
|
|
|
|||
|
|
for y, line in enumerate(lines):
|
|||
|
|
for x, ch in enumerate(line):
|
|||
|
|
if x >= width:
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
is_wall = (ch == self.WALL_CHAR)
|
|||
|
|
is_start = (ch == self.START_CHAR)
|
|||
|
|
is_exit = (ch == self.EXIT_CHAR)
|
|||
|
|
|
|||
|
|
# Пробел или буква - проходимая клетка
|
|||
|
|
if ch == self.PASS_CHAR or is_start or is_exit:
|
|||
|
|
is_wall = False
|
|||
|
|
|
|||
|
|
cell = Cell(x=x, y=y, is_wall=is_wall, is_start=is_start, is_exit=is_exit)
|
|||
|
|
maze.set_cell(x, y, cell)
|
|||
|
|
|
|||
|
|
if is_start:
|
|||
|
|
start_cell = cell
|
|||
|
|
if is_exit:
|
|||
|
|
exit_cell = cell
|
|||
|
|
|
|||
|
|
# Валидация
|
|||
|
|
if start_cell is None:
|
|||
|
|
raise ValueError("В лабиринте нет стартовой клетки (S)")
|
|||
|
|
if exit_cell is None:
|
|||
|
|
raise ValueError("В лабиринте нет выходной клетки (E)")
|
|||
|
|
|
|||
|
|
maze.start_cell = start_cell
|
|||
|
|
maze.exit_cell = exit_cell
|
|||
|
|
|
|||
|
|
return maze
|