⏱️ Корпус: длина партий, исходы и время

О чём это

Справочные измерения по всей базе (1 614 479 партий, замер 12.08.2026): сколько ходов живёт партия, чем она заканчивается, сколько партий падает по флагу на разных контролях. Это опорные числа для менеджера времени ботов, для дизайна анализа и для любых будущих решений про бюджеты. Прямое следствие уже заведено как engine#602.

Связанные: ml-lab-journal · game-analysis-design · database-structure

1. Длина партии

ходов
медиана12
среднее14,7
p9027
p9949
максимум574

Партии очень короткие. Хвост существует, но тонкий: длиннее 49 ходов лишь 1% партий. Это, кстати, ровно та причина, по которой explorer’ы и книга дебютов покрывают заметную долю реальной игры — глубина, на которую вообще успевает уйти партия, невелика.

Длина почти не зависит от контроля — на всех бэндах 13,7–15,0 ходов. То есть на длинных контролях игроки не играют дольше, они просто не тратят время.

2. Чем заканчиваются партии

ИсходПартийДоля
king_captured1 434 40588,85%
timeout77 4264,80%
double_declined35 3922,19%
draw_agreement30 4991,89%
unknown22 6391,40%
resign14 1200,87%

Почти девять партий из десяти доигрываются до взятия короля — поэтому фильтр termination = king_captured для обучающих меток стоит так дёшево: он отсекает всего 11% корпуса (обоснование фильтра — в журнале, запись 09.08).

3. Проигрыши по времени — по контролям

КонтрольПартийСр. ходовФлаг
≤ 60 с241 86713,712,26%
61–180 с573 89414,94,68%
181–300 с618 31215,02,63%
> 300 с175 31414,52,65%

Ключевое наблюдение

С 300 секунд доля флагов перестаёт улучшаться: 2,63% против 2,65% на контролях свыше 300 с. Дополнительное время не расходуется — значит на контролях от трёх минут часы перестают быть ограничением. Это и есть измеренный запас, о котором стоит думать при проектировании бюджетов.

Самые популярные контроли: 300+5 (23,5% партий), 180+3 (16,6%), 60+1 (11,7%), 300+3 (8,7%).

4. Сколько ходов остаётся, если мы на ходу N

Условное ожидание по партиям с king_captured — то, что на самом деле нужно менеджеру времени:

на ходупартий живоожидается ещёp90 ещё
11 434 57514,026
31 431 69412,124
51 359 11910,723
81 118 7139,722
10950 5209,421
15595 3208,820
20350 6938,720
30114 3319,422
4038 25810,926

Две особенности этой кривой, и обе важны:

Она начинается с 14, а не с 30. Движковый TimeManager стартует с BaseMovesToGo = 30 — то есть на первом ходу делит часы примерно на вдвое большее число ходов, чем партия проживёт. Недоплата ложится на ранние ходы, где решается почти всё.

Гипотеза проверена — она верна, но не везде

Кривая переехала в движок как политика empirical-v1 (1.14.0) и стала дефолтом. Парный замер: +13 elo против линейного спада при KCP one-ply на 5+3 — разбор дуэли. Но при oracle-3 с K=24 и K=48 политики неотличимы вовсе: дешёвый оценщик тратит 0.4 с при доступных 14–20 с, то есть часы там не связывают, ровно как и предсказывает раздел выше про исчерпание запаса с трёх минут. Выигрыш появляется только у дорогих оценщиков.

Она не монотонна. Проседает до 8,7 к 20-му ходу и снова растёт к 10,9 на 40-м: партия, дожившая до сорокового хода, по отбору является эндшпильной мельницей. Линейный taper не описывает ни начало кривой, ни её хвост — но именно хвост объясняет, почему потолок MaxFraction и резерв трогать нельзя.

5. Дырка в данных: thinking_time_ms пустая

Колонка turns.thinking_time_ms заполнена в 0 строк из 22 миллионов. При этом труба построена целиком: колонка в схеме есть, поле есть в контракте ingest (thinkingTimeMs: Option[Int]), IngestRepository его пишет — а производители шлют null. У play-api это даже записано явно в коде (.add("thinking_time_ms", Json.Null)), хотя часы он ведёт сам.

Поэтому фактический расход времени по ходам измерить сейчас нельзя — все выводы выше о запасе получены косвенно, через долю флагов. Заведено как play-api#316; исторические строки останутся NULL, данные никогда не существовали.

6. Косвенные подтверждения запаса со стороны ботов

  • Timed-дуэль raw-board против oracle-3 (3+2, 7 400 партий): счётчики поражений по времени 0/0 на каждом промежуточном срезе.
  • Книжная дуэль (3+2, 12 000 партий): тоже 0/0.
  • Арифметика на 3+2: 180 с + 2 с × ~15 ходов ≈ 210 с на ~15 ходов ≈ ~14 с/ход доступно. Наши дешёвые оценщики тратят доли секунды; KCP-модель с K=48 — около 2,4 с/ход, то есть влезает с многократным запасом.

Как воспроизвести

Запросы — к прод-БД analytics (read-only), таблицы games и turns. Условное ожидание считается как avg(total_turns − N) по партиям с total_turns ≥ N при termination = 'king_captured'. Замер 12.08.2026 на 1 614 479 партиях; при существенном росте корпуса числа стоит пересчитать, но форма кривой вряд ли изменится — распределение устойчиво по контролям и по источникам.