perf(map): A* на мин-куче, findPathToNeighbor — один многоцелевой прогон
О-3. Открытый список искался линейным сканом (O(n) на узел, O(n^2) на путь);
findPathToNeighbor запускал до 8 полных A* по очереди.

- OpenHeap: мин-куча по f, O(log n) на push/pop; tie-break по seq (порядок
  вставки) — обход остался детерминированным, как с линейным сканом.
- Общий каркас astar(grid, start, dirs, isGoal, h): цель и эвристика —
  параметры; findPath и findPathToNeighbor без дублирования цикла.
- findPathToNeighbor: все 8 соседей цели — цели одного прогона, эвристика —
  минимум манхэттена по целям (админисибельна, первый popped-goal оптимален).
- Соседство DIRS4/DIRS8 — константы модуля (было: spread каждый узел).

Тесты pathfinding — без правок ожиданий (11 старых зелёные), +2: выбор
ближайшего из 8 соседей за один прогон, старт-сосед цели — пустой путь.
Perf (swiftshader): routeMs 1-4 мс — в пределах baseline (маршруты короткие,
выиграш растёт с длиной пути).

Co-Authored-By: Claude Code <noreply@anthropic.com>
1 parent 202599e commit 518deb7ac7ff46f0d29f7a06baab9df3eeb64c87
@root root authored 7 hours ago
Showing 3 changed files
View
docs/engine/maps.md
View
packages/engine/src/map/__tests__/pathfinding.test.ts
View
packages/engine/src/map/pathfinding.ts