Разработка новой рейтинговой системы #22

Closed
opened 2026-09-08 23:19:13 +03:00 by NotBigGhost · 5 comments
Owner

Определение задачи:

Система рейтинга не учитывает множество важных элементов, и нуждается в доработке. Должна быть проведена исследовательская задача, результат которой - подготовка документа, описывающего новую рейтинговую систему, её правила и готовые цифры, формулы, коэффициенты и примеры расчётов. В данном документе также должны быть описаны причины принятия решений в рамках разработки этой системы, доказывающие их состоятельность и позволяющие оценить её качество.

Критерий готовности

Получение от владельца проекта утверждения новой системы после ознакомления с документом. По закрытии задачи документ должен быть загружен в комментарии к задаче #23.

Требования

1: количество раундов. 4 цели, собранные за 2 раунда, значительно ценнее, чем те же 4, но собранные под конец 8 раунда.
2: первое место всегда даёт максимальный бал, независимо от количества игроков за столом, что не совсем честно. Но если мы будем учитывать количество игроков, этот параметр должен иметь меньший вес, чем, например, количество раундов. Следовательно, для каждого значимого для рейтинга параметра необходимо ввести вес влияния, чтобы сделать возможным подсчёт рейтинга из множественных характеристик партии. Тогда будет возможно более объективно оценивать рейтинг, опираясь на ход партии.
3: при начислении баллов учитывается разница в рейтинге с оппонентами. Например, если человек с рейтингом 60 победил в дуэли человека с рейтингом 40, ему повышают рейтинг на меньшее число, и наоборот, победителю с 40 рейтинга его повышают сильнее.
4: добавить счётчик взятых за игру целей и занятых систем на поле на момент завершения игры, чтобы определить разброс между всеми игроками и соответствующе изменить начисление рейтинга.
5: учитывать тип победы. Например, победа по планетам это более близкая игра чем по целям а победа по пластику ещё ближе. Следовательно разброс между игроками уменьшается.

Контекст

Для победы в игре необходимо собрать количество целей, равное количеству игроков за столом. Так, если играют двое, нужно собрать 2 цели, если четверо - 4 цели и т.д.
Поле состоит из тайлов, каждый тайл делится на 4 сектора двух типов - система и космос. Количество тайлов определяется количеством игроков. Так, при игре вдвоём будет поле 2 на 2 (4 тайла), при игре втроём - 3 на 3 (9 тайлов), при игре вчетвером - 3 на 4 (12 тайлов), при игре впятером - 4 на 4 (16 тайлов). При этом количество систем на одном тайле варьируется от двух до трех, при этом если учесть частоту появления тайла с тремя системами, в среднем получается 2.2 системы на один тайл.

# Определение задачи: Система рейтинга не учитывает множество важных элементов, и нуждается в доработке. Должна быть проведена исследовательская задача, результат которой - подготовка документа, описывающего новую рейтинговую систему, её правила и готовые цифры, формулы, коэффициенты и примеры расчётов. В данном документе также должны быть описаны причины принятия решений в рамках разработки этой системы, доказывающие их состоятельность и позволяющие оценить её качество. # Критерий готовности Получение от владельца проекта утверждения новой системы после ознакомления с документом. По закрытии задачи документ должен быть загружен в комментарии к задаче #23. # Требования 1: количество раундов. 4 цели, собранные за 2 раунда, значительно ценнее, чем те же 4, но собранные под конец 8 раунда. 2: первое место всегда даёт максимальный бал, независимо от количества игроков за столом, что не совсем честно. Но если мы будем учитывать количество игроков, этот параметр должен иметь меньший вес, чем, например, количество раундов. Следовательно, для каждого значимого для рейтинга параметра необходимо ввести вес влияния, чтобы сделать возможным подсчёт рейтинга из множественных характеристик партии. Тогда будет возможно более объективно оценивать рейтинг, опираясь на ход партии. 3: при начислении баллов учитывается разница в рейтинге с оппонентами. Например, если человек с рейтингом 60 победил в дуэли человека с рейтингом 40, ему повышают рейтинг на меньшее число, и наоборот, победителю с 40 рейтинга его повышают сильнее. 4: добавить счётчик взятых за игру целей и занятых систем на поле на момент завершения игры, чтобы определить разброс между всеми игроками и соответствующе изменить начисление рейтинга. 5: учитывать тип победы. Например, победа по планетам это более близкая игра чем по целям а победа по пластику ещё ближе. Следовательно разброс между игроками уменьшается. # Контекст Для победы в игре необходимо собрать количество целей, равное количеству игроков за столом. Так, если играют двое, нужно собрать 2 цели, если четверо - 4 цели и т.д. Поле состоит из тайлов, каждый тайл делится на 4 сектора двух типов - система и космос. Количество тайлов определяется количеством игроков. Так, при игре вдвоём будет поле 2 на 2 (4 тайла), при игре втроём - 3 на 3 (9 тайлов), при игре вчетвером - 3 на 4 (12 тайлов), при игре впятером - 4 на 4 (16 тайлов). При этом количество систем на одном тайле варьируется от двух до трех, при этом если учесть частоту появления тайла с тремя системами, в среднем получается 2.2 системы на один тайл.
NotBigGhost added this to the v1.5 — изменение системы подсчёта рейтинга milestone 2026-09-08 23:19:13 +03:00
NotBigGhost added the Kind/Proposal label 2026-09-08 23:30:13 +03:00
Agent self-assigned this 2026-09-13 18:59:31 +03:00
Agent added the
Reviewed
Confirmed
1
label 2026-09-13 18:59:32 +03:00
Collaborator

План выполнения

  1. Модель — взвешенный многопользовательский Elo. Партия раскладывается на пары игроков; ожидаемый исход пары считается из разницы рейтингов (треб. 3). Изменение рейтинга: ΔR_i = K_i · G(N) · 1/(N−1) · Σ_j M_ij · (S_ij − E_ij) — система сумма-ноль, без инфляции.

  2. Множитель отрыва M_ij:

    • темп победы: (R_max − раунд)/(R_max − 1), треб. 1; R_max = 8, при хоумруле группы для 5–6 игроков — 9;
    • разница целей (/N) и миров (/ миров на поле / N), треб. 4;
    • близость по типу победы: цели > миры > пластик > ресурсы (домашний тай-брейк), треб. 5;
    • поправка на автокорреляцию.

    Вес размера стола G(N) мягкий и меньше веса темпа (треб. 2). Для новичков — повышенный K.

  3. Проверка на симуляции. Скрипт docs/rating/simulate.py (только stdlib, фиксированный seed) создаёт синтетическую лигу со скрытой силой игроков и сравнивает текущий LP, чистый парный Elo и новую систему. Метрики: корреляция с истинной силой, Brier и log-loss прогноза, сходимость, волатильность. Коэффициенты подбираются перебором.

  4. Документ docs/rating/rating-system.md:

    • проблемы текущей системы;
    • трассировка требований 1–5;
    • сравнение альтернатив (Glicko-2, TrueSkill/OpenSkill);
    • формулы и коэффициенты;
    • пошаговые примеры, в том числе стол на 6 с 9 раундами;
    • результаты симуляции;
    • последствия для #23: новые поля rounds/objectives/worlds, галочка группы «9 раундов на 5–6», снимок max_rounds в партии, пересчёт истории, смена отображения;
    • открытые вопросы.
  5. PR в dev. Мёрж PR — утверждение. После мёржа документ выкладывается комментарием в #23.

Критерии готовности

  • Каждое требование 1–5 имеет формулу, коэффициент и обоснование.
  • Есть не меньше пяти пошаговых примеров; их числа воспроизводит simulate.py через assert.
  • Симуляция сравнивает три системы; новая не хуже текущей по предсказательной силе.
  • Описаны изменения данных и миграция истории для #23.
  • Владелец утвердил документ.

Термины: «системы» из текста задачи в документе называются мирами, как в справочнике (стр. 8, 16). Поле: 2p — 4 тайла, 3p — 9, 4p — 12, 5p — 16, 6p — 20 (4×5), в среднем 2.2 мира на тайл.

Ветка: issue-22-rating-proposal от dev

## План выполнения 1. **Модель — взвешенный многопользовательский Elo.** Партия раскладывается на пары игроков; ожидаемый исход пары считается из разницы рейтингов (треб. 3). Изменение рейтинга: `ΔR_i = K_i · G(N) · 1/(N−1) · Σ_j M_ij · (S_ij − E_ij)` — система сумма-ноль, без инфляции. 2. **Множитель отрыва `M_ij`:** - темп победы: `(R_max − раунд)/(R_max − 1)`, треб. 1; `R_max` = 8, при хоумруле группы для 5–6 игроков — 9; - разница целей (`/N`) и миров (`/ миров на поле / N`), треб. 4; - близость по типу победы: цели > миры > пластик > ресурсы (домашний тай-брейк), треб. 5; - поправка на автокорреляцию. Вес размера стола `G(N)` мягкий и меньше веса темпа (треб. 2). Для новичков — повышенный `K`. 3. **Проверка на симуляции.** Скрипт `docs/rating/simulate.py` (только stdlib, фиксированный seed) создаёт синтетическую лигу со скрытой силой игроков и сравнивает текущий LP, чистый парный Elo и новую систему. Метрики: корреляция с истинной силой, Brier и log-loss прогноза, сходимость, волатильность. Коэффициенты подбираются перебором. 4. **Документ `docs/rating/rating-system.md`:** - проблемы текущей системы; - трассировка требований 1–5; - сравнение альтернатив (Glicko-2, TrueSkill/OpenSkill); - формулы и коэффициенты; - пошаговые примеры, в том числе стол на 6 с 9 раундами; - результаты симуляции; - последствия для #23: новые поля `rounds`/`objectives`/`worlds`, галочка группы «9 раундов на 5–6», снимок `max_rounds` в партии, пересчёт истории, смена отображения; - открытые вопросы. 5. **PR в `dev`.** Мёрж PR — утверждение. После мёржа документ выкладывается комментарием в #23. **Критерии готовности** - Каждое требование 1–5 имеет формулу, коэффициент и обоснование. - Есть не меньше пяти пошаговых примеров; их числа воспроизводит `simulate.py` через assert. - Симуляция сравнивает три системы; новая не хуже текущей по предсказательной силе. - Описаны изменения данных и миграция истории для #23. - Владелец утвердил документ. Термины: «системы» из текста задачи в документе называются **мирами**, как в справочнике (стр. 8, 16). Поле: 2p — 4 тайла, 3p — 9, 4p — 12, 5p — 16, 6p — 20 (4×5), в среднем 2.2 мира на тайл. **Ветка:** `issue-22-rating-proposal` от `dev`
Agent added the
Status
In Review
label 2026-09-13 19:52:40 +03:00
Collaborator

Исследование завершено, результат: PR #65 — документ docs/rating/rating-system.md и эталонная реализация с симуляцией docs/rating/simulate.py.

Вывод: многопользовательский Elo со шкалой вокруг 50. Размер изменения рейтинга зависит от множителя отрыва: темп победы (с учётом хоумрула 9 раундов), отрыв по целям и мирам, тип победы. Размер стола тоже учитывается, но весит слабее темпа. Разница рейтингов с соперниками учитывается через ожидаемый результат. Старая история пересчитывается по тем же формулам: у партий без новых полей признаки нейтральны.

На чём основано:

  • Правила — справочник, стр. 8, 11 и 16, плюс уточнения из этой задачи.
  • 15 пошаговых примеров расчёта; скрипт проверяет их через assert.
  • Синтетическая лига, 200 сезонов на сценарий, коэффициенты подобраны на отдельных сезонах.
    • Если отрыв связан с силой игроков, новая система лучше текущей и чистого Elo: ρ после 10 партий — 0.807 против 0.769, в «клубах» — 0.645 против 0.525.
    • Если отрыв — шум, система уступает около 0.1 п.п. точности.
  • Анализ чувствительности весов.

Открытые вопросы (раздел 9 документа):

  • шкала: 50 или 1500;
  • коэффициенты близости по типам победы;
  • новая причина победы last_standing;
  • удобство ввода миров;
  • затухание за неактивность;
  • MIN_GAMES.

Какой признак отрыва информативнее, покажут только реальные данные после #23 — план калибровки есть в разделе 8.

Статус: Status/In Review — жду вашего утверждения; мёрж PR закроет задачу. После мёржа документ будет выложен комментарием в #23, как требует критерий готовности.

Исследование завершено, результат: PR https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/65 — документ [`docs/rating/rating-system.md`](https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/src/branch/issue-22-rating-proposal/docs/rating/rating-system.md) и эталонная реализация с симуляцией `docs/rating/simulate.py`. **Вывод:** многопользовательский Elo со шкалой вокруг 50. Размер изменения рейтинга зависит от множителя отрыва: темп победы (с учётом хоумрула 9 раундов), отрыв по целям и мирам, тип победы. Размер стола тоже учитывается, но весит слабее темпа. Разница рейтингов с соперниками учитывается через ожидаемый результат. Старая история пересчитывается по тем же формулам: у партий без новых полей признаки нейтральны. **На чём основано:** - Правила — справочник, стр. 8, 11 и 16, плюс уточнения из этой задачи. - 15 пошаговых примеров расчёта; скрипт проверяет их через `assert`. - Синтетическая лига, 200 сезонов на сценарий, коэффициенты подобраны на отдельных сезонах. - Если отрыв связан с силой игроков, новая система лучше текущей и чистого Elo: ρ после 10 партий — 0.807 против 0.769, в «клубах» — 0.645 против 0.525. - Если отрыв — шум, система уступает около 0.1 п.п. точности. - Анализ чувствительности весов. **Открытые вопросы** (раздел 9 документа): - шкала: 50 или 1500; - коэффициенты близости по типам победы; - новая причина победы `last_standing`; - удобство ввода миров; - затухание за неактивность; - `MIN_GAMES`. Какой признак отрыва информативнее, покажут только реальные данные после #23 — план калибровки есть в разделе 8. **Статус:** `Status/In Review` — жду вашего утверждения; мёрж PR закроет задачу. После мёржа документ будет выложен комментарием в #23, как требует критерий готовности.
Author
Owner

Уточнение, при дуэли (игра на 2-х игроков), поле не 2x2, а 2x3.

Уточнение, при дуэли (игра на 2-х игроков), поле не 2x2, а 2x3.
Agent removed the
Status
In Review
label 2026-09-14 20:53:56 +03:00
Collaborator

План доработки по замечаниям

Основание: уточнение про поле 2×3 в этой задаче и решения по разделу 9 в комментарии к PR #65.

  1. simulate.py.
    • Поле дуэли 2×3 (6 тайлов, 13.2 мира, 6.6 на игрока).
    • Шкала 1500: R₀ = 1500, D = 400, K 64 → 16. Примеры и assert — в новой шкале.
    • |ΔR| у League Points в сравнении приводится ×10.
  2. Пересчёт. Примеры, сравнение систем (200 сезонов) и перебор коэффициентов. E, порядок и Brier от масштаба не зависят, поэтому таблицы меняются из-за поля 2×3; это проверяется отдельно.
  3. Документ, разделы 2 и 4–7. Новая строка поля, шкала 1500, все числа из новых прогонов, пределы изменений 32 / 128 / 192.
  4. Раздел 8 (последствия для #23).
    • Правило last_standing ⇔ ровно один невыбывший: автоматически в форме и админской правке, в списке выбора причины нет, сервер проверяет правило при завершении и правке.
    • Миграцией проставить last_standing старым партиям, где невыбывший ровно один.
    • Рейтинг показывается целым числом. В общем топе убрать столбец «Поб», «Очки» → «Рейтинг».
    • Устаревший абзац про CLAUDE.md заменить ссылкой на дублирование формулы в HelpPage.tsx.
  5. Раздел 9. «Открытые вопросы» → «Решения владельца» (6 пунктов).
  6. Трекер. Обновить описание PR #65, отчёт сюда, вернуть Status/In Review.

Критерии готовности

  • Поле 2×3 учтено в таблице правил, скрипте, примерах и симуляции.
  • Шкала 1500 во всех формулах, примерах и таблицах; assert примеров проходят.
  • Все шесть решений отражены в разделах 8–9.
  • PR #65 обновлён; утверждение — его мёрж.

Ветка: issue-22-rating-proposal от dev (существующая, PR #65)

## План доработки по замечаниям Основание: уточнение про поле 2×3 в этой задаче и решения по разделу 9 в комментарии к PR https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/65. 1. **`simulate.py`.** - Поле дуэли 2×3 (6 тайлов, 13.2 мира, 6.6 на игрока). - Шкала 1500: R₀ = 1500, D = 400, K 64 → 16. Примеры и `assert` — в новой шкале. - |ΔR| у League Points в сравнении приводится ×10. 2. **Пересчёт.** Примеры, сравнение систем (200 сезонов) и перебор коэффициентов. E, порядок и Brier от масштаба не зависят, поэтому таблицы меняются из-за поля 2×3; это проверяется отдельно. 3. **Документ, разделы 2 и 4–7.** Новая строка поля, шкала 1500, все числа из новых прогонов, пределы изменений 32 / 128 / 192. 4. **Раздел 8 (последствия для #23).** - Правило `last_standing` ⇔ ровно один невыбывший: автоматически в форме и админской правке, в списке выбора причины нет, сервер проверяет правило при завершении и правке. - Миграцией проставить `last_standing` старым партиям, где невыбывший ровно один. - Рейтинг показывается целым числом. В общем топе убрать столбец «Поб», «Очки» → «Рейтинг». - Устаревший абзац про CLAUDE.md заменить ссылкой на дублирование формулы в `HelpPage.tsx`. 5. **Раздел 9.** «Открытые вопросы» → «Решения владельца» (6 пунктов). 6. **Трекер.** Обновить описание PR #65, отчёт сюда, вернуть `Status/In Review`. **Критерии готовности** - Поле 2×3 учтено в таблице правил, скрипте, примерах и симуляции. - Шкала 1500 во всех формулах, примерах и таблицах; `assert` примеров проходят. - Все шесть решений отражены в разделах 8–9. - PR #65 обновлён; утверждение — его мёрж. **Ветка:** `issue-22-rating-proposal` от `dev` (существующая, PR #65)
Agent added the
Status
In Review
label 2026-09-14 21:12:12 +03:00
Collaborator

Доработка по замечаниям завершена, PR обновлён: #65 — документ docs/rating/rating-system.md.

Вывод: предложение согласовано с вашими решениями, открытых вопросов не осталось.

  • Поле дуэли 2×3. Учтено в правилах, примерах и симуляции. Метрики сдвинулись на тысячные, выводы прежние: ρ после 10 партий — 0.807 против 0.769 у текущей системы, в «клубах» — 0.644 против 0.525.
  • Шкала 1500. Старт 1500, D = 400, K 64 → 16. Все примеры и таблицы переведены в эту шкалу. Скрипт проверяет, что качество прогноза от шкалы не зависит.
  • Раздел 8 (для #23):
    • правило last_standing: ставится автоматически при одном невыбывшем, вручную не выбирается, сервер проверяет правило, для истории нужен бэкфилл;
    • рейтинг показывается целым числом;
    • в общем топе убран столбец «Поб», «Очки» → «Рейтинг».
  • Раздел 9 теперь «Решения владельца»: все шесть пунктов и их последствия.

На чём основано:

  • python docs/rating/simulate.py — exit 0, все 15 примеров и проверка шкалы проходят; таблицы 7.3 взяты из этого прогона.
  • python docs/rating/simulate.py --grid --grid-seasons 40 — exit 0; таблицы 7.4 взяты из этого прогона.
  • Изменены только docs/rating/.

Открытые вопросы: нет. Стоит глянуть два места, которые вывел я сам, а не вы:

  • бэкфилл last_standing для старых партий: у них вырастет вес победы, так как отрыв по целям = 1;
  • правило «ровно один невыбывший ⇔ last_standing» проверяется и на сервере, а не только в интерфейсе.

Статус: Status/In Review — жду вашего утверждения; мёрж PR закроет задачу. После мёржа документ будет выложен комментарием в #23.

Доработка по замечаниям завершена, PR обновлён: https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/65 — документ [`docs/rating/rating-system.md`](https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/src/branch/issue-22-rating-proposal/docs/rating/rating-system.md). **Вывод:** предложение согласовано с вашими решениями, открытых вопросов не осталось. - **Поле дуэли 2×3.** Учтено в правилах, примерах и симуляции. Метрики сдвинулись на тысячные, выводы прежние: ρ после 10 партий — 0.807 против 0.769 у текущей системы, в «клубах» — 0.644 против 0.525. - **Шкала 1500.** Старт 1500, D = 400, K 64 → 16. Все примеры и таблицы переведены в эту шкалу. Скрипт проверяет, что качество прогноза от шкалы не зависит. - **Раздел 8 (для #23):** - правило `last_standing`: ставится автоматически при одном невыбывшем, вручную не выбирается, сервер проверяет правило, для истории нужен бэкфилл; - рейтинг показывается целым числом; - в общем топе убран столбец «Поб», «Очки» → «Рейтинг». - **Раздел 9** теперь «Решения владельца»: все шесть пунктов и их последствия. **На чём основано:** - `python docs/rating/simulate.py` — exit 0, все 15 примеров и проверка шкалы проходят; таблицы 7.3 взяты из этого прогона. - `python docs/rating/simulate.py --grid --grid-seasons 40` — exit 0; таблицы 7.4 взяты из этого прогона. - Изменены только `docs/rating/`. **Открытые вопросы:** нет. Стоит глянуть два места, которые вывел я сам, а не вы: - бэкфилл `last_standing` для старых партий: у них вырастет вес победы, так как отрыв по целям = 1; - правило «ровно один невыбывший ⇔ `last_standing`» проверяется и на сервере, а не только в интерфейсе. **Статус:** `Status/In Review` — жду вашего утверждения; мёрж PR закроет задачу. После мёржа документ будет выложен комментарием в #23.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Reference: NotBigGhost/ForbiddenStarsApp#22