Балансировать рейтинги игроков в конкурентной карточной игре непросто, и мы повторяли на пользовательской системе Elo, которая соответствует Sedma, вдохновленному Semice игровому процессу с уникальными показателями производительности.
Что нового в системе Elo?
Динамический K-фактор K-фактор контролирует, насколько быстро корректируются рейтинги. Наша игра адаптирует K на основе вашего текущего рейтинга:
- 1200 Elo: K = 40 (новые игроки настраиваются быстрее)
- 1200–1800 Elo: K = 32 (нормальная настройка)
- 1800–2200 Elo: K = 24 (более стабильный)
- 2200 Elo: K = 16 (очень стабильный)
Ваши обновления Elo — это не просто выигрыш / проигрыш:
- +0.05 за раунд, выигранный 16 (макс +0.15)
- +0.1 за раунд, выигранный 24 (макс +0.2)
- +0.03 за раунд выиграл с 4 и последним (макс +0.09)
Каждый плохой ход применяет небольшой malus (–0.02), ограниченный –0.3.
Бонусное масштабирование Если вы проиграли, но сыграли хорошо? Ваши бонусы по-прежнему применяются, но с силой 10%.
Почему такой подход?
Мы хотим, чтобы Elo отражала то, как вы выигрываете (или проигрываете), а не только результат. Сильная производительность в убытке все равно должна чего-то стоить. Точно так же безрассудные победы со многими плохими ходами не должны повышать рейтинги.
public static void CalculateNewRatings(
ref int ratingA,
ref int ratingB,
bool playerAWon,
int badMovesA,
int badMovesB,
int wonBy16A,
int wonBy16B,
int wonBy24A,
int wonBy24B,
int wonBy4AndLastA,
int wonBy4AndLastB
)
{
// K determines how sensitive the Elo rating is to each match outcome.
// Higher K means faster rating changes (good for new players),
// lower K means more stable ratings (good for experienced players).
int kA = GetKFactor(ratingA);
int kB = GetKFactor(ratingB);
// Bonus and malus coefficients
const float BonusPer16 = 0.05f;
const float BonusPer24 = 0.1f;
const float BonusPer4AndLast = 0.03f;
const float MalusPerBadMove = 0.02f;
// Caps
const float MaxBonus16 = 0.15f;
const float MaxBonus24 = 0.2f;
const float MaxBonus4AndLast = 0.09f;
const float MaxMalus = 0.3f;
float baseScoreA = playerAWon ? 1f : 0f;
float baseScoreB = 1f - baseScoreA;
// Bonus for player A (full if won, 1/10 if lost)
float multiplierA = playerAWon ? 1f : 0.1f;
float bonusA =
Mathf.Min(wonBy16A * BonusPer16, MaxBonus16) +
Mathf.Min(wonBy24A * BonusPer24, MaxBonus24) +
Mathf.Min(wonBy4AndLastA * BonusPer4AndLast, MaxBonus4AndLast);
bonusA *= multiplierA;
// Bonus for player B (full if won, 1/10 if lost)
float multiplierB = playerAWon ? 0.1f : 1f;
float bonusB =
Mathf.Min(wonBy16B * BonusPer16, MaxBonus16) +
Mathf.Min(wonBy24B * BonusPer24, MaxBonus24) +
Mathf.Min(wonBy4AndLastB * BonusPer4AndLast, MaxBonus4AndLast);
bonusB *= multiplierB;
float malusA = Mathf.Min(badMovesA * MalusPerBadMove, MaxMalus);
float malusB = Mathf.Min(badMovesB * MalusPerBadMove, MaxMalus);
float adjustedScoreA = Mathf.Clamp(baseScoreA + bonusA - malusA, 0f, 1f);
float adjustedScoreB = Mathf.Clamp(baseScoreB + bonusB - malusB, 0f, 1f);
double expectedA = 1.0 / (1.0 + Math.Pow(10, (ratingB - ratingA) / 400.0));
double expectedB = 1.0 / (1.0 + Math.Pow(10, (ratingA - ratingB) / 400.0));
//Debug.Log($"[ELO CALCULATION]");
//Debug.Log($"Player A: baseScore={baseScoreA}, bonus={bonusA}, malus={malusA}, adjustedScore={adjustedScoreA}, expected={expectedA}");
//Debug.Log($"Player B: baseScore={baseScoreB}, bonus={bonusB}, malus={malusB}, adjustedScore={adjustedScoreB}, expected={expectedB}");
//Debug.Log($"Old Ratings - A: {ratingA}, B: {ratingB}");
ratingA = (int)Math.Round(ratingA + kA * (adjustedScoreA - expectedA));
ratingB = (int)Math.Round(ratingB + kB * (adjustedScoreB - expectedB));
//Debug.Log($"New Ratings - A: {ratingA}, B: {ratingB}");
}
private static int GetKFactor(int rating)
{
if (rating < 1200) return 40; // Fast adaptation for new players
if (rating < 1800) return 32; // Balanced default for most players
if (rating < 2200) return 24; // More stable for advanced players
return 16; // Very stable for top-ranked
}
Что дальше?
Эта система является экспериментальной! Мы активно настраиваем коэффициенты и можем корректировать:
- Сколько весят бонусы/злоупотребления
- Когда значение K меняется
- Как вести командные матчи или розыгрыши
Мы хотим получить ваши отзывы! Является ли этот рейтинг справедливым? Вы думали, что изменение рейтинга не было оправдано? — Комментируйте ниже или обратитесь к нам — ваш вклад помогает нам усовершенствовать систему!
