Echilibrarea evaluărilor într-un joc competitiv de cărți nu este ușoară. Am rafinat un sistem Elo propriu, potrivit mecanicii inspirate din Sedma și Sedmice, cu indicatori specifici de performanță.
🎯 Ce este nou în sistemul Elo?
✅ Factor K dinamic. K controlează viteza ajustării evaluării. Jocul îl adaptează după evaluarea curentă:
- Sub 1200 Elo: K = 40 (adaptare mai rapidă pentru începători)
- 1200–1800 Elo: K = 32 (ajustare normală)
- 1800–2200 Elo: K = 24 (mai stabil)
- Peste 2200 Elo: K = 16 (foarte stabil)
✅ Bonusuri de performanță. Actualizarea Elo nu ține doar de victorie sau înfrângere:
- +0.05 pentru fiecare rundă câștigată cu 16 puncte (maxim +0.15)
- +0.1 pentru fiecare rundă câștigată cu 24 de puncte (maxim +0.2)
- +0.03 pentru fiecare rundă câștigată cu 4 și ultima levată (maxim +0.09)
✅ Penalizări pentru mutări greșite. Fiecare greșeală aduce –0.02, până la –0.3 în total.
✅ Ajustarea bonusurilor. Dacă pierzi, dar ai jucat bine, bonusurile se aplică în continuare, la 10% din valoare.
💡 De ce această abordare?
Vrem ca Elo să reflecte cum câștigi sau pierzi, nu doar rezultatul. O performanță bună la înfrângere trebuie să conteze. La fel, victoriile imprudente cu multe greșeli nu ar trebui să umfle evaluarea.
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
}
📝 Ce urmează?
⚠️ Sistemul este experimental! Ajustăm activ coeficienții și putem modifica:
- Ponderea bonusurilor și penalizărilor
- Pragurile factorului K
- Gestionarea meciurilor pe echipe și a egalurilor
💬 Vrem feedback! Evaluarea pare echitabilă? Ai avut un meci în care modificarea părea nejustificată? Lasă un comentariu sau contactează-ne: contribuția ta ne ajută să rafinăm sistemul.
