from abc import ABC, abstractmethod from typing import Tuple import os from maze_model import Maze, Cell class MazeBuilder(ABC): @abstractmethod def build_from_file(self, filename: str) -> Maze: pass class TextFileMazeBuilder(MazeBuilder): def build_from_file(self, filename: str) -> Maze: if not os.path.exists(filename): raise FileNotFoundError(f"Файл {filename} не найден..") 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 = len(lines[0]) if lines else 0 for i, line in enumerate(lines): if len(line) != width: raise ValueError(f"Лабиринт не прямоугольный, что-то не так с размерами!") maze = Maze(width, height) start_found = False exit_found = False for y, line in enumerate(lines): for x, char in enumerate(line): cell = Cell(x, y) if char == '#': cell.is_wall = True elif char == 'S': cell.is_start = True cell.is_wall = False maze.start = cell start_found = True elif char == 'E': cell.is_exit = True cell.is_wall = False maze.exit = cell exit_found = True elif char == ' ': cell.is_wall = False else: raise ValueError(f"Недопустимый символ-'{char}' в позиции ({x}, {y}), уберите его") maze.set_cell(x, y, cell) if not start_found: raise ValueError("В лабиринте нет начала") if not exit_found: raise ValueError("В лабиринте нет конца") return maze