solverMaze_solver

This commit is contained in:
Veronika Minina 2026-05-17 14:56:59 +03:00
parent d8eebad0a5
commit af4dae63f5

View File

@ -0,0 +1,129 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "1ef30a86-b41f-49eb-84c3-5d425614cbdd",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"from typing import List, Optional\n",
"from dataclasses import dataclass, field\n",
"from modelsMaze import Maze\n",
"from modelsCell import Cell\n",
"from strategiesPathfinding_strategy import PathFindingStrategy\n",
"from visualizationObserver import Observer\n",
"\n",
"@dataclass\n",
"class SearchStats:\n",
" \"\"\"Статистика поиска.\"\"\"\n",
" algorithm_name: str\n",
" time_ms: float\n",
" visited_cells: int\n",
" path_length: int\n",
" path_found: bool = True\n",
"\n",
"class MazeSolver:\n",
" \"\"\"\n",
" Оркестратор для решения лабиринта.\n",
" Использует паттерн Strategy для алгоритмов поиска.\n",
" Поддерживает Observer для уведомлений.\n",
" \"\"\"\n",
" \n",
" def __init__(self, maze: Maze, strategy: Optional[PathFindingStrategy] = None):\n",
" self.maze = maze\n",
" self._strategy = strategy\n",
" self._observers: List[Observer] = []\n",
" self._last_path: List[Cell] = []\n",
" self._last_stats: Optional[SearchStats] = None\n",
" \n",
" def set_strategy(self, strategy: PathFindingStrategy) -> None:\n",
" \"\"\"Динамическая смена стратегии.\"\"\"\n",
" self._strategy = strategy\n",
" self._notify(f\"Стратегия изменена на {strategy.name}\")\n",
" \n",
" def attach(self, observer: Observer) -> None:\n",
" \"\"\"Подписать наблюдателя.\"\"\"\n",
" self._observers.append(observer)\n",
" \n",
" def detach(self, observer: Observer) -> None:\n",
" \"\"\"Отписать наблюдателя.\"\"\"\n",
" if observer in self._observers:\n",
" self._observers.remove(observer)\n",
" \n",
" def _notify(self, event: str) -> None:\n",
" \"\"\"Уведомить всех наблюдателей.\"\"\"\n",
" for observer in self._observers:\n",
" observer.update(event)\n",
" \n",
" def solve(self) -> List[Cell]:\n",
" \"\"\"\n",
" Выполнить поиск пути с текущей стратегией.\n",
" Возвращает путь (список клеток).\n",
" \"\"\"\n",
" if self._strategy is None:\n",
" raise ValueError(\"Стратегия не установлена\")\n",
" \n",
" if not self.maze.start_cell or not self.maze.exit_cell:\n",
" raise ValueError(\"Лабиринт не имеет старта или выхода\")\n",
" \n",
" self._notify(f\"Начинаем поиск пути с использованием {self._strategy.name}...\")\n",
" \n",
" start_time = time.perf_counter()\n",
" path = self._strategy.find_path(self.maze, self.maze.start_cell, self.maze.exit_cell)\n",
" end_time = time.perf_counter()\n",
" \n",
" time_ms = (end_time - start_time) * 1000\n",
" \n",
" # Получаем количество посещённых клеток из стратегии\n",
" visited_cells = getattr(self._strategy, 'last_visited_count', 0)\n",
" \n",
" self._last_path = path\n",
" self._last_stats = SearchStats(\n",
" algorithm_name=self._strategy.name,\n",
" time_ms=time_ms,\n",
" visited_cells=visited_cells,\n",
" path_length=len(path),\n",
" path_found=len(path) > 0\n",
" )\n",
" \n",
" if path:\n",
" self._notify(f\"Путь найден! Длина: {len(path)}, время: {time_ms:.2f} мс, посещено: {visited_cells}\")\n",
" else:\n",
" self._notify(f\"Путь не найден! Время: {time_ms:.2f} мс, посещено: {visited_cells}\")\n",
" \n",
" return path\n",
" \n",
" @property\n",
" def last_path(self) -> List[Cell]:\n",
" return self._last_path\n",
" \n",
" @property\n",
" def last_stats(self) -> Optional[SearchStats]:\n",
" return self._last_stats"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:base] *",
"language": "python",
"name": "conda-base-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}