Идея хорошая и, что важно, дёшево реализуемая — почти вся инфраструктура уже есть. Но в ней есть одна критичная развилка, на которой книга либо станет сильной, либо посредственной. Разберу честно.
Вердикт
Сильная, высокоокупаемая идея — при одном условии: «лучшую» линию выбирать по сильным игрокам, а не по всем партиям. Без этого книга выучит «что выигрывает против слабых», а не «что объективно хорошо».
Почему это правильный ход
- Движок слаб именно в дебюте. Он жадный/MC, а в дебюте ветвление огромно (кости × много фигур) — там поиск проседает сильнее всего, а данных, наоборот, больше всего (все партии проходят через одни и те же ранние позиции). Книга бьёт ровно в слабое место.
- Экономит время. Тяжёлые боты проигрывают по часам (dicechess-bot-time-budget). Готовый ход из книги = 0 раздумий в дебюте → бот быстрее и не сжигает бюджет на самой ветвистой фазе. Это не побочный, а один из главных профитов.
- Данные и пайплайн уже есть. Запросы
continuations/dice-distribution/equityуже считают частоту + win% по (позиция, кости, линия) с фильтромmin_rating. И уже есть задачаdb:export-book(веткаfeat/189-export-opening-book) — то есть это наполовину начато. - Совпадает с вектором «статистика/win-rate = ядро ценности» (dicechess-analytics-ui-vision).
Критичные поправки (без них — мимо)
- «Лучшее» — только из сильных партий. Эталон = win-rate сильнейших (dicechess-engine-strength). Считай книгу по
min_rating ≥ 2000/2200(оба игрока) и исключи партии ботов/слабого движка — иначе книга оптимизируется под слабую оппозицию и зациклится (боты играют книгу → книга учится на ботах). Это правка №1. - Строй на ОЧИЩЕННЫХ continuations. Мы только что выкатили фильтр незавершённых ходов (без короля/без флипа = брошенные). Книга должна брать уже отфильтрованные линии — иначе порекомендует «e2e4-и-сдался» как «дебют».
- win% — это корреляция, не причинность. Высокий win% линии часто потому, что её выбирали сильные (а выигрывали они и по другим причинам). Как прокси для v1 — приемлемо, но честно: это «что играют и с чем выигрывают сильные», а не доказанно лучшее. Снижается кондиционированием по рейтингу.
Что заложить в дизайн (реалистичные ожидания)
- Ключ = (позиция × бросок), не просто позиция (в этом отличие от шахмат). Книга крупнее, но пороги «достаточно партий» на трёх уровнях (позиция / бросок / линия) обрезают её до хорошо хоженого ядра.
- Это дебютная книга, неглубокая. С каждым ходом ветвление по костям ×~56, и «достаточно партий» исчезает быстро → книга покроет первые 1–3 хода главных линий, дальше — движок. Это нормально (так и работают книги), но порог покрытия/глубины надо подобрать.
- Запись = (позиция, кости) → лучшая результирующая позиция + последовательность микро-ходов (ход в dice chess = несколько микро-ходов). Бот должен уметь исполнить эту последовательность. Win% берётся «для стороны, чей ход» — значит автоматически работает и за белых, и за чёрных.
- Храни топ-K с win% и числом партий, а не один ход — даст боту запас и данные для разнообразия.
Не пропустить
- Валидация ареной. Бот-с-книгой против бота-без-книги: измерь прирост win% и сэкономленное время. Это и доказательство пользы, и прямая привязка к проблеме тайм-бюджета. Без этого «дать файл роботам» — вера, а не факт.
- Чуть-чуть рандома среди близких по win% топ-линий — иначе бот предсказуем/эксплуатируем (соперники выучат книгу), плюс это хедж против корреляционного смещения.
- Перегенерация по мере накопления партий (задача
db:export-bookэто и делает) — определи каденс.
Короткие броски (всплыло на проде)
Помни: в данных есть броски не только из 3 костей (напр. dice_sorted="N"). Книга должна обрабатывать любые длины броска, а не хардкодить «56».
Итог: делать стоит, окупаемость высокая, фундамент готов. Решающее — фильтр по силе игроков + чистые данные + арена-валидация. Хочешь — распишу конкретную схему формата книги (JSON-структура: ключ позиции+костей → топ-ходы) и SQL/пороги поверх существующего db:export-book, или прикину арену-эксперимент для проверки прироста.