using UnityEngine; namespace Hallucinate.Game { /// /// Pure logic for Elo rating calculations. /// Follows the 1v1 competitive formula with dynamic K-factor. /// public static class EloSystem { public const int RATING_FLOOR = 100; public const int PLACEMENT_GAMES = 30; public static EloResult Calculate( int ratingA, int ratingB, int gamesPlayedA, int gamesPlayedB, float resultA) // 1=win, 0=lose, 0.5=draw { // 1. Expected Scores float eA = 1f / (1f + Mathf.Pow(10f, (ratingB - ratingA) / 400f)); float eB = 1f - eA; // 2. K-Factors int kA = GetK(ratingA, gamesPlayedA); int kB = GetK(ratingB, gamesPlayedB); // 3. New Ratings int nA = Mathf.Max(RATING_FLOOR, Mathf.RoundToInt(ratingA + kA * (resultA - eA))); int nB = Mathf.Max(RATING_FLOOR, Mathf.RoundToInt(ratingB + kB * ((1f - resultA) - eB))); return new EloResult(nA, nB, nA - ratingA, nB - ratingB); } private static int GetK(int rating, int gamesPlayed) { if (gamesPlayed < PLACEMENT_GAMES) return 40; if (rating < 1200) return 32; if (rating < 2000) return 24; return 16; } public static string GetRank(int rating) { if (rating < 800) return "Iron"; if (rating < 1000) return "Bronze"; if (rating < 1200) return "Silver"; if (rating < 1500) return "Gold"; if (rating < 1800) return "Platinum"; if (rating < 2100) return "Diamond"; return "Master"; } public static string GetRankColor(int rating) { if (rating < 800) return "#8A8A8A"; // Iron if (rating < 1000) return "#CD7F32"; // Bronze if (rating < 1200) return "#C0C0C0"; // Silver if (rating < 1500) return "#FFD700"; // Gold if (rating < 1800) return "#4DC8A0"; // Platinum if (rating < 2100) return "#7B6EE8"; // Diamond return "#E84D8A"; // Master } } }