# Отчёт по лабораторной работе: Алгоритмы поиска пути в лабиринте

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

Разработка программы для загрузки лабиринта из текстового файла, реализации трёх алгоритмов поиска пути (BFS, DFS, A\*) и проведения экспериментального сравнения их эффективности на лабиринтах различной сложности.

## 2. Структура программы

Программа написана на Python 3 и состоит из следующих основных классов:

- `GridPoint` – представление клетки лабиринта (координаты, проходимость, флаги старта/выхода);
- `Labyrinth` – модель лабиринта (сетка клеток, методы получения соседей);
- `TextMazeLoader` – загрузка лабиринта из файла с символами `#` (стена), `S` (старт), `E` (выход);
- `SearchAlgorithm` (и наследники `BreadthFirst`, `DepthFirst`, `AStar`) – реализация алгоритмов поиска;
- `LabyrinthSolver` – класс-оркестратор, позволяющий сменить стратегию и измеряющий время выполнения;
- `Player`, `Command`, `MoveCommand`, `InteractiveView` – для интерактивного режима с отменой ходов;
- функции `run_experiment` и `generate_plots` – для многократных запусков и построения графиков.

## 3. Описание алгоритмов

### 3.1 BFS (поиск в ширину)
Использует очередь. Гарантирует нахождение кратчайшего пути (по числу шагов). Обходит клетки в порядке увеличения расстояния от старта.

### 3.2 DFS (поиск в глубину)
Использует стек. Идёт «вглубь» по одному пути, не гарантирует кратчайший путь. Обычно быстрее по времени и памяти на больших лабиринтах.

### 3.3 A* (звездочка)
Использует приоритетную очередь и эвристику (манхэттенское расстояние). Оценивает клетку по формуле `f = g + h`, где `g` – пройденное расстояние, `h` – эвристика. Находит оптимальный путь, если эвристика допустима.

## 4. Методика эксперимента

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

Тестовые лабиринты:

| Название | Размер | Описание |
|----------|--------|-----------|
| Small 10x6 | 10×6 | Простой лабиринт с извилистым коридором |
| Medium 10x10 | 10×10 | Лабиринт среднего размера с несколькими тупиками |
| Large 20x20 | 20×20 | Большой запутанный лабиринт |
| Empty 15x15 | 15×15 | Пустой лабиринт без стен (прямая линия от S до E) |
| No exit 10x10 | 10×10 | Лабиринт без буквы E (путь отсутствует) |

## 5. Результаты экспериментов

| Лабиринт       | Алгоритм | Время, мс | Посещено клеток | Длина пути |
|----------------|----------|-----------|-----------------|------------|
| Small 10x6     | BFS      | 0.057     | 25              | 16         |
| Small 10x6     | DFS      | 0.057     | 24              | 16         |
| Small 10x6     | A*       | 0.048     | 23              | 16         |
| Medium 10x10   | BFS      | 0.048     | 47              | 16         |
| Medium 10x10   | DFS      | 0.035     | 44              | 30         |
| Medium 10x10   | A*       | 0.098     | 47              | 16         |
| Large 20x20    | BFS      | 0.099     | 100             | 36         |
| Large 20x20    | DFS      | 0.070     | 75              | 68         |
| Large 20x20    | A*       | 0.165     | 85              | 36         |
| Empty 15x15    | BFS      | 0.133     | 133             | 17         |
| Empty 15x15    | DFS      | 0.114     | 161             | 89         |
| Empty 15x15    | A*       | 0.154     | 65              | 17         |
| No exit 10x10  | BFS      | 0.044     | 25              | 0          |
| No exit 10x10  | DFS      | 0.059     | 25              | 0          |
| No exit 10x10  | A*       | 0.046     | 25              | 0          |

## 6. Анализ результатов

### 6.1. Нахождение кратчайшего пути
- **BFS** и **A*** нашли оптимальные пути во всех лабиринтах, где выход существовал (длина пути совпадает для них в каждом случае).
- **DFS** в лабиринтах Medium, Large и Empty дал существенно более длинные пути (30 против 16, 68 против 36, 89 против 17), что характерно для глубинного обхода без эвристики.

### 6.2. Время выполнения
- На малых лабиринтах все алгоритмы работают сопоставимо (0.035–0.099 мс).
- На лабиринте Large 20×20 BFS выполнился за 0.099 мс, A* – 0.165 мс (медленнее из-за сложности поддержки очереди с приоритетом), DFS – быстрее всех (0.070 мс).
- В пустом лабиринте BFS и A* обошли почти все клетки (133 и 65 посещённых соответственно), но A* за счёт эвристики посетил вдвое меньше клеток, хотя время оказалось чуть выше, чем у BFS (0.154 против 0.133 мс). Это объясняется накладными расходами на вычисление эвристики и управление кучей.

### 6.3. Количество посещённых клеток
- **A*** показал лучшую эффективность в пустом лабиринте (65 посещённых против 133 у BFS и 161 у DFS). В лабиринтах со стенами разница не столь заметна, но A* почти всегда посещал меньше клеток, чем BFS.
- **DFS** в среднем посещает меньше клеток, чем BFS, но при этом путь часто неоптимален.
- **BFS** вынужден обходить всю область равных расстояний, поэтому посещённых клеток обычно больше.

### 6.4. Поведение при отсутствии выхода
Все алгоритмы корректно завершились, вернув пустой путь (длина 0). В лабиринте без выхода BFS, DFS и A* посетили 25 клеток – это все доступные клетки.

## 7. Выводы

1. **BFS** надёжен для поиска кратчайшего пути, но может быть медленнее на больших открытых пространствах из-за широкого обхода.
2. **DFS** – самый быстрый по времени и экономный по памяти, но не гарантирует оптимальность пути. Его применение оправдано, когда любой путь подходит.
3. **A*** демонстрирует лучший баланс: находит кратчайший путь и при этом посещает меньше клеток, чем BFS. Небольшое замедление на сложных лабиринтах компенсируется меньшим числом обработанных клеток.
4. Программа успешно справляется с лабиринтами разного размера и конфигурации, включая отсутствие выхода.
5. Интерактивный режим с отменой ходов (паттерн Command) и выбором алгоритма (паттерн Strategy) реализован и работает корректно.
