Кривая потерь по регламенту 31.10 (решение №14)

Бой (модуль Battle):
- доля выбывших каждого типа — плавная функция соотношения итоговых сил (сильная / слабая)
  по опорным точкам регламента: 1:1 — 45% / 45%, 3:1 — 16% / 74%, 5:1 — 11% / 88% (ТЕСТ);
  между точками линейно, без порогов-переключателей; одинаково для PvE, PvP и Круга
- заменяет «проигравший теряет 50%, победитель до 50%»
- считается точной дробью, округление потерь — как прежде шансом (№13)
- за 5:1 — значения последней точки (рост разгрома дальше не задан — вопрос команде)

Таблица BattleConfig: точки кривой (lossRatioPermille, strongLossPermille, weakLossPermille)
вместо loserLossPercent; некорректная таблица — значения по умолчанию. Версия правил 4.

Раненых пока нет: все выбывшие — погибшие. Раненые (№15) — следующим шагом вместе с госпиталем,
нужен контракт с Населением (Валдемар), чтобы раненые учитывались среди людей города.

Тесты: опорные точки, симметрия, плавность и монотонность, кривая из таблицы и защита от ошибки;
тесты округления пересчитаны под кривую. Все 47 тестов ModuleTests проходят вне Unity.
Код Валдемара не менялся.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alexander
2026-10-31 15:54:37 +01:00
co-authored by Claude Opus 5.5
parent 8e9dbdf1cf
commit d9c0039bd2
7 changed files with 165 additions and 49 deletions
+15 -12
View File
@@ -62,31 +62,31 @@
| Голод и усталость вместе | Последовательно: 50% × 80% = **40%** силы (а не 30%). |
| Порядок | Контры и осадные → бонусы стороны → состояния (голод, усталость) → случайность. |
| Исход | Побеждает тот, у кого итоговая сила больше; ничья — защитнику. |
| Потери проигравшего | Половина каждого типа (не окончательно: №14 — плавная функция и разгром, ждём кривую). |
| Потери победителя | Половина × (сила проигравшего / сила победителя): чем ровнее бой, тем больше потерь, но не больше половины. |
| Потери (решение №14, регламент 31.10) | Доля выбывших каждого типа зависит от соотношения итоговых сил (сильная / слабая). Опорные точки (ТЕСТ): **1:1 — 45% / 45%**, **3:1 — 16% / 74%**, **5:1 — 11% / 88%**. Между точками — плавно (линейно по соотношению), без порогов. Одинаково для PvE, PvP и Круга. За 5:1 — как при 5:1. Точки — в `BattleConfig` (`lossRatioPermille`, `strongLossPermille`, `weakLossPermille`). |
| Округление потерь | Решение №13. Целая часть гарантирована, дробная — шанс ещё одной потери. Бросок — из отдельного потока случайности (своя «соль» на сторону и тип войск, не пересекается с удачей), воспроизводим по номеру боя. Одиночка-проигравший (потеря 0,5) гибнет примерно в половине боёв; 3 проигравших (1,5) теряют 1 или 2. |
Примеры (замок Змея Горыныча, гарнизон 20: пехота 8, лучники 6, кавалерия 4, осадные 2, за стенами):
| Атакующие | Сила | Исход | Вернутся |
| Атакующие | Исход | Вернутся (в среднем) | Враг теряет из 20 |
| --- | --- | --- | --- |
| 30 пехоты | 126 против 155 | поражение | 15 |
| 40 пехоты | 168 против 155 | победа | 22 |
| 30 смешанных (12 / 8 / 6 / 4) | 248 против 154 | победа | — |
| 30 пехоты | поражение | 15,5 | 8,3 |
| 40 пехоты | победа в 97% боёв | 22,5 | 9,2 |
| 30 смешанных (12 / 8 / 6 / 4) | победа | 19,1 | 10,8 |
| 78 смешанных | победа | 67,7 | 16,4 |
**Прогноз с учётом случайности** (тот же замок, 10 000 боёв с разными номерами):
| Атакующие | Прогноз | Шанс победы | Сила | Потери |
| --- | --- | --- | --- | --- |
| 30 пехоты | высокий риск поражения | 0% | 119–132 против 147–163 | 15 |
| 30 пехоты | высокий риск поражения | 0% | 119–132 против 147–163 | 14–16 |
| 36 пехоты | исход неясен | 26,5% | 143–158 против 147–163 | 16–18 |
| 40 пехоты | исход неясен | 97,4% | 159–176 против 147–163 | 16–20 |
| 45 пехоты | преимущество | 100% | 179–198 против 147–163 | 16–21 |
| 30 смешанных (12 / 8 / 6 / 4) | преимущество | 100% | 236–260 против 147–162 | 7–13 |
| 40 пехоты | исход неясен | 97,4% | 159–176 против 147–163 | 16–19 |
| 45 пехоты | преимущество | 100% | 179–198 против 147–163 | 18–20 |
| 30 смешанных (12 / 8 / 6 / 4) | преимущество | 100% | 236–260 против 147–162 | 9–14 |
Шанс проверен тестом `Battle_WinChance_MatchesRealBattles`: совпадает с долей побед в 20 000 настоящих боёв с точностью ±2%.
Бой без состава (старые походы, `Attackers` и `Defenders` числами) считается так, будто все — пехота. Без стен 30 против 20 — по-прежнему победа и 20 вернувшихся.
Бой без состава (старые походы, `Attackers` и `Defenders` числами) считается так, будто все — пехота. Без стен 30 против 20 (1,5:1) — победа, возвращаются 18–19.
## События
@@ -107,7 +107,9 @@
- **Номер боя в мультиплеере** должен выдавать сервер: иначе клиент мог бы подбирать удачный.
- **Командный план и ревью от 27.10.2026** (`Bogatyri_Plan_razrabotki.docx`, `Bogatyri_Battle_Army_Review_27-10-2026.docx`): случайность ±5% каждой стороне (воспроизводимая), прогноз риска вместо точного итога, потери от соотношения сил, раненые и погибшие, голод −50%, усталость −20%, числа — в настройки. Делается на этапе 2 плана.
- **Малые отряды** решены (№13): одиночка-проигравший гибнет с шансом по дробной части потерь.
- **Открыто (№14, №15):** кривая потерь и разгром; доля погибших и раненых от тяжести поражения.
- **Сделано 31.10.2026: кривая потерь (№14)** по опорным точкам регламента 31.10. Раненых пока нет: все выбывшие считаются погибшими.
- **Открыто: разгром дальше 5:1.** Регламент даёт точки до 5:1; дальше доли держатся на 11% / 88%. Растёт ли разгром выше (например, до 100% при 10:1) — решает команда.
- **Следующий шаг — раненые (№15)** вместе с госпиталем. Доля погибших среди выбывших (ТЕСТ регламента): уверенная победа ~20%, близкий бой ~30%, поражение 2:1 ~45%, разгром 5:1 ~70%. Чтобы раненые не «пропали» из людей города, их должно учитывать Население (Валдемар) — договориться о контракте до реализации.
- **Утвердить формулу** (контры, стены, осадные, потери) или поправить числа в `BattleSystem.cs`.
- **Бонус героя** пока не передаётся в поход: `GameProgress.ArmyBonus` и сила героя в слое приложения. Нужен способ передать их в `AttackerBonusPercent` — например, через новый контракт или поле похода.
@@ -118,6 +120,7 @@
| Дата | Кто | Что |
| --- | --- | --- |
| 31.10.2026 | Claude | Кривая потерь (решение №14, регламент 31.10): доля выбывших от соотношения итоговых сил по опорным точкам 1:1 — 45% / 45%, 3:1 — 16% / 74%, 5:1 — 11% / 88%, между ними плавно; вместо «проигравший 50%». Точки в `BattleConfig`, неверная таблица — значения по умолчанию. Версия правил 4. Тест `Battle_LossCurve_ControlPointsAndSmoothness`; тесты округления пересчитаны под кривую. |
| 30.10.2026 | Claude | Комплект требований 29.10, решения №11–13: точный шанс победы в прогнозе (`BattleForecast.WinChancePermille`); сила — точной дробью без промежуточного округления; потери — целая часть гарантирована, дробная — шанс из отдельного потока случайности. Версия правил 3. Тесты: шанс совпадает с настоящими боями, сила без округления, округление потерь. |
| 28.10.2026 | Claude | Голод и усталость: `BattleCondition` (флаги), `BattleRequest.AttackerConditions` / `DefenderConditions`, `BattleOutcome.…ConditionPercent`; голод −50%, усталость −20%, вместе 40% (последовательно); числа в `BattleConfig` и `BattleRules` (версия 2). Тесты: штрафы, голод переворачивает бой у нападающего и у защитника, прогноз с голодом. |
| 28.10.2026 | Claude | Этап 2 плана: числа боя — в таблицу `BattleConfig` (`Assets/Resources/BattleConfig.asset`) и `BattleRules` с версией; случайность ±5% каждой стороне из `BattleRequest.Seed`; `Forecast` — прогноз риска; `BattleOutcome` симметричный: до боя, выжившие, погибшие, раненые (пока нули) по типам у обеих сторон, номер боя, версия правил, удача сторон. Тесты: случайность воспроизводима и в пределах ±5%, прогноз не противоречит бою, итог сходится по типам, правила из таблицы. |
+1
View File
@@ -99,6 +99,7 @@ EditMode-тесты: `Assets/Scripts/Modules/Tests/ModuleTests.cs`. Запуск
| Дата | Кто | Что |
| --- | --- | --- |
| 31.10.2026 | Claude | Кривая потерь боя по регламенту 31.10 (решение №14). Обновлён Battle. |
| 30.10.2026 | Claude | Мир по документу 02: события строго по времени после офлайна, время и номер боя в событиях похода, единицы у таймеров; тесты «Готово, когда» (порядок, двойная доставка, таймеры, 0/1 солдат). Обновлены World, Core. |
| 30.10.2026 | Claude | Бой по решениям №11–13 комплекта 29.10: шанс победы, сила без промежуточного округления, округление потерь шансом; голод в офлайн-бою по истории Населения. Обновлены Battle, World, Core. |
| 28.10.2026 | Claude | Население стало частью Поселения, как на схеме Димы: `Settlement/Population`, сборка `Bogatyri.Settlement.Population`. Найм воинов из свободных жителей с гражданским резервом, история голода для боя. Обновлены Settlement, Population, Core. |