public void Player1WinsPlayer2_AssertPlayer1GainsElo() { var match = new EloMatch(); var player1Identifier = match.AddPlayer(1200, 1); var player2Identifier = match.AddPlayer(1300, 2); var result = match.Calculate(); var player1EloDiff = result.GetRatingDifference(player1Identifier); var player2EloDiff = result.GetRatingDifference(player2Identifier); Assert.Greater(player1EloDiff, player2EloDiff); }
public void TwoPlayerScenario() { var match = new EloMatch(); var player1Identifier = match.AddPlayer(1200, true); var player2Identifier = match.AddPlayer(1320, false); var result = match.Calculate(); var player1EloDifference = result.GetRatingDifference(player1Identifier); var player2EloDifference = result.GetRatingDifference(player2Identifier); Assert.Greater(player1EloDifference, player2EloDifference); }
private async Task <GameHistory> ComputeNewUserPoints(GameHistory gameHistory) { var users = new Dictionary <string, User>(); foreach (var(playerId, player) in gameHistory.Summary.Players) { users[playerId] = await this.Repository.GetUserById(player.WebsiteId !.Value).ConfigureAwait(false); } var match = new EloMatch(); var eloPlayers = gameHistory.Summary.Players.Aggregate(new Dictionary <string, IEloPlayer>(), (acc, kvp) => { var user = users[kvp.Key]; acc[kvp.Key] = match.AddPlayer(kvp.Value.Rank, user.Points); return(acc); }); match.ComputeElos(); foreach (var(playerId, player) in gameHistory.Summary.Players) { player.Points = eloPlayers[playerId].NewElo; player.DeltaPoints = eloPlayers[playerId].EloChange; } return(gameHistory); }
public void ThreePlayerScenario() { var match = new EloMatch(); var player1Identifier = match.AddPlayer(1280, 1); var player2Identifier = match.AddPlayer(1300, 2); var player3Identifier = match.AddPlayer(1220, 3); var result = match.Calculate(); var player1NewRating = result.GetRatingAfter(player1Identifier); var player2NewRating = result.GetRatingAfter(player2Identifier); var player3NewRating = result.GetRatingAfter(player3Identifier); Assert.Greater(player1NewRating, 1280); Assert.Less(player2NewRating, 1300); Assert.Less(player3NewRating, 1220); }
public void MultiMatch_100Contestants_DoesNotThrow() { var match = new EloMatch(); Assert.DoesNotThrow(() => { for (var i = 0; i < 100; i++) { _ = match.AddPlayer(i + 1200, i == 0 ? true : false); } var result = match.Calculate(); }); }
public void AddPlayer(int playerId, int rank) { var elo = GetCurrentEloForPlayer(playerId); _match.AddPlayer(playerId, rank, elo); }
public async Task GenerateEloRatingsForAllGamesAsync(ulong guildId, bool erasePreviousRatings = false) { // todo: call into GenerateEloRatingsForGameAsync rather than duplicating all the logic var db = new GameBotDbContext(); var gameModes = new List <GameMode> { GameMode.Variable, GameMode.SuddenDeath, GameMode.Standard }; foreach (var gameMode in gameModes) { var games = await db.Games.AsQueryable() .Include(g => g.GamePlayers) .ThenInclude(gp => gp.Player) .ThenInclude(p => p.EloRatings) .Where(g => g.GuildId == guildId) .Where(g => g.IsRanked && g.State == 3) .Where(g => g.Penalty == (int)(object)gameMode) .Where(g => g.GamePlayers.Count() >= 4) .Where(g => !g.GamePlayers.Any(gp => gp.Rank == null)) .OrderBy(g => g.Id) .ToListAsync(); var ratings = new Dictionary <string, int>(); games.ForEach(game => { Console.WriteLine($"========================================"); Console.WriteLine($"Calculating Elo for game {game.Id}"); var match = new EloMatch(); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; if (!ratings.ContainsKey(nickname)) { var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString()); if (erasePreviousRatings) { ratings.Add(nickname, 1500); } else { ratings.Add(nickname, currentEloRating?.Rating ?? 1500); } } gamePlayer.PreGameEloRating = ratings[nickname]; //Console.WriteLine($"Adding {nickname} with {ratings[nickname]} rating and rank of {gamePlayer.Rank}"); match.AddPlayer(nickname, gamePlayer.Rank.Value, ratings[nickname]); } match.CalculateElos(); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; ratings[nickname] = match.GetElo(nickname); gamePlayer.PostGameEloRating = ratings[nickname]; gamePlayer.EloChange = match.GetEloChange(nickname); var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString()); if (currentEloRating != null) { currentEloRating.Rating = match.GetElo(nickname); } else { gamePlayer.Player.EloRatings.Add(new EloRating { GameMode = gameMode.ToString(), Rating = match.GetElo(nickname) }); } Console.WriteLine($"{nickname} has new rating of {ratings[nickname]} ({match.GetEloChange(nickname)})"); } }); var changes = db.SaveChanges(); Console.WriteLine($"========================================"); Console.WriteLine($"Final {gameMode} ratings:"); var i = 1; foreach (var rating in ratings.OrderByDescending(x => x.Value)) { Console.WriteLine($"{i}: {rating.Key}: {rating.Value}"); i++; } Console.WriteLine($"========================================"); } }
public async Task GenerateEloRatingsForGameAsync(int gameId) { var db = new GameBotDbContext(); var game = await db.Games.AsQueryable() .Include(g => g.GamePlayers) .ThenInclude(gp => gp.Player) .ThenInclude(p => p.EloRatings) .Where(g => g.IsRanked && g.State == 3) .Where(g => g.GamePlayers.Count() >= 4) .Where(g => !g.GamePlayers.Any(gp => gp.Rank == null)) .Where(g => g.Id == gameId) .SingleOrDefaultAsync(); var ratings = new Dictionary <string, int>(); var gameMode = (GameMode)game.Penalty; Console.WriteLine($"========================================"); Console.WriteLine($"Calculating Elo for game {game.Id}"); var match = new EloMatch(); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; if (!ratings.ContainsKey(nickname)) { var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString()); ratings.Add(nickname, currentEloRating?.Rating ?? 1500); } gamePlayer.PreGameEloRating = ratings[nickname]; Console.WriteLine($"Adding {nickname} with {ratings[nickname]} rating and rank of {gamePlayer.Rank}"); match.AddPlayer(nickname, gamePlayer.Rank.Value, ratings[nickname]); } match.CalculateElos(); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; ratings[nickname] = match.GetElo(nickname); gamePlayer.PostGameEloRating = ratings[nickname]; gamePlayer.EloChange = match.GetEloChange(nickname); var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString()); if (currentEloRating != null) { currentEloRating.Rating = match.GetElo(nickname); } else { gamePlayer.Player.EloRatings.Add(new EloRating { GameMode = gameMode.ToString(), Rating = match.GetElo(nickname) }); } Console.WriteLine($"{nickname} has new rating of {ratings[nickname]} ({match.GetEloChange(nickname)})"); } var changes = db.SaveChanges(); Console.WriteLine($"{changes} changes written"); Console.WriteLine($"========================================"); }
public void Manual() { // Calculating Elo for game 356 //Jon has new rating of 1564(8) //Cody has new rating of 1524(6) //mj has new rating of 1464(6) //Josh has new rating of 1464(3) //Calvin has new rating of 1478(-1) //Mo has new rating of 1530(-6) //Dave has new rating of 1508(-8) //Em has new rating of 1443(-9) Debug.WriteLine("Ties at bottom"); var match = new EloMatch(); match.AddPlayer("Jon", 1, 1556); match.AddPlayer("Cody", 2, 1518); match.AddPlayer("mj", 3, 1458); match.AddPlayer("Josh", 4, 1461); match.AddPlayer("Calvin", 5, 1479); match.AddPlayer("Mo", 6, 1536); match.AddPlayer("Dave", 7, 1516); match.AddPlayer("Em", 8, 1452); match.CalculateElos(20); Debug.WriteLine($"Jon: {match.GetElo("Jon")} ({match.GetEloChange("Jon")})"); Debug.WriteLine($"Cody: {match.GetElo("Cody")} ({match.GetEloChange("Cody")})"); Debug.WriteLine($"mj: {match.GetElo("mj")} ({match.GetEloChange("mj")})"); Debug.WriteLine($"Josh: {match.GetElo("Josh")} ({match.GetEloChange("Josh")})"); Debug.WriteLine($"Calvin: {match.GetElo("Calvin")} ({match.GetEloChange("Calvin")})"); Debug.WriteLine($"Mo: {match.GetElo("Mo")} ({match.GetEloChange("Mo")})"); Debug.WriteLine($"Dave: {match.GetElo("Dave")} ({match.GetEloChange("Dave")})"); Debug.WriteLine($"Em: {match.GetElo("Em")} ({match.GetEloChange("Em")})"); //Debug.WriteLine($"Em: {match.GetElo("Em")} ({match.GetEloChange("Em")})"); //Debug.WriteLine("Regular rankings"); //var match2 = new EloMatch(); //match2.AddPlayer("Jon", 1, 1500); //match2.AddPlayer("Dave", 2, 1500); //match2.AddPlayer("Ed", 3, 1500); //match2.AddPlayer("Em", 4, 1500); //match2.AddPlayer("Cody", 5, 1500); //match2.AddPlayer("MJ", 6, 1500); //match2.AddPlayer("Andrey", 7, 1500); //match2.AddPlayer("Lauren", 8, 1500); //match2.AddPlayer("Autumn", 9, 1500); //match2.CalculateElos(20); //Debug.WriteLine($"Jon: {match2.GetElo("Jon")} ({match2.GetEloChange("Jon")})"); //Debug.WriteLine($"Dave: {match2.GetElo("Dave")} ({match2.GetEloChange("Dave")})"); //Debug.WriteLine($"Ed: {match2.GetElo("Ed")} ({match2.GetEloChange("Ed")})"); //Debug.WriteLine($"Em: {match2.GetElo("Em")} ({match2.GetEloChange("Em")})"); //Debug.WriteLine($"Cody: {match2.GetElo("Cody")} ({match2.GetEloChange("Cody")})"); //Debug.WriteLine($"MJ: {match2.GetElo("MJ")} ({match2.GetEloChange("MJ")})"); //Debug.WriteLine($"Andrey: {match2.GetElo("Andrey")} ({match2.GetEloChange("Andrey")})"); //Debug.WriteLine($"Lauren: {match2.GetElo("Lauren")} ({match2.GetEloChange("Lauren")})"); //Debug.WriteLine($"Autumn: {match2.GetElo("Autumn")} ({match2.GetEloChange("Autumn")})"); }
public void GenerateRatings(GameMode gameMode, int initialK) { ulong guildId = 689504722163335196; var db = new PerudoBot.Data.GameBotDbContext(); var games = db.Games.AsQueryable() .Include(g => g.GamePlayers) .ThenInclude(gp => gp.Player) .ThenInclude(p => p.EloRatings) .Where(g => g.GuildId == guildId) .Where(g => g.IsRanked && g.State == 3) .Where(g => g.Penalty == (int)(object)gameMode) .Where(g => g.GamePlayers.Count() > 3) //&& g.GamePlayers.Count() < 8) // .Where(g => g.Id == 338) .Where(g => !g.GamePlayers.Any(gp => gp.Rank == null)) //.OrderByDescending(g => g.Id) //.Take(10) .OrderBy(g => g.Id) .ToList(); //Debug.WriteLine($"========================================"); //Debug.WriteLine($"Generating Elo Ratings for {gameMode}"); var ratings = new Dictionary <string, int>(); games.ForEach(game => { //var outputGame = false; //if (games.OrderByDescending(g => g.Id).Take(5).ToList().Contains(game.Id)) Debug.WriteLine($"========================================"); Debug.WriteLine($"Calculating Elo for game {game.Id}"); var match = new EloMatch(); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; if (!ratings.ContainsKey(nickname)) { var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString() && 1 == 2); ratings.Add(nickname, currentEloRating?.Rating ?? 1500); } gamePlayer.PreGameEloRating = ratings[nickname]; //Debug.WriteLine($"Adding {nickname} with {ratings[nickname]} rating and rank of {gamePlayer.Rank}"); match.AddPlayer(nickname, gamePlayer.Rank.Value, ratings[nickname]); } match.CalculateElos(initialK); foreach (var gamePlayer in game.GamePlayers.OrderBy(gp => gp.Rank)) { var nickname = gamePlayer.Player.Nickname; ratings[nickname] = match.GetElo(nickname); gamePlayer.PostGameEloRating = ratings[nickname]; gamePlayer.EloChange = gamePlayer.PostGameEloRating - gamePlayer.PreGameEloRating; var currentEloRating = gamePlayer.Player.EloRatings .FirstOrDefault(er => er.GameMode == gameMode.ToString()).Rating = match.GetElo(nickname); Debug.WriteLineIf(game.Id == games.Max(x => x.Id) || 1 == 2, $"{nickname} has new rating of {ratings[nickname]} ({match.GetEloChange(nickname)})"); } }); // var changes = db.SaveChanges(); // Debug.WriteLine($"Wrote {changes} to the db"); Debug.WriteLine($"========================================"); Debug.WriteLine($"Final {gameMode} ratings: K={initialK}"); var i = 1; foreach (var rating in ratings.OrderByDescending(x => x.Value)) { Debug.WriteLine($"{i}: {rating.Key}: {rating.Value}"); i++; } Debug.WriteLine($"========================================"); }