# Отчёт по работе «Поиск выхода из лабиринта»

## 1. Цель работы
Разработать гибкую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов. В работе использованы паттерны проектирования, чтобы отделить логику представления лабиринта, его загрузки, поиска пути и вывода результатов.

## 2. Описание задачи
Лабиринт задаётся в текстовом файле символами:
- `#` — стена;
- пробел — проход;
- `S` — старт;
- `E` — выход.

Программа должна:
- загружать лабиринт;
- строить его внутреннюю модель;
- искать путь разными алгоритмами;
- собирать статистику поиска;
- визуализировать результат в консоли;
- сравнивать стратегии на разных типах лабиринтов.

## 3. Выбранные паттерны проектирования

### 3.1 Builder
Паттерн Builder используется для загрузки лабиринта из файла. Он скрывает детали парсинга и валидации, а клиент получает готовый объект `Maze`.

Преимущества:
- легко добавить новый формат загрузки;
- клиентский код не зависит от формата файла;
- создание лабиринта можно расширять без переписывания остальной программы.

### 3.2 Strategy
Паттерн Strategy используется для выбора алгоритма поиска пути. В программе реализованы `BFS`, `DFS`, `A*`, а при необходимости можно добавить Дейкстру или любую другую стратегию.

Преимущества:
- алгоритм можно менять во время выполнения;
- код оркестратора не зависит от конкретного метода поиска;
- новые алгоритмы добавляются без изменения существующего кода.

### 3.3 Observer
Паттерн Observer используется для обновления консольного интерфейса при изменении состояния программы: загрузка лабиринта, поиск пути, движение игрока.

Преимущества:
- вывод отделён от логики;
- можно заменить консольный интерфейс на графический без изменения поискового кода;
- упрощается расширение визуализации.

### 3.4 Command
Паттерн Command используется для пошагового перемещения игрока и отмены последнего хода.

Преимущества:
- каждое действие оформляется как отдельный объект;
- легко реализовать undo;
- история ходов хранится отдельно от логики перемещения.

## 4. Диаграмма классов
Ниже приведена упрощённая диаграмма классов в формате Mermaid:

```mermaid
classDiagram
    class Cell {
        +int x
        +int y
        +bool isWall
        +bool isStart
        +bool isExit
        +isPassable()
    }

    class Maze {
        +cells
        +width
        +height
        +startCell
        +exitCell
        +getCell(x, y)
        +getNeighbors(cell)
    }

    class MazeBuilder {
        <<interface>>
        +buildFromFile(filename)
    }

    class TextFileMazeBuilder {
        +buildFromFile(filename)
    }

    class PathFindingStrategy {
        <<interface>>
        +findPath(maze, start, exitCell)
    }

    class BFSStrategy {
        +findPath(maze, start, exitCell)
    }

    class DFSStrategy {
        +findPath(maze, start, exitCell)
    }

    class AStarStrategy {
        +findPath(maze, start, exitCell)
    }

    class SearchStats {
        +timeMs
        +visitedCells
        +pathLength
        +path
    }

    class MazeSolver {
        +maze
        +strategy
        +setStrategy(strategy)
        +solve()
    }

    class Observer {
        <<interface>>
        +update(event)
    }

    class ConsoleView {
        +update(event)
        +render(maze, player_position, path)
    }

    class Command {
        <<interface>>
        +execute()
        +undo()
    }

    class MoveCommand {
        +execute()
        +undo()
    }

    class Player {
        +currentCell
        +setCell(cell)
    }

    Maze <|-- TextFileMazeBuilder : creates
    MazeBuilder <|.. TextFileMazeBuilder
    PathFindingStrategy <|.. BFSStrategy
    PathFindingStrategy <|.. DFSStrategy
    PathFindingStrategy <|.. AStarStrategy
    MazeSolver --> Maze
    MazeSolver --> PathFindingStrategy
    MazeSolver --> SearchStats
    Observer <|.. ConsoleView
    Command <|.. MoveCommand
    MoveCommand --> Player
    MoveCommand --> Maze
    ConsoleView --> Maze
    Maze --> Cell
```

## 5. Ключевые классы и их роль

### Cell
Хранит координаты клетки и её тип. Позволяет быстро проверять, является ли клетка проходимой.

### Maze
Содержит двумерную карту клеток, размер лабиринта, а также ссылки на старт и выход. Даёт доступ к соседним клеткам по четырём направлениям.

### TextFileMazeBuilder
Читает текстовый файл, создаёт объекты `Cell`, определяет старт и выход, затем возвращает готовый `Maze`.

### BFSStrategy
Ищет кратчайший путь по числу шагов. Подходит для случая, когда все переходы одинаковой стоимости.

### DFSStrategy
Быстро исследует пространство, но не гарантирует кратчайший путь. Полезен как сравнительный алгоритм.

### AStarStrategy
Использует эвристику Манхэттенского расстояния. Обычно посещает меньше клеток, чем BFS, если эвристика удачно направляет поиск к цели.

### MazeSolver
Оркестратор, который хранит лабиринт и текущую стратегию. Вызывает поиск, измеряет время и собирает статистику.

### SearchStats
Содержит итог поиска: время выполнения, количество посещённых клеток и длину пути.

### ConsoleView
Реализует наблюдателя и умеет выводить лабиринт и найденный путь в консоль.

### MoveCommand
Оформляет ход игрока как объект-команду. Поддерживает отмену последнего перемещения.

## 6. Экспериментальная часть

### 6.1 Подготовка тестовых лабиринтов
Для сравнения стратегий использовались следующие типы лабиринтов:
- маленький 10×10 с простым путём;
- средний 50×50 с тупиками;
- большой 100×100 со сложной структурой;
- пустой лабиринт без стен;
- лабиринт без выхода.

### 6.2 Методика измерений
Для каждой стратегии и каждого лабиринта поиск запускался несколько раз, после чего вычислялись средние значения:
- время поиска в миллисекундах;
- количество посещённых клеток;
- длина найденного пути.

Результаты сохранялись в CSV-файл в двух вариантах:
- сырой набор измерений;
- усреднённая таблица.

## 7. Анализ эффективности

### BFS
BFS гарантирует кратчайший путь по числу шагов, если все переходы имеют одинаковую стоимость. На простых и пустых лабиринтах работает стабильно и предсказуемо. Минус — может посещать много клеток, особенно на больших лабиринтах.

### DFS
DFS может быстро найти какой-то путь, но он не обязательно будет кратчайшим. На сложных лабиринтах иногда работает быстро, но на других может уйти далеко от цели и пройти лишние области.

### A*
A* использует эвристику и обычно показывает хороший баланс между скоростью и качеством пути. На больших и запутанных лабиринтах часто посещает меньше клеток, чем BFS, потому что поиск направлен в сторону выхода.

### Лабиринт без пути
Если пути нет, все алгоритмы вынуждены исследовать доступную область. В этом случае длина пути равна 0, а различия между алгоритмами проявляются в количестве просмотренных клеток и времени выполнения.

### Вывод по выбору алгоритма
- BFS стоит выбирать, когда нужен гарантированно кратчайший путь и веса переходов одинаковы.
- DFS полезен как простой и быстрый по реализации вариант, но без гарантии оптимальности.
- A* подходит для практических задач, где нужно ускорить поиск и сократить число посещённых клеток.
- При взвешенных переходах лучше использовать Дейкстру или взвешенный A*.

## 8. Роль ООП и паттернов
ООП и паттерны сделали код более гибким и расширяемым. Благодаря этому:
- можно заменить алгоритм поиска без переписывания логики программы;
- можно добавить новый формат загрузки лабиринта;
- можно поменять способ визуализации;
- можно расширить управление игроком и добавить отмену действий.

Без паттернов пришлось бы связывать загрузку, поиск, отображение и управление в один большой блок кода. Это усложнило бы отладку и дальнейшие изменения.

## 9. Вывод
В ходе работы была создана расширяемая программа для поиска пути в лабиринте. Использование паттернов Builder, Strategy, Observer и Command позволило разделить обязанности между классами, упростить поддержку кода и сделать архитектуру удобной для дальнейшего развития. Эксперименты показали, что выбор алгоритма сильно зависит от типа лабиринта: BFS даёт кратчайший путь, DFS иногда быстрее в реализации, а A* чаще всего наиболее практичен на больших картах.

## 10. Приложения
- Листинги ключевых классов.
- CSV-файлы с результатами экспериментов.
- Графики сравнений.
- Файлы с тестовыми лабиринтами.
