public IEnumerable <PlayerRankingEntry> DetermineRanking(Records data) { var calculator = new RatingCalculator(); var players = new Dictionary <Player, Rating>(); foreach (var player in data.GetPlayers()) { players[player] = new Rating(calculator); } var results = new RatingPeriodResults(); foreach (var game in data.Games) { foreach (var winner in game.Winners()) { foreach (var loser in game.Losers()) { results.AddResult(players[winner], players[loser]); } } } calculator.UpdateRatings(results); foreach (var player in players) { yield return(new PlayerRankingEntry() { Player = player.Key, Score = player.Value.GetRating() }); } }
static void Main(string[] args) { Console.WriteLine("Hello World!"); // Instantiate a RatingCalculator object. // At instantiation, you can set the default rating for a player's volatility and // the system constant for your game ("τ", which constrains changes in volatility // over time) or just accept the defaults. var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a Rating object for each player. var player1 = new Rating(calculator /* , rating, ratingDeviation, volatility */); var player2 = new Rating(calculator /* , rating, ratingDeviation, volatility */); var player3 = new Rating(calculator /* , rating, ratingDeviation, volatility */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); // Add game results to the RatingPeriodResults object until you reach the end of your rating period. // Use addResult(winner, loser) for games that had an outcome. results.AddResult(player1, player2); // Use addDraw(player1, player2) for games that resulted in a draw. results.AddDraw(player1, player2); // Use addParticipant(player) to add players that played no games in the rating period. results.AddParticipant(player3); // Once you've reached the end of your rating period, call the updateRatings method // against the RatingCalculator; this takes the RatingPeriodResults object as argument. // * Note that the RatingPeriodResults object is cleared down of game results once // the new ratings have been calculated. // * Participants remain within the RatingPeriodResults object, however, and will // have their rating deviations recalculated at the end of future rating periods // even if they don't play any games. This is in-line with Glickman's algorithm. calculator.UpdateRatings(results); // Access the getRating, getRatingDeviation, and getVolatility methods of each // player's Rating to see the new values. var players = new[] { player1, player2, player3 }; for (var index = 0; index < players.Length; index++) { var player = players[index]; Console.WriteLine("Player #" + index + " values: " + player.GetRating() + ", " + player.GetRatingDeviation() + ", " + player.GetVolatility()); } }
private void UpdatePlayersRating(Matches match) { foreach (var player in match.GetAllUsers(datastore)) { player.PreviousSkillRating = player.SkillRating; } var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); var ratingsPlayers = new List <Tuple <Users, Rating> >(); double team1Rating = match.GetTeam1Users(datastore).Sum(x => x.SkillRating) / match.GetTeam1Users(datastore).Count; double team2Rating = match.GetTeam2Users(datastore).Sum(x => x.SkillRating) / match.GetTeam2Users(datastore).Count; double team1RatingsDeviation = match.GetTeam1Users(datastore).Sum(x => x.RatingsDeviation) / match.GetTeam1Users(datastore).Count; double team2RatingsDeviation = match.GetTeam2Users(datastore).Sum(x => x.RatingsDeviation) / match.GetTeam2Users(datastore).Count; double team1Volatility = match.GetTeam1Users(datastore).Sum(x => x.Volatility) / match.GetTeam1Users(datastore).Count; double team2Volatility = match.GetTeam2Users(datastore).Sum(x => x.Volatility) / match.GetTeam2Users(datastore).Count; var team1RatingCalc = new Rating(calculator, team1Rating, team1RatingsDeviation, team1Volatility); var team2RatingCalc = new Rating(calculator, team2Rating, team2RatingsDeviation, team2Volatility); foreach (var player in match.GetTeam1Users(datastore)) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <Users, Rating>(player, playerRating)); if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamOne) { results.AddResult(playerRating, team2RatingCalc); } else if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamTwo) { results.AddResult(team2RatingCalc, playerRating); } } foreach (var player in match.GetTeam2Users(datastore)) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <Users, Rating>(player, playerRating)); if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamOne) { results.AddResult(team1RatingCalc, playerRating); } else if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamTwo) { results.AddResult(playerRating, team1RatingCalc); } } calculator.UpdateRatings(results); foreach (var player in ratingsPlayers) { player.Item1.SkillRating = player.Item2.GetRating(); player.Item1.RatingsDeviation = player.Item2.GetRatingDeviation(); player.Item1.Volatility = player.Item2.GetVolatility(); } datastore.db.SaveChangesAsync(); }
private void UpdatePlayerRatings() { var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); var ratingsPlayers = new List <Tuple <User, Rating> >(); double team1Rating = Team1.Sum(x => x.SkillRating) / Team1.Count; double team2Rating = Team2.Sum(x => x.SkillRating) / Team2.Count; double team1RatingsDeviation = Team1.Sum(x => x.RatingsDeviation) / Team1.Count; double team2RatingsDeviation = Team2.Sum(x => x.RatingsDeviation) / Team2.Count; double team1Volatility = Team1.Sum(x => x.Volatility) / Team1.Count; double team2Volatility = Team2.Sum(x => x.Volatility) / Team2.Count; var team1RatingCalc = new Rating(calculator, team1Rating, team1RatingsDeviation, team1Volatility); var team2RatingCalc = new Rating(calculator, team2Rating, team2RatingsDeviation, team2Volatility); foreach (var player in Team1) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <User, Rating>(player, playerRating)); if (WinningTeam == Team1) { results.AddResult(playerRating, team2RatingCalc); } else if (WinningTeam == Team2) { results.AddResult(team2RatingCalc, playerRating); } } foreach (var player in Team2) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <User, Rating>(player, playerRating)); if (WinningTeam == Team1) { results.AddResult(team1RatingCalc, playerRating); } else if (WinningTeam == Team2) { results.AddResult(playerRating, team1RatingCalc); } } calculator.UpdateRatings(results); foreach (var player in ratingsPlayers) { player.Item1.PreviousSkillRating = player.Item1.SkillRating; player.Item1.SkillRating = player.Item2.GetRating(); player.Item1.RatingsDeviation = player.Item2.GetRatingDeviation(); player.Item1.Volatility = player.Item2.GetVolatility(); db.Users.Update(player.Item1); } db.SaveChanges(); }
public static void CalculateRatingFromStart() { var calculator = new RatingCalculator(); var results = new RatingPeriodResults(); var allChars = new List <CharacterModel>(); var allKillmails = new List <KillmailModel>(); using (var connection = DatabaseConnection.CreateConnection(DbConnectionString)) { var query = @" WITH hours AS ( SELECT generate_series( date_trunc('hour', (SELECT killed_at FROM killmail ORDER BY killed_at LIMIT 1)), date_trunc('hour', (SELECT killed_at FROM killmail ORDER BY killed_at DESC LIMIT 1)), '1 hour'::interval ) AS hour ) SELECT hours.hour, killmail.id, killmail.killed_at, killmail.victim_id, killmail.attacker_id FROM hours LEFT JOIN killmail ON date_trunc('hour', killmail.killed_at) = hours.hour LEFT JOIN killmail AS prev ON prev.killed_at = (SELECT MAX(killed_at) FROM killmail AS k1 WHERE k1.victim_id = killmail.victim_id AND k1.killed_at < killmail.killed_at ) WHERE prev.killed_at IS NULL OR (killmail.killed_at - prev.killed_at) > make_interval(mins => 10) ORDER BY hours.hour, killmail.killed_at ; "; try { allKillmails = connection.Query <KillmailModel>(query) .ToList(); } catch (Exception ex) { Console.WriteLine(ex); } } using (var connection = DatabaseConnection.CreateConnection(DbConnectionString)) { var query = @" SELECT id, name FROM character "; try { allChars = connection.Query <CharacterModel>(query).ToList(); } catch (Exception ex) { Console.WriteLine(ex); } } // Set initial rating and rd for all characters foreach (var character in allChars) { character.rating = new Rating(calculator); } var killmailsGroupedByTimeslice = allKillmails.ToLookup(x => x.Timeslice); foreach (var timesliceGroup in killmailsGroupedByTimeslice) { // Console.WriteLine(timesliceGroup); // No games in rating period. if (timesliceGroup.Count() == 1 && timesliceGroup.First().victim_id == null) { // Perform Rating calculation decay for all characters involved in kills so far calculator.UpdateRatings(results); } else { foreach (var killmailInTimesliceGroup in timesliceGroup) { if (killmailInTimesliceGroup.attacker_id == null) { continue; } // Perform Rating calculation var attacker = allChars.Find(x => x.id == killmailInTimesliceGroup.attacker_id.Value); var victim = allChars.Find(x => x.id == killmailInTimesliceGroup.victim_id.Value); results.AddResult(attacker.rating, victim.rating); // Set updated_at property for later checks on updating rating var timesliceOffset = new TimeSpan(0, 1, 0, 0);; attacker.updated_at = killmailInTimesliceGroup.Timeslice + timesliceOffset; victim.updated_at = killmailInTimesliceGroup.Timeslice + timesliceOffset; } // Perform Rating calculations (includes decay for all characters that are not in rating period if they were involved in kills in earlier timeslices) calculator.UpdateRatings(results); } } foreach (var character in allChars) { InsertRating(character); } }
public GlickoSystem() { playerlist = new Dictionary <string, Rating>(); calculator = new RatingCalculator(); results = new RatingPeriodResults(); }