예제 #1
0
        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()
                });
            }
        }
예제 #2
0
        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();
    }
예제 #4
0
        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();
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
 public GlickoSystem()
 {
     playerlist = new Dictionary <string, Rating>();
     calculator = new RatingCalculator();
     results    = new RatingPeriodResults();
 }