from abc import ABC, abstractmethod from models import Cell, Maze class MazeBuilder(ABC): @abstractmethod def build_from_file(self, filename: str) -> Maze: pass class TextFileMazeBuilder(MazeBuilder): WALL_CHAR = '#' START_CHAR = 'S' EXIT_CHAR = 'E' PASS_CHAR = ' ' 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) for y, line in enumerate(lines): for x, ch in enumerate(line): if x >= width: continue cell = Cell(x, y) if ch == self.WALL_CHAR: cell.is_wall = True elif ch == self.START_CHAR: cell.is_start = True elif ch == self.EXIT_CHAR: cell.is_exit = True elif ch == self.PASS_CHAR: pass else: cell.is_wall = True maze.set_cell(x, y, cell) if maze.start is None: raise ValueError("В лабиринте нет стартовой клетки (S)") if maze.exit is None: raise ValueError("В лабиринте нет выхода (E)") return maze