65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
|
|
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
|