6.9 KiB
6.9 KiB
Структура:
- Описание задачи и выбранных паттернов (с диаграммой классов из Mermaid).
- Листинги ключевых классов (можно выборочно) или ссылка на репозиторий.
- Результаты экспериментов (таблицы, графики).
- Анализ эффективности алгоритмов и применимости паттернов.
- Выводы: как ООП и паттерны помогли сделать код гибким и расширяемым. Что было бы сложно изменить без них.
Выводы:
1) Описание задачи и выбранных паттернов
Диаграмма классов
| Паттерн | Реализация в проекте | Обоснование |
|---|---|---|
| Builder | MazeBuilders (интерфейс)TextFileMazeBuilder |
Создание лабиринта из текстового файла. Позволяя легко добавить другие форматы без изменения Maze |
| Strategy | PathFindingStrategy (интерфейс)BFSDFSAStar |
Алгоритмы поиска пути взаимозаменяемы Strategy позволяет переключать их через MazeSolver.setStrategy() и добавлять новые (например, Дейкстра) без изменения кода |
| Observer | Observer (интерфейс)ConsoleView |
Отделяет визуализацию от логики поискаMazeSolver может уведомлять подписчиков о событиях (начало/конец поиска), а ConsoleView реагирует на нихЛегко добавить другие виды отображения (GUI, лог-файл) |
| Command | Command (интерфейс)Observer (интерфейс)MoveCommandConsoleView |
Обеспечивает пошаговое наблюдение и отслеживание с возможностью отмены |
2) Листинги ключевых классов:
Core:
class Cell:
def __init__(self, x = 0, y = 0, isWall = False, isStart = False, isExit = False):
self.x = x
self.y = y
self.isWall = isWall
self.isStart = isStart
self.isExit = isExit
# Возращает True, если посаседству стена
def isPassable(self):
return not self.isWall
class Maze:
def __init__(self, grid, start = None, exit = None):
self.grid = grid
self.start = start
self.exit = exit
self.height = len(grid)
self.width = len(grid[0]) if grid else 0
# Создание новой ячейки
def getCell(self, x, y):
if 0 <= x < self.height and 0 <= y < self.width:
return self.grid[x][y]
return None
# Ищет соседние проходимые клетки
def getNeighbors(self, cell):
directions = [(0,1),(1,0),(0,-1),(-1,0)]
result = []
for dx, dy in directions:
nx, ny = cell.x + dx, cell.y + dy
neighbor = self.getCell(nx, ny)
if neighbor and neighbor.isPassable():
result.append(neighbor)
return result
Builder:
from abc import ABC, abstractmethod
class MazeBuilders(ABC):
@abstractmethod
def build_from_file(self, filename):
pass
from Core.Cell import Cell
from Core.Maze import Maze
from Builder.BuilderInterface import MazeBuilders
class TextFileMazeBuilder(MazeBuilders):
def build_from_file(self, filename):
grid = []
start = None
exit = None
with open(filename, "r", encoding="utf-8") as f:
lines = [line.rstrip("\n") for line in f]
for y, line in enumerate(lines):
row = []
for x, ch in enumerate(line):
cell = Cell(x, y, isWall = (ch == "#"), isStart = (ch == "S"), isExit = (ch == "E"))
if (ch == "S"):
start = cell
if (ch == "E"):
exit = cell
row.append(cell)
grid.append(row)
return Maze(grid, start, exit)
3) Результаты экспериментов:
График созданный на основе 5 попыток замеров и их усреднения
4) Анализ эффективности алгоритмов и применимости паттернов:
- BFS
Работает медленно и обходит гораздо больше клеток, но гарантирует кратчайший маршерут - DFS Работает быстро, но за это приходиться платить не самыми оптимальными путями и количеством обходимых маршерутов(из-за чего растёт время работы)
- A** Является золотой серединой между DFS и BFS ищет маршерут хуже BFS, но лучше чем DFS, обратная зависимость наблюдается в измерении времени
5)Выводы: как ООП и паттерны помогли сделать код гибким и расширяемым? Что было бы сложно изменить без них?
ООП и паттерны помогли систематизировать код и написать единый код для 3 структур, так же легко масштабировать проект, за счёт единых функций применимых для разных алгоритмов Сложно было бы изменить файлы лабиринтов, алгоритмы поиска пути,

