from abc import ABC, abstractmethod from .maze import 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 f: lines = [line.rstrip("\n") for line in f.readlines()] height = len(lines) width = max(len(line) for line in lines) if height > 0 else 0 start_count = 0 exit_count = 0 maze = Maze(width, height) for y, line in enumerate(lines): for x, ch in enumerate(line): if ch == "#": maze.set_cell(x, y, "wall") elif ch == "S": maze.set_cell(x, y, "start") start_count += 1 elif ch == "E": maze.set_cell(x, y, "exit") exit_count += 1 else: maze.set_cell(x, y, "path") if start_count != 1 or exit_count != 1: raise ValueError(f"S={start_count}, E={exit_count}") return maze