Spielerbewertungen in einem kompetitiven Kartenspiel auszugleichen, ist nicht einfach – und wir haben auf einem benutzerdefinierten Elo-System iteriert, das zu Sedma passt, einem von Semice inspirierten Gameplay mit einzigartigen Leistungskennzahlen.
Was ist neu in unserem Elo System?
✅ Dynamischer K-Faktor Der K-Faktor steuert, wie schnell sich die Bewertungen anpassen. Unser Spiel passt K basierend auf Ihrer aktuellen Bewertung an:
- <1200 Elo: K = 40 (neue Spieler passen sich schneller an)
- 1200–1800 Elo: K = 32 (normale Einstellung)
- 1800–2200 Elo: K = 24 (stabiler)
- >2200 Elo: K = 16 (sehr stabil)
Leistungsbasierte Boni Ihr Elo-Update ist nicht nur Gewinn/Verlust:
- +0.05 pro gewonnener Runde mit 16 Punkten (max. +0.15)
- +0.1 pro gewonnener Runde mit 24 Punkten (max. +0.2)
- +0.03 pro gewonnener Runde mit 4 und zuletzt (max. +0.09)
✅ Schlechte Zugstrafen Jeder schlechte Zug wendet einen kleinen Malus (–0.02) an, der auf –0.3 insgesamt begrenzt ist.
✅ Bonus-Skalierung Wenn Sie verlieren, aber gut gespielt haben? Ihre Boni gelten immer noch – aber bei 10% Stärke.
💡 Warum dieser Ansatz?
Wir möchten, dass Elo widerspiegelt, wie Sie gewinnen (oder verlieren), nicht nur das Ergebnis. Eine starke Leistung in einem Verlust sollte immer noch für etwas zählen. Ebenso sollten rücksichtslose Gewinne mit vielen schlechten Zügen die Bewertungen nicht aufblähen.
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
}
Was kommt als nächstes?
⚠️ Dieses System ist experimentell! Wir stimmen die Koeffizienten aktiv ab und können Folgendes anpassen:
- Wie viel Boni/Mauser wiegen
- Wenn sich K-Werte ändern
- Wie man mit Teammatches oder Unentschieden umgeht
💬 Wir wollen dein Feedback! Fühlt sich dieses Rating fair an? Hat ein Spiel Sie denken lassen, dass die Bewertungsänderung nicht gerechtfertigt war? 👉 Kommentar unten oder erreichen Sie – Ihr Input hilft uns, das System zu verfeinern!
