2026-rff_mp/ivanchenkoam/maze_project/builders.py

61 lines
2.0 KiB
Python
Raw Normal View History

"""Паттерн Builder - загрузка лабиринта из файла"""
from abc import ABC, abstractmethod
from typing import List
from models import Cell, Maze
class MazeBuilder(ABC):
"""Абстрактный строитель лабиринта"""
@abstractmethod
def build_from_file(self, filename: str) -> Maze:
pass
class TextFileMazeBuilder(MazeBuilder):
"""Строитель лабиринта из текстового файла"""
def build_from_file(self, filename: str) -> Maze:
with open(filename, 'r', encoding='utf-8') as file:
lines = [line.rstrip('\n') for line in file.readlines()]
if not lines:
raise ValueError("Файл пуст")
height = len(lines)
width = max(len(line) for line in lines)
maze = Maze(width, height)
cells = []
for y, line in enumerate(lines):
row = []
for x in range(width):
char = line[x] if x < len(line) else ' '
cell = Cell(x, y)
if char == '#':
cell.is_wall = True
elif char == 'S':
cell.is_start = True
elif char == 'E':
cell.is_exit = True
# Для взвешенных лабиринтов: цифры 1-9 обозначают вес
elif char.isdigit():
cell.is_wall = False
cell.weight = int(char)
else:
cell.is_wall = False
row.append(cell)
cells.append(row)
maze.set_cells(cells)
if maze.start is None:
raise ValueError("Нет стартовой клетки (S)")
if maze.exit is None:
raise ValueError("Нет выходной клетки (E)")
return maze