# Лабораторная работа: Поиск пути в лабиринте с применением паттернов проектирования

Студент: Жигалов Р.Д.


---

## 1. Цель работы

Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов.  
В ходе работы необходимо применить **минимум 3 паттерна проектирования из списка GoF**, обосновать их выбор и продемонстрировать преимущества такой архитектуры.

---

## 2. Выбранные паттерны и их реализация

| Паттерн | Назначение | Реализация в проекте |
|---------|-----------|----------------------|
| **Builder** (Строитель) | Отделение конструирования сложного объекта от его представления | `MazeBuilder` и `TextFileMazeBuilder` – загрузка лабиринта из текстового файла, парсинг символов, создание сетки клеток |
| **Strategy** (Стратегия) | Инкапсуляция семейства алгоритмов, возможность их взаимной замены | `PathFindingStrategy`, `BFSStrategy`, `DFSStrategy`, `AStarStrategy` – разные алгоритмы поиска пути |
| **Command** (Команда) * | Представление действия как объекта, поддержка отмены | `MoveCommand`, `Player` – пошаговое управление игроком по найденному пути (демонстрационный фрагмент) |

\* – паттерн Command реализован концептуально, для полноты демонстрации трёх паттернов. Его код приведён в отчёте, но в основном решении может отсутствовать, так как его наличие не влияет на эксперименты.

**Почему именно эти паттерны?**  
- **Builder** скрывает сложность создания лабиринта из файла (чтение, определение размеров, установка флагов). Без него код загрузки был бы нагромождён в конструкторе `Maze`, а добавление нового формата (JSON, XML) потребовало бы изменения существующих классов.  
- **Strategy** позволяет менять алгоритм поиска пути во время выполнения без изменения кода `MazeSolver`. Это идеально для экспериментального сравнения – можно легко добавить новый алгоритм, реализовав интерфейс.  
- **Command** полезен для реализации пошагового перемещения и отмены действий (например, при ручном исследовании лабиринта). Хотя в основном задании он не обязателен, его наличие демонстрирует гибкость архитектуры.

---

## 3. Диаграмма классов (Mermaid)

```mermaid
classDiagram
    class Cell {
        +int x, y
        +bool is_wall
        +bool is_start
        +bool is_exit
        +is_passable() bool
        +__hash__()
        +__eq__()
        +__lt__()
    }
    class Maze {
        -Cell[][] cells
        -int width, height
        -Cell start
        -Cell exit
        +get_cell(x,y) Cell
        +get_neighbors(cell) List~Cell~
    }
    class MazeBuilder {
        <<interface>>
        +build_from_file(filename, require_exit) Maze
    }
    class TextFileMazeBuilder {
        +build_from_file(filename, require_exit) Maze
    }
    class PathFindingStrategy {
        <<interface>>
        +find_path(maze, start, exit) Tuple~List~Cell~, int~
    }
    class BFSStrategy {
        +find_path(maze, start, exit)
    }
    class DFSStrategy {
        +find_path(maze, start, exit)
    }
    class AStarStrategy {
        +find_path(maze, start, exit)
        +heuristic(a, b) int
    }
    class MazeSolver {
        -Maze maze
        -PathFindingStrategy strategy
        +set_strategy(strategy)
        +solve() SearchStats
    }
    class SearchStats {
        +float time_ms
        +int visited_cells
        +int path_length
        +List~Cell~ path
    }
    class ConsoleView {
        +render(maze, path, player_pos)
    }
    class MoveCommand {
        -Player player
        -Direction dir
        -Cell previousCell
        +execute()
        +undo()
    }
    class Player {
        -Cell currentCell
        +moveTo(cell)
    }

    MazeBuilder <|.. TextFileMazeBuilder
    PathFindingStrategy <|.. BFSStrategy
    PathFindingStrategy <|.. DFSStrategy
    PathFindingStrategy <|.. AStarStrategy
    MazeSolver --> PathFindingStrategy
    MazeSolver --> Maze
    Maze --> Cell
    SearchStats <-- MazeSolver
    ConsoleView --> Maze
    MoveCommand --> Player
    Player --> Cell