1
0
forked from UNN/2026-rff_mp
2026-rff_mp/BolonkinNM/docs/report.md

250 lines
13 KiB
Markdown
Raw Normal View History

2026-05-24 16:39:37 +00:00
# Отчёт по работе «Поиск выхода из лабиринта»
## 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
2026-05-23 15:45:47 +00:00
```
2026-05-24 16:39:37 +00:00
## 5. Ключевые классы и их роль
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### Cell
Хранит координаты клетки и её тип. Позволяет быстро проверять, является ли клетка проходимой.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### Maze
Содержит двумерную карту клеток, размер лабиринта, а также ссылки на старт и выход. Даёт доступ к соседним клеткам по четырём направлениям.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### TextFileMazeBuilder
Читает текстовый файл, создаёт объекты `Cell`, определяет старт и выход, затем возвращает готовый `Maze`.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### BFSStrategy
Ищет кратчайший путь по числу шагов. Подходит для случая, когда все переходы одинаковой стоимости.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### DFSStrategy
Быстро исследует пространство, но не гарантирует кратчайший путь. Полезен как сравнительный алгоритм.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### AStarStrategy
Использует эвристику Манхэттенского расстояния. Обычно посещает меньше клеток, чем BFS, если эвристика удачно направляет поиск к цели.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### MazeSolver
Оркестратор, который хранит лабиринт и текущую стратегию. Вызывает поиск, измеряет время и собирает статистику.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### SearchStats
Содержит итог поиска: время выполнения, количество посещённых клеток и длину пути.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### ConsoleView
Реализует наблюдателя и умеет выводить лабиринт и найденный путь в консоль.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### MoveCommand
Оформляет ход игрока как объект-команду. Поддерживает отмену последнего перемещения.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
## 6. Экспериментальная часть
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### 6.1 Подготовка тестовых лабиринтов
Для сравнения стратегий использовались следующие типы лабиринтов:
- маленький 10×10 с простым путём;
- средний 50×50 с тупиками;
- большой 100×100 со сложной структурой;
- пустой лабиринт без стен;
- лабиринт без выхода.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### 6.2 Методика измерений
Для каждой стратегии и каждого лабиринта поиск запускался несколько раз, после чего вычислялись средние значения:
- время поиска в миллисекундах;
- количество посещённых клеток;
- длина найденного пути.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
Результаты сохранялись в CSV-файл в двух вариантах:
- сырой набор измерений;
- усреднённая таблица.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
## 7. Анализ эффективности
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### BFS
BFS гарантирует кратчайший путь по числу шагов, если все переходы имеют одинаковую стоимость. На простых и пустых лабиринтах работает стабильно и предсказуемо. Минус — может посещать много клеток, особенно на больших лабиринтах.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### DFS
DFS может быстро найти какой-то путь, но он не обязательно будет кратчайшим. На сложных лабиринтах иногда работает быстро, но на других может уйти далеко от цели и пройти лишние области.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### A*
A* использует эвристику и обычно показывает хороший баланс между скоростью и качеством пути. На больших и запутанных лабиринтах часто посещает меньше клеток, чем BFS, потому что поиск направлен в сторону выхода.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### Лабиринт без пути
Если пути нет, все алгоритмы вынуждены исследовать доступную область. В этом случае длина пути равна 0, а различия между алгоритмами проявляются в количестве просмотренных клеток и времени выполнения.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
### Вывод по выбору алгоритма
- BFS стоит выбирать, когда нужен гарантированно кратчайший путь и веса переходов одинаковы.
- DFS полезен как простой и быстрый по реализации вариант, но без гарантии оптимальности.
- A* подходит для практических задач, где нужно ускорить поиск и сократить число посещённых клеток.
- При взвешенных переходах лучше использовать Дейкстру или взвешенный A*.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
## 8. Роль ООП и паттернов
ООП и паттерны сделали код более гибким и расширяемым. Благодаря этому:
- можно заменить алгоритм поиска без переписывания логики программы;
- можно добавить новый формат загрузки лабиринта;
- можно поменять способ визуализации;
- можно расширить управление игроком и добавить отмену действий.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
Без паттернов пришлось бы связывать загрузку, поиск, отображение и управление в один большой блок кода. Это усложнило бы отладку и дальнейшие изменения.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
## 9. Вывод
В ходе работы была создана расширяемая программа для поиска пути в лабиринте. Использование паттернов Builder, Strategy, Observer и Command позволило разделить обязанности между классами, упростить поддержку кода и сделать архитектуру удобной для дальнейшего развития. Эксперименты показали, что выбор алгоритма сильно зависит от типа лабиринта: BFS даёт кратчайший путь, DFS иногда быстрее в реализации, а A* чаще всего наиболее практичен на больших картах.
2026-05-23 15:45:47 +00:00
2026-05-24 16:39:37 +00:00
## 10. Приложения
- Листинги ключевых классов.
- CSV-файлы с результатами экспериментов.
- Графики сравнений.
- Файлы с тестовыми лабиринтами.