Last active
January 13, 2025 19:38
-
-
Save daverave1212/312b4d44b0cc44da4df32110809ede02 to your computer and use it in GitHub Desktop.
A generic Match making system made in C# for elo calculations. Simply take this file and use it as in the example.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Use like: | |
| float[] eloChanges = EloSystem.CalculateEloChanges(playerElos: new float[] { 14000, 4500, 11000, 17444, 6969, 21000 }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| float[][] teamsEloChanges1 = EloSystem.CalculateTeamsEloChanges(teamsWithPlayerElos: new[] { team1, team2, team3 }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| float[][] teamsEloChanges2 = EloSystem.CalculateTeamsEloChanges(teamsWithPlayerElos: new float[][] { | |
| new float[] { 14000, 4500 }, | |
| new float[] { 11000, 17444 }, | |
| new float[] { 6969, 21000 }, | |
| }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| */ | |
| using System; | |
| using System.Linq; | |
| public class EloTeam { | |
| public EloPlayer[] players = {}; | |
| // Calculate later | |
| public float _winProbability = -1; | |
| public float _deltaElo = -1; | |
| public EloTeam(float[] playerElos) { | |
| players = playerElos.Select(elo => new EloPlayer(elo)).ToArray(); | |
| } | |
| public EloTeam(EloPlayer[] _players) { | |
| players = _players; | |
| } | |
| public float GetTotalEloWorth() { | |
| float totalElo = 0; | |
| foreach (EloPlayer player in players) { | |
| totalElo += player.elo; | |
| } | |
| return totalElo; | |
| } | |
| public string ToString() { | |
| string message = $"Team with elo={GetTotalEloWorth()} _winProbability={_winProbability} _deltaElo={_deltaElo}"; | |
| foreach (EloPlayer player in players) { | |
| message += $"\n player _deltaElo={player._deltaElo}"; | |
| } | |
| return message; | |
| } | |
| public void CalculatePlayerEloDeltas(float totalEloDelta) { | |
| float totalElo = GetTotalEloWorth(); | |
| foreach (EloPlayer player in players) { | |
| float eloFraction = player.elo / totalElo; | |
| player._deltaElo = eloFraction * totalEloDelta; | |
| } | |
| } | |
| public float[] GetPlayersEloDeltas() { | |
| return players.Select(player => player._deltaElo).ToArray(); | |
| } | |
| public static float CalculateTotalEloTeamsElo(EloTeam[] teams) { | |
| float totalElo = 0; | |
| foreach (EloTeam team in teams) { | |
| totalElo += team.GetTotalEloWorth(); | |
| } | |
| return totalElo; | |
| } | |
| } | |
| public class EloPlayer { | |
| public string name = "Default"; | |
| public float elo = 0; | |
| public float _deltaElo = -1; | |
| public EloPlayer(string name, float elo) { | |
| this.name = name; | |
| this.elo = elo; | |
| } | |
| public EloPlayer(float elo) { | |
| this.elo = elo; | |
| } | |
| } | |
| public class EloSystem | |
| { | |
| public static void Example() | |
| { | |
| var player1 = new EloPlayer("xQn", 14000); | |
| var player2 = new EloPlayer("Heretic", 4500); | |
| var player3 = new EloPlayer("RDU", 11000); | |
| var player4 = new EloPlayer("JeefHS", 17444); | |
| var player5 = new EloPlayer("Bofur", 6969); | |
| var player6 = new EloPlayer("Kripparian", 21000); | |
| EloTeam team1 = new EloTeam(new[] { player1, player2 }); | |
| EloTeam team2 = new EloTeam(new[] { player3, player4 }); | |
| EloTeam team3 = new EloTeam(new[] { player5, player6 }); | |
| Console.WriteLine(team1.GetTotalEloWorth()); | |
| Console.WriteLine(team2.GetTotalEloWorth()); | |
| Console.WriteLine(team3.GetTotalEloWorth()); | |
| Console.Write("Total elo: "); | |
| Console.WriteLine(EloTeam.CalculateTotalEloTeamsElo(new[] { team1, team2, team3 })); | |
| float[] eloChanges = CalculateEloChanges(playerElos: new float[] { 14000, 4500, 11000, 17444, 6969, 21000 }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| float[][] teamsEloChanges1 = CalculateTeamsEloChanges(teamsWithPlayerElos: new[] { team1, team2, team3 }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| float[][] teamsEloChanges2 = CalculateTeamsEloChanges(teamsWithPlayerElos: new float[][] { | |
| new float[] { 14000, 4500 }, | |
| new float[] { 11000, 17444 }, | |
| new float[] { 6969, 21000 }, | |
| }, winnerIndex: 1, eloStakes: 100, isDebug: true); | |
| } | |
| public static float[] CalculateEloChanges(float[] playerElos, float winnerIndex, float eloStakes, bool isDebug=false) { | |
| EloPlayer[] players = playerElos.Select(elo => new EloPlayer(elo)).ToArray(); | |
| EloTeam[] teams = players.Select(player => new EloTeam(new[] { player })).ToArray(); | |
| teams = CalculateTeamsEloChanges(teams, winnerIndex, eloStakes, isDebug); | |
| return teams.Select(team => team._deltaElo).ToArray(); | |
| } | |
| public static float[][] CalculateTeamsEloChanges(float[][] teamsWithPlayerElos, float winnerIndex, float eloStakes, bool isDebug=false) { | |
| EloTeam[] teams = teamsWithPlayerElos.Select(playerElos => new EloTeam(playerElos)).ToArray(); | |
| teams = CalculateTeamsEloChanges(teams, winnerIndex, eloStakes, isDebug); | |
| return teams.Select(team => team.GetPlayersEloDeltas()).ToArray(); | |
| } | |
| public static EloTeam[] CalculateTeamsEloChanges(EloTeam[] teams, float winnerIndex, float eloStakes = 1000, bool isDebug=false) { | |
| // Calculate win probabilities for each team | |
| var totalElo = EloTeam.CalculateTotalEloTeamsElo(teams); | |
| foreach (EloTeam team in teams) { | |
| team._winProbability = team.GetTotalEloWorth() / totalElo; | |
| } | |
| // Calculate team elo changes | |
| for (int i = 0; i < teams.Length; i++) { | |
| var team = teams[i]; | |
| var isWinner = i == winnerIndex; | |
| if (isWinner) { | |
| team._deltaElo = eloStakes * (1 - team._winProbability); | |
| } else { | |
| team._deltaElo = eloStakes * (0 - team._winProbability); | |
| } | |
| } | |
| // Calculate player elo changes | |
| foreach (EloTeam team in teams) { | |
| team.CalculatePlayerEloDeltas(team._deltaElo); | |
| if (isDebug) { | |
| Console.WriteLine(team.ToString()); | |
| } | |
| } | |
| return teams; | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment