Индекс Морозова (MBI): методология
Индекс Морозова (MBI) отвечает на один вопрос для каждой из 960 стартовых позиций Chess960: насколько велик перевес белых на старте. На этой странице — весь метод целиком: любое число на сайте можно пересчитать по нему заново.
Автор методологии: Роман Морозов. Об авторе · Версия 2.0 · 2026-09-18
CC BY 4.0 Методология и данные: CC BY 4.0 — свободное использование со ссылкой на автора.
Что именно измеряется
В шахматах белые ходят первыми. Право первого хода чего-то стоит — и в Chess960 оно стоит по-разному в каждой из 960 расстановок. Индекс измеряет ВЕЛИЧИНУ этого стартового перевеса, а не то, кто лучше стоит. В 956 позициях из 960 движок ставит старт от равенства и выше в пользу белых; оставшиеся четыре уходят в минус на 2–7 сантипешки — это меньше, чем оценка гуляет между собственными итерациями поиска, то есть шум около нуля, а не перевес чёрных. Мера — расстояние от нуля в любую сторону, поэтому честная формулировка — «насколько велика фора здесь», а ровной называется позиция, где эта фора наименьшая.
MBI — шкала 0–100. 100 — наименьший измеренный перевес белых среди всех 960 позиций, самый ровный старт. 0 — наибольший. Индекс построен на РАНГЕ позиции, а не на абсолютной величине, поэтому он говорит, как позиция выглядит на фоне остальных 959, а не на сколько пешек кто-то впереди.
Как оценивается каждая позиция
Каждая стартовая позиция один раз анализируется Stockfish из начальной расстановки с фиксированным бюджетом УЗЛОВ, а не фиксированным временем. Это ключевое решение всего метода: бюджет узлов не зависит от машины. Бюджет времени дал бы быстрому компьютеру более глубокий поиск и, значит, другое число — и проверить результат было бы невозможно.
- Движок: Stockfish 17.1, официальная сборка, оценка NNUE зашита в бинарник.
- SHA-256 бинарника:
5f95eaea0d4eb697381989187ce6eb4d6ad59283c34421765ecc73cdb09ba766 - Сети NNUE: nn-1c0000000000.nnue, nn-37f18f62d772.nnue
- Лимит поиска: 400 000 000 узлов на позицию (`go nodes`).
- Опции UCI: Threads = 1, Hash = 256 МБ, UCI_Chess960 = true.
- `ucinewgame` перед каждой позицией: хеш-таблица очищается, позиции не влияют друг на друга, порядок счёта не имеет значения.
- Оценка всегда берётся с точки зрения белых, в сантипешках (100 cp — одна пешка).
- Оценка и вариант берутся с ПОСЛЕДНЕЙ ЗАВЕРШЁННОЙ итерации поиска — со строки без пометок lowerbound/upperbound. Итерация, оборванная лимитом узлов, сообщает границу, а не устоявшуюся оценку, и вариант у неё в один-два хода; взять её значило бы опубликовать шум вместо результата.
Однопоточный поиск с фиксированным хешем и фиксированным числом узлов детерминирован: тот же бинарник на любой машине вернёт то же значение в сантипешках, бит в бит. Именно это делает независимую проверку возможной, а не просто правдоподобной.
От сантипешек к индексу
Сантипешки — не линейная мера чего-либо человеческого, и разница между +18 и +22 сама по себе ничего не значит. Поэтому индекс использует РАНГ позиции среди всех 960, а не сырое число:
rank(sp) = position of eval_cp(sp) in the sorted list of all 960 values
(ascending: smallest White edge first, ties share the mean rank)
MBI(sp) = round( 100 * (960 - rank(sp)) / (960 - 1) )
| Класс | Перевес белых | Позиций |
|---|---|---|
| A — самые ровные | ≤ +19 cp | 240 |
| B — ровные | +20…+26 cp | 240 |
| C — заметный перевес | +27…+35 cp | 240 |
| D — наибольший перевес | > +35 cp | 240 |
На всех 960 позициях оценка движка укладывается в диапазон от -7 до +83 сантипешек, медиана +26.0.
Как распределены 960 значений
Каждая полоса — корзина шириной в пять сантипешек; число справа — сколько из 960 стартовых позиций в неё попало.
Валидация
Движковая оценка — это утверждение о позиции. Чтобы проверить, что утверждение предсказывает реальный результат, часть позиций доигрывается: движок против движка, много партий на позицию, сиды зафиксированы и опубликованы. Если позиции, которые индекс называет ровными, действительно дают счёт ближе к 50% за белых — значит, индекс измеряет то, что заявлено.
- 60 позиций × 50 партий = 3000 партий, контроль 300,000 nodes/move.
- Корреляция Спирмена между стартовой оценкой и счётом белых: 0.76 (95% ДИ 0.63…0.85, 10000 бутстрап-выборок). MBI — монотонное преобразование этой оценки, поэтому число описывает и его.
- Вывод: валидировано — порядок позиций предсказывает результат self-play, индекс публикуется как измеренный.
Базовый сид: 20260825. Любая партия воспроизводится точно.
| Позиция | Группа | Движок, cp | Партий | +/=/− | Счёт белых |
|---|---|---|---|---|---|
| 42 | случайные | +23 | 50 | 6/44/0 | 56.0% (42.3–68.8%) |
| 52 | случайные | +18 | 50 | 5/45/0 | 55.0% (41.3–67.9%) |
| 80 | самые перекошенные | +83 | 50 | 7/42/1 | 56.0% (42.3–68.8%) |
| 86 | случайные | +34 | 50 | 1/48/1 | 50.0% (36.6–63.4%) |
| 102 | самые ровные | 0 | 50 | 3/47/0 | 53.0% (39.5–66.1%) |
| 131 | самые ровные | 0 | 50 | 0/50/0 | 50.0% (36.6–63.4%) |
| 204 | самые ровные | 0 | 50 | 0/46/4 | 46.0% (33.0–59.6%) |
| 217 | самые ровные | +3 | 50 | 0/50/0 | 50.0% (36.6–63.4%) |
| 259 | самые ровные | +3 | 50 | 2/43/5 | 47.0% (33.9–60.6%) |
| 262 | случайные | +43 | 50 | 6/44/0 | 56.0% (42.3–68.8%) |
| 266 | случайные | +26 | 50 | 3/47/0 | 53.0% (39.5–66.1%) |
| 268 | самые перекошенные | +58 | 50 | 8/42/0 | 58.0% (44.2–70.6%) |
| 269 | самые ровные | 0 | 50 | 1/46/3 | 48.0% (34.8–61.5%) |
| 272 | самые перекошенные | +58 | 50 | 13/36/1 | 62.0% (48.2–74.1%) |
| 292 | случайные | +49 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 300 | самые ровные | 0 | 50 | 3/47/0 | 53.0% (39.5–66.1%) |
| 332 | самые перекошенные | +59 | 50 | 10/40/0 | 60.0% (46.2–72.4%) |
| 348 | самые перекошенные | +62 | 50 | 6/44/0 | 56.0% (42.3–68.8%) |
| 399 | самые перекошенные | +65 | 50 | 7/38/5 | 52.0% (38.5–65.2%) |
| 401 | самые ровные | -7 | 50 | 0/49/1 | 49.0% (35.7–62.4%) |
| 418 | самые ровные | -2 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 424 | случайные | +23 | 50 | 6/44/0 | 56.0% (42.3–68.8%) |
| 429 | самые ровные | 0 | 50 | 0/50/0 | 50.0% (36.6–63.4%) |
| 432 | самые ровные | +3 | 50 | 5/44/1 | 54.0% (40.4–67.0%) |
| 433 | самые ровные | -4 | 50 | 4/45/1 | 53.0% (39.5–66.1%) |
| 467 | самые ровные | +2 | 50 | 2/47/1 | 51.0% (37.6–64.3%) |
| 471 | самые ровные | 0 | 50 | 0/50/0 | 50.0% (36.6–63.4%) |
| 481 | случайные | +5 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 485 | самые ровные | +3 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 497 | самые ровные | 0 | 50 | 0/48/2 | 48.0% (34.8–61.5%) |
| 499 | случайные | +18 | 50 | 4/46/0 | 54.0% (40.4–67.0%) |
| 531 | случайные | +13 | 50 | 4/46/0 | 54.0% (40.4–67.0%) |
| 556 | случайные | +21 | 50 | 2/48/0 | 52.0% (38.5–65.2%) |
| 557 | самые перекошенные | +63 | 50 | 15/35/0 | 65.0% (51.1–76.7%) |
| 565 | самые перекошенные | +60 | 50 | 4/44/2 | 52.0% (38.5–65.2%) |
| 576 | самые ровные | 0 | 50 | 1/48/1 | 50.0% (36.6–63.4%) |
| 578 | самые перекошенные | +56 | 50 | 12/38/0 | 62.0% (48.2–74.1%) |
| 593 | самые ровные | +2 | 50 | 0/49/1 | 49.0% (35.7–62.4%) |
| 604 | самые перекошенные | +81 | 50 | 13/37/0 | 63.0% (49.1–75.0%) |
| 620 | самые перекошенные | +63 | 50 | 12/38/0 | 62.0% (48.2–74.1%) |
| 637 | случайные | +21 | 50 | 7/43/0 | 57.0% (43.3–69.7%) |
| 654 | случайные | +34 | 50 | 4/45/1 | 53.0% (39.5–66.1%) |
| 665 | случайные | +22 | 50 | 6/44/0 | 56.0% (42.3–68.8%) |
| 745 | случайные | +13 | 50 | 3/46/1 | 52.0% (38.5–65.2%) |
| 748 | случайные | +42 | 50 | 6/43/1 | 55.0% (41.3–67.9%) |
| 760 | самые перекошенные | +61 | 50 | 8/40/2 | 56.0% (42.3–68.8%) |
| 784 | самые перекошенные | +58 | 50 | 10/38/2 | 58.0% (44.2–70.6%) |
| 786 | самые ровные | +2 | 50 | 4/45/1 | 53.0% (39.5–66.1%) |
| 794 | самые перекошенные | +67 | 50 | 12/38/0 | 62.0% (48.2–74.1%) |
| 801 | случайные | +11 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 814 | случайные | +32 | 50 | 5/45/0 | 55.0% (41.3–67.9%) |
| 823 | самые ровные | -5 | 50 | 2/48/0 | 52.0% (38.5–65.2%) |
| 868 | самые перекошенные | +75 | 50 | 9/41/0 | 59.0% (45.2–71.5%) |
| 870 | случайные | +44 | 50 | 5/45/0 | 55.0% (41.3–67.9%) |
| 879 | самые перекошенные | +66 | 50 | 11/38/1 | 60.0% (46.2–72.4%) |
| 880 | самые перекошенные | +63 | 50 | 7/42/1 | 56.0% (42.3–68.8%) |
| 885 | случайные | +14 | 50 | 1/49/0 | 51.0% (37.6–64.3%) |
| 886 | самые перекошенные | +58 | 50 | 5/45/0 | 55.0% (41.3–67.9%) |
| 902 | самые перекошенные | +62 | 50 | 5/44/1 | 54.0% (40.4–67.0%) |
| 935 | самые перекошенные | +78 | 50 | 11/38/1 | 60.0% (46.2–72.4%) |
Глубокая проверка и классификация v2
Версия 2.0 добавляет к индексу второй слой. Каждая позиция разыграна по главной линии движка на 30 ходов (35 — для приоритетных), самые ровные позиции и все нулевые или отрицательные пересчитаны с бюджетом узлов в 3–10 раз больше, а нулевые/отрицательные получили ещё поиск трёх лучших ходов (MultiPV) и вторую серию self-play.
Полоса баланса (по базовой оценке)
Абсолютные пороги в сантипешках вместо квартилей: E — ровная, |cp| ≤ 10; S — небольшой перевес, 11–25; M — заметный, 26–40; L — большой, ≥ 41. Квартили гарантировали 240 «ровных» позиций при любых данных; полоса вмещает ровно столько, сколько их есть. Полосу задаёт базовый счёт (400 000 000 узлов, одна глубина для всех 960), глубокий — проверяет.
| Полоса | Позиций |
|---|---|
| E — ровная | 64 |
| S — небольшой перевес | 386 |
| M — заметный перевес | 377 |
| L — большой перевес | 133 |
Динамика (по разыгрыванию)
Тот же движок играет за обе стороны с фиксированным бюджетом 5 000 000 узлов на ход, оценка записывается перед каждым полуходом. volatile — оценка качнулась на ≥ 60 cp или сменила знак не менее 2 раз (знаком считаются только значения за ±15 cp); equalizing — перевес к финалу меньше стартового не менее чем на 10 cp; sharpening — больше не менее чем на 15 cp; stable — всё остальное.
Оценки при таком бюджете на ход завышают перевес белых в начале партии и сходятся к нулю по мере упрощения, поэтому сырая траектория почти любой позиции «выравнивается». Перед разметкой из каждого разыгрывания вычитается медианная траектория всех 960 позиций (по каждому полуходу): общий дрейф сокращается, остаётся то, чем позиция отличается от типичной. Сырые опорные точки на 10, 20 и 30 ходах публикуются как есть.
| Динамика | Позиций |
|---|---|
| стабильная | 542 |
| выравнивается | 285 |
| обостряется | 25 |
| неустойчивая | 108 |
Полосы × динамика
| Полоса | стабильная | выравнивается | обостряется | неустойчивая |
|---|---|---|---|---|
| E | 28 | 33 | 1 | 2 |
| S | 234 | 120 | 6 | 26 |
| M | 240 | 81 | 14 | 42 |
| L | 40 | 51 | 4 | 38 |
Глубокий пересчёт
Позиции с |cp| ≤ 25 пересчитаны с бюджетом 1 200 000 000 узлов, нулевые и отрицательные — 4 000 000 000 узлов; один поток, фиксированный хэш — каждое число воспроизводимо бит-в-бит. Позиция считается подтверждённой, если глубокое значение отличается от базового не более чем на 10 cp (двойной разброс соседних итераций базового поиска): подтверждено 123 из 147. Глубокий счёт сдвигает эти позиции систематически вверх — медиана +3 cp при ×3 и +9 cp при ×10 — и ни одна не оказалась отрицательной; полоса по глубокому значению публикуется рядом с базовой, читатель видит обе.
Спорные тринадцать
Тринадцать позиций в базовом счёте дали ноль или небольшой минус. Знак решает глубокий поиск; поиск трёх лучших ходов (800 000 000 узлов) и вторая серия self-play (100 партий на позицию при 1 000 000 узлах на ход) — независимые проверки, а не право вето.
| Позиция | Движок, cp | Глубоко, cp | Вердикт | Self-play v2 |
|---|---|---|---|---|
| 102 | 0 | +20 | перевес белых — минус был шумом | 54.5% (44.8–63.9%) |
| 131 | 0 | +5 | ровно — в пределах шума движка | 50.5% (40.9–60.1%) |
| 204 | 0 | +9 | ровно — в пределах шума движка | 47.5% (38.0–57.2%) |
| 269 | 0 | +15 | перевес белых — минус был шумом | 48.5% (38.9–58.2%) |
| 300 | 0 | +12 | перевес белых — минус был шумом | 51.5% (41.8–61.1%) |
| 401 | -7 | 0 | ровно — в пределах шума движка | 49.0% (39.4–58.7%) |
| 418 | -2 | +5 | ровно — в пределах шума движка | 50.5% (40.9–60.1%) |
| 429 | 0 | +10 | ровно — в пределах шума движка | 51.0% (41.3–60.6%) |
| 433 | -4 | +3 | ровно — в пределах шума движка | 51.5% (41.8–61.1%) |
| 471 | 0 | +15 | перевес белых — минус был шумом | 50.0% (40.4–59.6%) |
| 497 | 0 | +6 | ровно — в пределах шума движка | 49.0% (39.4–58.7%) |
| 576 | 0 | +13 | перевес белых — минус был шумом | 50.0% (40.4–59.6%) |
| 823 | -5 | 0 | ровно — в пределах шума движка | 51.5% (41.8–61.1%) |
Полосы по семействам позиций
| Номенклатура | E | S | M | L |
|---|---|---|---|---|
| BastionGuard | 14 | 69 | 58 | 27 |
| BastionScout | 14 | 61 | 70 | 23 |
| RampartGuard | 11 | 53 | 67 | 13 |
| RampartScout | 2 | 30 | 30 | 10 |
| ThroneGuard | 16 | 98 | 65 | 25 |
| ThroneScout | 7 | 75 | 87 | 35 |
Ограничения — прочтите до того, как цитировать числа
- Движковая оценка — не человеческая практика. Позиция, которую движок считает ровной, может быть неудобной, острой или непривычной для человека — здесь это не измеряется.
- Один движок, одна оценочная функция. Другой движок дал бы слегка другой порядок. Метод зафиксирован и опубликован именно для того, чтобы любой мог повторить его на другом движке и сравнить.
- Фиксированный бюджет узлов — это срез на одной глубине поиска. Более глубокий анализ сдвигает отдельные значения; порядок позиций устойчивее любого отдельного числа — поэтому индекс и построен на ранге.
- В Chess960 почти нет дебютной теории. В классических шахматах перевес белых отчасти состоит из библиотеки заготовок; здесь — только из работы фигур. Это делает измерение чище, но и означает, что к классическому старту эти числа отношения не имеют.
- Self-play на сверхбыстром контроле — дешёвое приближение «реальной игры». Он проверяет порядок позиций, но не удостоверяет ни одну отдельную позицию.
- Индекс — свойство ТОЛЬКО стартовой позиции. О том, кто лучше стоит после первого хода, он не говорит ничего.
- Разыгрывание — одна линия движка при скромном бюджете на ход: оно показывает, как ведёт себя баланс в быстрой игре, а не теоретическую цену позиции.
Как перепроверить самому
Всё, что нужно для пересчёта датасета, открыто: точная сборка движка, бюджет, скрипты и сырой вывод. Пересчёт одной позиции занимает несколько минут на одном ядре, весь набор — одну ночь.
- Скачайте сырые данные и скрипты со страницы открытых данных. Открытые данные
- Проверьте одну позицию против опубликованного датасета — команда считает её заново и сверяет:
python tools/balance/verify_reproduce.py --sp 518 - Или пересчитайте весь набор (прогон возобновляемый: после обрыва дописывается в тот же файл):
python tools/balance/eval_all.py --nodes 400000000 --workers 20
Если ваше значение отличается — это и есть находка: не совпадут либо сборка движка, либо бюджет узлов, либо опции. Все три напечатаны выше.
Цитирование и лицензия
Методология и датасет опубликованы под CC BY 4.0: используйте как угодно, в том числе коммерчески, со ссылкой на автора.
Морозов Р. Индекс баланса Chess960 (MBI). ch960.com/balance, 2026. CC BY 4.0.