chore: восстановление репозитория из снапшота v0.3.1
Прежняя git-история утрачена при переносе проекта на машину владельца (снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной истории. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
commit
1c85091186
184 changed files with 33303 additions and 0 deletions
81
docs/plans/plan-phase-4.md
Normal file
81
docs/plans/plan-phase-4.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# План фазы 4: этап 4 — ИИ ур. 4–6, MCTS + Web Worker (packages/ai)
|
||||
|
||||
Обновлено: 2026-08-05 | Статус: реализовано (гейты зелёные, 118 тестов)
|
||||
|
||||
## Критические долги (реестр — в начале, III.5)
|
||||
|
||||
- Нет.
|
||||
|
||||
## Ключевые решения (не пере-решать)
|
||||
|
||||
- MCTS-движок — чистый модуль в packages/ai (без воркер-API); воркер — тонкая
|
||||
обёртка worker.ts с абстракцией порта. Однопоточно (без SharedArrayBuffer —
|
||||
COOP/COEP на шареде не гарантированы).
|
||||
- Плейаут — «лёгкая» политика, НЕ chooseMove этапа 3: тот сканирует всю доску
|
||||
через applyMove на каждый ход (~мс на ход) — в плейауте непозволительно.
|
||||
Лёгкая: дешёвая реакция на атари у последнего хода + случайные точки с
|
||||
фильтром своего глаза и лимитом попыток. Компромисс силы ради бюджета —
|
||||
зафиксирован здесь.
|
||||
- Бюджеты: {4: 300, 5: 800, 6: 1500} мс; ур.5 — дефолт между уровнями (спека
|
||||
задаёт только крайние) — записано в контракте.
|
||||
- Сериализация позиции в протоколе — списком ходов от пустой доски (воркер
|
||||
пересобирает и валидирует через applyMove), не снапшотом grid.
|
||||
- cancel → воркер отвечает result с лучшим найденным, не молчит и не error.
|
||||
- maxSimulations — override для детерминированных тестов.
|
||||
- Контракт — docs/INTERFACES.md (зафиксирован 2026-08-05 до кода).
|
||||
|
||||
## Объём этапа 4
|
||||
|
||||
1. packages/ai/src/mcts.ts — дерево UCT (c=1.4), ленивая экспансия, лёгкий
|
||||
плейаут, оценка scorePosition с komi, бюджет clock/shouldStop/maxSimulations,
|
||||
topMoves (до 3) для подсказки этапа 5.
|
||||
2. packages/ai/src/worker-protocol.ts — типы WorkerRequest/WorkerResponse +
|
||||
пересборка BoardState из списка ходов (валидация, error при нелегальном).
|
||||
3. packages/ai/src/worker.ts — тонкая обёртка порта (onmessage → choose →
|
||||
result/error; cancel → result с лучшим найденным).
|
||||
4. index.ts — экспорты движка и протокола.
|
||||
|
||||
## Тесты (гейт приёмки этапа)
|
||||
|
||||
- Детерминизм: maxSimulations=50 + фиксированный seed → идентичный move и
|
||||
topMoves в двух прогонах на одной позиции.
|
||||
- Легальность: ход MCTS легален на случайных позициях (запиненные seed'ы,
|
||||
9×9 и 13×13); pass возвращается, только если легальных постановок нет или
|
||||
он лучший по визитам (в любом случае applyMove не падает).
|
||||
- Бюджет: фейк-clock (счётчик now()) — остановка по deadline; shouldStop() —
|
||||
остановка после N симуляций, ответ всегда с легальным ходом.
|
||||
- Качество (мягкий): MCTS ур.4 с maxSimulations=200 забирает группу в атари
|
||||
на сконструированной позиции (где эвристика ур.1 с rng 0.99 пропускает) —
|
||||
не эталон силы, а smoke «дерево реально ищет».
|
||||
- Протокол: фейк-порт — choose → result с тем же requestId; нелегальный список
|
||||
ходов → error; cancel активного → result, не error; cancel чужого id →
|
||||
без эффекта.
|
||||
- Полная партия 9×9 бот(MCTS ур.4, maxSimulations=100) против бота ур.3 —
|
||||
завершается до over; все ходы легальны (предпосылка критерия v1 №2).
|
||||
- Perf-smoke: 1500 мс бюджета → ≤ ~2.2 с фактически (overhead кроме симуляций
|
||||
мал); число симуляций за 300 мс на 9×9 — в отчёт.
|
||||
- Wiring: orphan-check обновить под новые экспорты.
|
||||
|
||||
## Критерий выхода
|
||||
|
||||
Все тесты зелёные + `npm run gates` зелёный. Критерий v1 №3 («ур.6 < 2 с на
|
||||
среднем ноутбуке») — по бюджету 1500 мс + overhead; факт — в отчёт сессии.
|
||||
|
||||
## Пометки по факту реализации (2026-08-05)
|
||||
|
||||
- Все пункты объёма и тестов выполнены; гейты зелёные (118 тестов, lint без
|
||||
предупреждений). Perf-факты: ~147 симуляций за 300 мс на 9×9; ур.6 на
|
||||
13×13 — фактически ~1500 мс (бюджет 1500 мс + overhead < 5 мс).
|
||||
- Экспансия untried-детей — в детерминированном порядке legalMoves, первыми
|
||||
идут ходы со снятием камней (захваты разворачиваются в дерево раньше).
|
||||
Контракт порядок экспансии не оговаривает — эвристика внутри рамок UCT;
|
||||
без неё сигнал качество-smoke (захват группы за 200 симуляций) не
|
||||
выделяется на фоне шума плейаутов.
|
||||
- createWorkerHandler(port, deps?) — необязательный второй параметр
|
||||
WorkerDeps с инжектируемыми часами (в контракте «функция вида…»): нужен
|
||||
для детерминированных тестов протокола (фейк-часы, реентерабельный cancel
|
||||
из колбэка now()).
|
||||
- Качество-smoke: позиция «кольцо в атари + сплошные стены» — единственная
|
||||
из проверенных конструкций, где захват даёт устойчивый перекос winRate в
|
||||
случайных плейаутах (≈0.95 против ≈0.57). Seed запинен: при 200 симуляциях
|
||||
захват выбирается в ~75% seed'ов (при 800 — 12/12).
|
||||
Loading…
Add table
Add a link
Reference in a new issue