forked from UNN/2026-rff_mp
Compare commits
24 Commits
1-st-exerc
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 82e988c965 | |||
| 58daf860ed | |||
| 566d89fda2 | |||
| c7229154ca | |||
| 6e4ae1835b | |||
|
|
25341dc814 | ||
| fe9ce65eb2 | |||
| 405d1e583b | |||
| 74807f5514 | |||
| 3a251f06c7 | |||
| e4c7e2d97a | |||
|
|
7e84caffc4 | ||
| 84e5d1e763 | |||
| f5b0fec46f | |||
| e4423a3be8 | |||
| eeb28d8b6a | |||
| b3e4b6149e | |||
| c98c8a472b | |||
|
|
666e6ecd41 | ||
| 062d3b983e | |||
| 197c266cd4 | |||
| b874ac28aa | |||
| ff1063d866 | |||
| 3e175eb367 |
0
BoriskovaDV/428.md
Normal file
0
BoriskovaDV/428.md
Normal file
0
KislyuninED/428.md
Normal file
0
KislyuninED/428.md
Normal file
1
MalkinMV/428b.md
Normal file
1
MalkinMV/428b.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
428b
|
||||||
183
README.md
183
README.md
|
|
@ -197,3 +197,186 @@ with open("results.csv", "w", newline="") as f:
|
||||||
- Как удаление работает в каждой структуре.
|
- Как удаление работает в каждой структуре.
|
||||||
|
|
||||||
* Вывод должен содержать ответ на вопрос: какую структуру и для каких задач (частые вставки, частый поиск, необходимость получать данные в порядке) стоит выбирать в реальной жизни.*
|
* Вывод должен содержать ответ на вопрос: какую структуру и для каких задач (частые вставки, частый поиск, необходимость получать данные в порядке) стоит выбирать в реальной жизни.*
|
||||||
|
|
||||||
|
## Задание: Поиск выхода из лабиринта (объектно-ориентированная реализация с паттернами)
|
||||||
|
|
||||||
|
### Цель работы
|
||||||
|
Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов. В ходе работы необходимо применить минимум 3 паттерна проектирования из списка GoF, обосновать их выбор и продемонстрировать преимущества такой архитектуры.
|
||||||
|
|
||||||
|
### Общая схема приложения (пример)
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
classDiagram
|
||||||
|
class Maze {
|
||||||
|
-Cell[] cells
|
||||||
|
-int width, height
|
||||||
|
-Cell start
|
||||||
|
-Cell exit
|
||||||
|
+getCell(x,y): Cell
|
||||||
|
+getNeighbors(cell): List~Cell~
|
||||||
|
}
|
||||||
|
|
||||||
|
class Cell {
|
||||||
|
-int x, y
|
||||||
|
-bool isWall
|
||||||
|
-bool isStart
|
||||||
|
-bool isExit
|
||||||
|
+isPassable(): bool
|
||||||
|
}
|
||||||
|
|
||||||
|
class MazeBuilder {
|
||||||
|
<<interface>>
|
||||||
|
+buildFromFile(filename): Maze
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextFileMazeBuilder {
|
||||||
|
+buildFromFile(filename): Maze
|
||||||
|
}
|
||||||
|
|
||||||
|
class PathFindingStrategy {
|
||||||
|
<<interface>>
|
||||||
|
+findPath(maze, start, exit): List~Cell~
|
||||||
|
}
|
||||||
|
|
||||||
|
class BFSStrategy
|
||||||
|
class DFSStrategy
|
||||||
|
class AStarStrategy
|
||||||
|
class DijkstraStrategy
|
||||||
|
|
||||||
|
class SearchStats {
|
||||||
|
+timeMs: float
|
||||||
|
+visitedCells: int
|
||||||
|
+pathLength: int
|
||||||
|
}
|
||||||
|
|
||||||
|
class MazeSolver {
|
||||||
|
-Maze maze
|
||||||
|
-PathFindingStrategy strategy
|
||||||
|
+setStrategy(strategy)
|
||||||
|
+solve(): SearchStats
|
||||||
|
}
|
||||||
|
|
||||||
|
class Command {
|
||||||
|
<<interface>>
|
||||||
|
+execute()
|
||||||
|
+undo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveCommand {
|
||||||
|
-Player player
|
||||||
|
-Direction dir
|
||||||
|
-Cell previousCell
|
||||||
|
+execute()
|
||||||
|
+undo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Player {
|
||||||
|
-Cell currentCell
|
||||||
|
+moveTo(cell)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Observer {
|
||||||
|
<<interface>>
|
||||||
|
+update(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConsoleView {
|
||||||
|
+update(event)
|
||||||
|
+render(maze, player, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
MazeBuilder <|.. TextFileMazeBuilder
|
||||||
|
MazeBuilder --> Maze : creates
|
||||||
|
PathFindingStrategy <|.. BFSStrategy
|
||||||
|
PathFindingStrategy <|.. DFSStrategy
|
||||||
|
PathFindingStrategy <|.. AStarStrategy
|
||||||
|
PathFindingStrategy <|.. DijkstraStrategy
|
||||||
|
MazeSolver --> PathFindingStrategy : uses
|
||||||
|
MazeSolver --> Maze : uses
|
||||||
|
Command <|.. MoveCommand
|
||||||
|
MoveCommand --> Player
|
||||||
|
Player --> Cell
|
||||||
|
Observer <|.. ConsoleView
|
||||||
|
MazeSolver --> Observer : notifies
|
||||||
|
```
|
||||||
|
|
||||||
|
### Выполнение
|
||||||
|
|
||||||
|
#### Этап 1. Модель лабиринта (без паттернов, просто классы)
|
||||||
|
**Задача:** Создать классы `Cell` и `Maze`, которые представляют карту лабиринта.
|
||||||
|
- `Cell` хранит координаты (x, y), флаги `isWall`, `isStart`, `isExit`, метод `isPassable()` (возвращает `True` для прохода, если не стена).
|
||||||
|
- `Maze` хранит двумерный массив клеток, ширину, высоту, ссылки на стартовую и выходную клетку. Методы: `getCell(x, y)`, `getNeighbors(cell)` – возвращает список соседних проходимых клеток (вверх, вниз, влево, вправо, если в пределах границ и не стена).
|
||||||
|
|
||||||
|
**Результат:** Лабиринт можно создать вручную в коде, но загрузку пока не делаем.
|
||||||
|
|
||||||
|
#### Этап 2. Загрузка лабиринта из файла – применение паттерна **Builder**
|
||||||
|
**Задача:** Реализовать загрузку лабиринта из текстового файла, где `#` – стена, ` ` (пробел) – проход, `S` – старт, `E` – выход.
|
||||||
|
- Создать интерфейс `MazeBuilder` с методом `buildFromFile(filename)`.
|
||||||
|
- Реализовать класс `TextFileMazeBuilder`, который читает файл, парсит символы, создаёт объекты `Cell`, задаёт координаты и флаги, после чего возвращает готовый `Maze`.
|
||||||
|
|
||||||
|
Процесс построения лабиринта сложный (парсинг, валидация, установка старта/выхода). Builder скрывает детали создания от клиента. В будущем можно легко добавить другой формат (например, JSON или бинарный) через новую реализацию `MazeBuilder`.
|
||||||
|
|
||||||
|
#### Этап 3. Стратегии поиска пути – паттерн **Strategy**
|
||||||
|
**Задача:** Реализовать семейство алгоритмов поиска пути от старта до выхода.
|
||||||
|
- Создать интерфейс `PathFindingStrategy` с методом `findPath(maze, start, exit)`, возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет.
|
||||||
|
- Реализовать минимум 3 стратегии:
|
||||||
|
- **BFS** (поиск в ширину) – гарантирует кратчайший путь по количеству шагов.
|
||||||
|
- **DFS** (поиск в глубину) – быстрый, но не обязательно кратчайший.
|
||||||
|
- **A*** (с эвристикой, например, манхэттенское расстояние) – компромисс между скоростью и оптимальностью.
|
||||||
|
- (Опционально) **Дейкстра** – полезна для взвешенных лабиринтов, но в базовом варианте все шаги имеют вес 1, тогда она совпадает с BFS.
|
||||||
|
|
||||||
|
Каждая стратегия возвращает путь. Для BFS/DFS используйте очередь/стек, для A* – приоритетную очередь (heapq). Важно: алгоритмы не должны модифицировать сам лабиринт, только читать состояние клеток.
|
||||||
|
|
||||||
|
Strategy позволяет легко переключать алгоритмы во время выполнения, не меняя код остальной программы. Новый алгоритм можно добавить, реализовав интерфейс.
|
||||||
|
|
||||||
|
#### Этап 4. Класс-оркестратор – **MazeSolver** (использует Strategy)
|
||||||
|
**Задача:** Создать класс, который принимает лабиринт и стратегию, выполняет поиск и собирает статистику.
|
||||||
|
- `MazeSolver` содержит поля `maze` и `strategy`.
|
||||||
|
- Метод `setStrategy(strategy)` для динамической смены алгоритма.
|
||||||
|
- Метод `solve()` вызывает `strategy.findPath(...)` и возвращает объект `SearchStats` (время выполнения в миллисекундах, количество посещённых клеток, длина найденного пути).
|
||||||
|
- Для замера времени используйте `time.perf_counter()` до и после вызова стратегии.
|
||||||
|
|
||||||
|
#### Этап 5. Визуализация и пошаговое управление – паттерны **Observer** и **Command** (по желанию)
|
||||||
|
**5.1. Наблюдатель (Observer)** – обновление консольного интерфейса.
|
||||||
|
- Создать интерфейс `Observer` с методом `update(event)`, где `event` может быть строкой или объектом с типом события (`"path_found"`, `"move"`, `"maze_loaded"`).
|
||||||
|
- Реализовать класс `ConsoleView`, который отображает лабиринт, текущее положение игрока (если реализован пошаговый режим) и найденный путь. Метод `render(maze, player_position, path)` рисует карту в консоли.
|
||||||
|
- `MazeSolver` (или отдельный контроллер) может иметь список наблюдателей и уведомлять их при изменении состояния.
|
||||||
|
|
||||||
|
**5.2. Команда (Command)** – для пошагового перемещения игрока по найденному пути (или ручного управления).
|
||||||
|
- Создать интерфейс `Command` с методами `execute()` и `undo()`.
|
||||||
|
- Реализовать `MoveCommand`, который принимает игрока (`Player`), направление и изменяет его позицию, сохраняя предыдущую для отмены.
|
||||||
|
- Создать класс `Player`, хранящий текущую клетку.
|
||||||
|
- Консольное меню позволяет вводить команды (W/A/S/D), выполнять `MoveCommand`, при необходимости отменять последний ход (Ctrl+Z). Это опционально, но очень наглядно демонстрирует паттерн.
|
||||||
|
|
||||||
|
*Observer можно реализовать только для вывода сообщений о начале/конце поиска, а Command – для демонстрации undo при ручном исследовании лабиринта.*
|
||||||
|
|
||||||
|
#### Этап 6. Экспериментальная часть (аналогично заданию со структурами данных)
|
||||||
|
**Задача:** Сравнить эффективность реализованных стратегий на лабиринтах разной сложности.
|
||||||
|
1. **Подготовка тестовых лабиринтов:**
|
||||||
|
- Маленький (10×10) с простым путём.
|
||||||
|
- Средний (50×50) с тупиками.
|
||||||
|
- Большой (100×100) с запутанной структурой.
|
||||||
|
- «Пустой» лабиринт (без стен) – для демонстрации максимальной производительности.
|
||||||
|
- «Без выхода» – чтобы проверить обработку отсутствия пути.
|
||||||
|
2. **Замеры:**
|
||||||
|
- Для каждого лабиринта и каждой стратегии запустить `solve()` 5–10 раз, усреднить время, количество посещённых клеток, длину пути.
|
||||||
|
- Записать результаты в CSV: `лабиринт,стратегия,время_мс,посещено_клеток,длина_пути`.
|
||||||
|
3. **Анализ:**
|
||||||
|
- Построить графики для каждого лабиринта.
|
||||||
|
- Проанализировать и написать выводы по итогам (эффективность того или иного алгоритма в разных случаях).
|
||||||
|
|
||||||
|
4. **Дополнительное задание:** Реализовать взвешенные клетки (например, болото – вес 3, песок – вес 2, асфальт – вес 1) и сравнить Дейкстру с A* на взвешенном графе.
|
||||||
|
|
||||||
|
#### Этап 7. Отчёт
|
||||||
|
**Структура отчёта:**
|
||||||
|
1. Описание задачи и выбранных паттернов (с диаграммой классов из Mermaid).
|
||||||
|
2. Листинги ключевых классов (можно выборочно) или ссылка на репозиторий.
|
||||||
|
3. Результаты экспериментов (таблицы, графики).
|
||||||
|
4. Анализ эффективности алгоритмов и применимости паттернов.
|
||||||
|
5. Выводы: как ООП и паттерны помогли сделать код гибким и расширяемым. Что было бы сложно изменить без них.
|
||||||
|
|
||||||
|
### Советы
|
||||||
|
- Для A* самая простая эвристика: `abs(x1 - x2) + abs(y1 - y2)`.
|
||||||
|
- При поиске пути надо хранить предшественников (`parent` для каждой посещённой клетки), чтобы восстановить путь.
|
||||||
|
- Для BFS/DFS используй `deque` (очередь) и `list` (стек).
|
||||||
|
- Визуализацию в консоли можно сделать с помощью `os.system('cls' if os.name == 'nt' else 'clear')` для перерисовки.
|
||||||
|
|
|
||||||
0
SavelevMI/428.md
Normal file
0
SavelevMI/428.md
Normal file
0
Smirnovvs/428.txt
Normal file
0
Smirnovvs/428.txt
Normal file
0
VarnakovAA/429.md
Normal file
0
VarnakovAA/429.md
Normal file
0
dyachenkoas/428
Normal file
0
dyachenkoas/428
Normal file
0
kalinovskiymi/428
Normal file
0
kalinovskiymi/428
Normal file
6
osipovamd/428.md
Normal file
6
osipovamd/428.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{\rtf1\ansi\ansicpg1251\cocoartf2869
|
||||||
|
\cocoatextscaling0\cocoaplatform0{\fonttbl}
|
||||||
|
{\colortbl;\red255\green255\blue255;}
|
||||||
|
{\*\expandedcolortbl;;}
|
||||||
|
\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
||||||
|
}
|
||||||
1
victorovaas/429
Normal file
1
victorovaas/429
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<EFBFBD>¥¦¨¬ ¢כ¢®₪ ×®¬ ₪ ם×א (ECHO) ¢×«מח¥.
|
||||||
Loading…
Reference in New Issue
Block a user