130 lines
5.1 KiB
Plaintext
130 lines
5.1 KiB
Plaintext
{
|
||
"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
|
||
}
|