# Этап 2. Загрузка лабиринта из файла

Во втором этапе реализована загрузка лабиринта из текстового файла с применением паттерна **Builder**.

## Паттерн Builder

Процесс создания лабиринта из файла включает несколько шагов: чтение файла, валидацию структуры, парсинг символов и заполнение клеток. Builder скрывает эти детали от клиента — снаружи виден только один метод `build_from_file()`, внутри которого сосредоточена вся логика построения.

Дополнительное преимущество: в будущем можно легко добавить новый формат (например, JSON или бинарный) через новую реализацию `MazeBuilder` без изменения остального кода.

## Класс `MazeBuilder`

Абстрактный базовый класс — интерфейс паттерна Builder. Объявляет единственный метод `build_from_file()`, который обязан реализовать каждый конкретный строитель.

По условию задания интерфейс назывался `MazeBuilder` с методом `buildFromFile`. В реализации название метода приведено к **PEP 8** — `build_from_file`. Сам класс оформлен через `ABC` — попытка создать объект `MazeBuilder()` напрямую вызовет `TypeError`.

## Класс `TextFileBuilder`

Конкретная реализация строителя для текстовых файлов. Загружает лабиринт из `.txt` файла где `#` — стена, — проход, `S` — старт, `E` — выход.

Процесс построения разбит на три приватных шага:

### `_read_file`

Читает файл построчно и обрезает символы переноса строки `\n` и `\r`. Возвращает список строк — каждая строка соответствует одной строке лабиринта.

### `_test_text_maze`

Валидирует структуру: проверяет что все строки одинаковой длины. Если нет — лабиринт некорректен и `_create_maze` выбросит `ValueError`.

Реализован как `@staticmethod` — не использует состояние объекта, только входные данные.

### `_create_maze`

Создаёт объект `Maze` нужного размера и заполняет его клетки символами из файла через `maze[y, x] = symbol`. Тип каждой клетки определяется автоматически через `cell_mapping` в `__setitem__` лабиринта.

## Использование

```python
from source.build.builder import TextFileBuilder

maze = TextFileBuilder().build_from_file('source/templates/10x10_path_v1.txt')
print(maze)
```

## Известная ошибка

В текущей реализации `_create_maze` есть опечатка при вычислении `width`:

```python
height, width = len(text_maze), len(text_maze)  # width всегда равен height
```

Правильная версия:

```python
height, width = len(text_maze), len(text_maze[0])
```

На квадратных лабиринтах (10×10, 50×50) это не проявляется, но на прямоугольных даст некорректный результат.