public async Task Update(ulong winner, ulong loser, bool draw)
        {
            var winnerRank = (await GetRank(winner))?.Rating ?? new Trueskill.TrueskillRating(_gameinfo.DefaultRating.Mean, _gameinfo.DefaultRating.StandardDeviation);
            var loserRank  = (await GetRank(loser))?.Rating ?? new Trueskill.TrueskillRating(_gameinfo.DefaultRating.Mean, _gameinfo.DefaultRating.StandardDeviation);

            var teams = new[] {
                new Dictionary <ulong, Rating> {
                    { winner, new Rating(winnerRank.Mean, winnerRank.StdDev) }
                },
                new Dictionary <ulong, Rating> {
                    { loser, new Rating(loserRank.Mean, loserRank.StdDev) }
                },
            };

            var results = TrueSkillCalculator.CalculateNewRatings(
                _gameinfo,
                teams,
                draw ? new[] { 0, 0 } : new[] { 0, 1 }
                );

            var winnerResult = results[winner];
            var loserResult  = results[loser];

            await SetRank(winner, winnerResult.Mean, winnerResult.StandardDeviation);
            await SetRank(loser, loserResult.Mean, loserResult.StandardDeviation);
        }
Beispiel #2
0
        public IDictionary <Player, Rating> GetNewRatings()
        {
            var redTeam  = new Team <Player>();
            var blueTeam = new Team <Player>();

            foreach (PlayerGameStats p in playerStats)
            {
                if (p.Team == HqmTeam.red)
                {
                    redTeam.AddPlayer(p.Player, new Moserware.Skills.Rating(p.RatingMean, p.RatingStandardDeviation));
                }
                else if (p.Team == HqmTeam.blue)
                {
                    blueTeam.AddPlayer(p.Player, new Moserware.Skills.Rating(p.RatingMean, p.RatingStandardDeviation));
                }
            }
            int redrank    = winner == HqmTeam.red ? 1 : 2;
            int bluerank   = winner == HqmTeam.blue ? 1 : 2;
            var newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(redTeam, blueTeam), redrank, bluerank);

            return(newRatings.ToDictionary(x => x.Key, x => new Rating()
            {
                Mean = x.Value.Mean, StandardDeviation = x.Value.StandardDeviation
            }));
        }
Beispiel #3
0
 private int AdjustRatings(int kills, bool firstTeamWon, GameInfo gameInfo, IEnumerable <IDictionary <Player, Rating> > teams, string name1, string name2)
 {
     if (kills > 0)
     {
         const int team1      = 1;
         const int team2      = 2;
         int       winner     = firstTeamWon ? team1 : team2;
         int       loser      = firstTeamWon ? team2 : team1;
         string    killerName = firstTeamWon ? name1 : name2;
         string    victimName = firstTeamWon ? name2 : name1;
         var       killer     = GetPlayerData(killerName);
         var       victim     = GetPlayerData(victimName);
         killer.Kills++;
         victim.Deaths++;
         var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, winner, loser);
         foreach (var pair in newRatings)
         {
             string name       = (string)pair.Key.Id;
             var    playerData = _PlayerData[name];
             playerData.Rating = pair.Value;
         }
         kills--;
     }
     return(kills);
 }
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return(Page());
            }

            MatchPeople = MatchPeople.Where(x => x.Person.PersonName != null).ToList();
            MatchPeople.ForEach(x => x.Person.PersonName = FirstCharToUpper(x.Person.PersonName));
            _context.MatchPeople.AttachRange(MatchPeople);
            MatchPeople.ForEach(x => x.Person.GetData(_context));

            //abstract this, this is used in Leaderboard
            var newSkills = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, GetTeams(MatchPeople), (int)Result.Win, (int)Result.Loss);

            for (int i = 0; i < MatchPeople.Count(); i++)
            {
                double oldRating = MatchPeople[i].Person.Rating.ConservativeRating;
                MatchPeople[i].Person.Rating = newSkills[MatchPeople[i].Person];
                MatchPeople[i].RatingChange  = MatchPeople[i].Person.Rating.ConservativeRating - oldRating;
                MatchPeople[i].Match         = Match;
                MatchPeople[i].MatchResult   = (i % 2) + 1;
            }

            await _context.SaveChangesAsync();

            return(RedirectToPage("./Result"));
        }
Beispiel #5
0
        private static void OneOnTwoBalancedPartialPlay()
        {
            // This scenario uses the "Partial Play" feature

            var gameInfo = GameInfo.DefaultGameInfo;

            // Player 1 is normal and just has a default rating
            // This player is the only person on the first team

            var p1    = new Player(1);
            var team1 = new Team(p1, gameInfo.DefaultRating);

            // Team 2 is much more interesting. Here we specify that
            // player 2 was on the team, but played for 0% of the game
            // and player 3 was on the team but played for 100% of the
            // game and thus should be updated appropriately.
            var p2 = new Player(2, 0.0);
            var p3 = new Player(3, 1.00);

            var team2 = new Team()
                        .AddPlayer(p2, gameInfo.DefaultRating)
                        .AddPlayer(p3, gameInfo.DefaultRating);

            var teams        = Teams.Concat(team1, team2);
            var newRatings   = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2);
            var matchQuality = TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams);
        }
Beispiel #6
0
        private static void TwoPlayerTestNotDrawn()
        {
            // Here's the most simple case: you have two players and one wins
            // against the other.

            // Let's new up two players. Note that the argument passed into to Player
            // can be anything. This allows you to wrap any object. Here I'm just
            // using a simple integer to represent the player, but you could just as
            // easily pass in a database entity representing a person/user or any
            // other custom class you have.

            var player1 = new Player(1);
            var player2 = new Player(2);

            // The algorithm has several parameters that can be tweaked that are
            // found in the "GameInfo" class. If you're just starting out, simply
            // use the defaults:
            var gameInfo = GameInfo.DefaultGameInfo;

            // A "Team" is a collection of "Player" objects. Here we have a team
            // that consists of single players.

            // Note that for each player on the team, we indicate that they have
            // the "DefaultRating" which means that the algorithm has never seen
            // them before. In a real implementation, you'd pull this previous
            // rating for the player based on the player.Id value. It could come
            // from a database.
            var team1 = new Team(player1, gameInfo.DefaultRating);
            var team2 = new Team(player2, gameInfo.DefaultRating);

            // We bundle up all of our teams together so that we can feed them to
            // the algorithm.
            var teams = Teams.Concat(team1, team2);

            // Before we know the actual results of the game, we can ask the
            // calculator for what it perceives as the quality of the match (higher
            // means more fair/equitable)
            AssertMatchQuality(0.447, TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams));

            // This is the key line. We ask the calculator to calculate new ratings
            // Pay careful attention to the numbers at the end. This indicates that
            // team1 came in first place and team2 came in second place. TrueSkill
            // is flexible and allows scenarios such as team1 and team2 drawing which
            // could be represented as "1,1" since they both came in first place.
            var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2);

            // The result of the calculation is a dictionary mapping the players to
            // their new rating. Here we get the ratings out for each player
            var player1NewRating = newRatings[player1];
            var player2NewRating = newRatings[player2];

            // In a real implementation, you'd store these values in a persistent
            // store like a database (note that you can use the player.Id to map
            // the Player class to the class of your choice.
            AssertRating(29.39583201999924, 7.171475587326186, player1NewRating);
            AssertRating(20.60416798000076, 7.171475587326186, player2NewRating);
        }
Beispiel #7
0
        private static void TwoOnFourOnTwoWinDraw()
        {
            // Let's really take advantage of the algorithm by having three teams play:

            // Default info is fine
            var gameInfo = GameInfo.DefaultGameInfo;

            // The first team:
            var player1 = new Player(1);
            var player2 = new Player(2);

            var team1 = new Team()
                        .AddPlayer(player1, new Rating(40, 4))
                        .AddPlayer(player2, new Rating(45, 3));

            // The second team:
            var player3 = new Player(3);
            var player4 = new Player(4);
            var player5 = new Player(5);
            var player6 = new Player(6);

            var team2 = new Team()
                        .AddPlayer(player3, new Rating(20, 7))
                        .AddPlayer(player4, new Rating(19, 6))
                        .AddPlayer(player5, new Rating(30, 9))
                        .AddPlayer(player6, new Rating(10, 4));

            var player7 = new Player(7);
            var player8 = new Player(8);

            // The third team:
            var team3 = new Team()
                        .AddPlayer(player7, new Rating(50, 5))
                        .AddPlayer(player8, new Rating(30, 2));


            // Put all three teams into one parameter:
            var teams = Teams.Concat(team1, team2, team3);

            // Note that we tell the calculator that there was a first place outcome of team 1, and then team 2 and 3 tied/drew
            var newRatingsWinLose = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2, 2);

            // Winners
            AssertRating(40.877, 3.840, newRatingsWinLose[player1]);
            AssertRating(45.493, 2.934, newRatingsWinLose[player2]);
            AssertRating(19.609, 6.396, newRatingsWinLose[player3]);
            AssertRating(18.712, 5.625, newRatingsWinLose[player4]);
            AssertRating(29.353, 7.673, newRatingsWinLose[player5]);
            AssertRating(9.872, 3.891, newRatingsWinLose[player6]);
            AssertRating(48.830, 4.590, newRatingsWinLose[player7]);
            AssertRating(29.813, 1.976, newRatingsWinLose[player8]);

            // We can even see match quality for the entire match consisting of three teams
            AssertMatchQuality(0.367, TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams));
        }
Beispiel #8
0
        private void SetRating(GameInfo info, Team[] teamArray, int[] rankArray)
        {
            var teams      = Teams.Concat(teamArray);
            var newRatings = TrueSkillCalculator.CalculateNewRatings(info, teams, rankArray);

            foreach (var newRating in newRatings)
            {
                var key = playerIdToRiderIdDic[(int)newRating.Key.Id];
                KyoteiTrueSkillDic[key].Rating = newRating.Value;
            }
        }
Beispiel #9
0
        private static void ThreeOnTwoTests()
        {
            // To make things interesting, here is a team of three people playing
            // a team of two people.
            // Initialize the players on the first team. Remember that the argument
            // passed to the Player constructor can be anything. It's strictly there
            // to help you uniquely identify people.
            var player1 = new Player(1);
            var player2 = new Player(2);
            var player3 = new Player(3);
            // Note the fluent-like API where you can add players to the Team and
            // specify the rating of each using their mean and standard deviation
            // (for more information on these parameters, see the accompanying post
            // http://www.moserware.com/2010/03/computing-your-skill.html )
            var team1 = new Team()
                        .AddPlayer(player1, new Rating(28, 7))
                        .AddPlayer(player2, new Rating(27, 6))
                        .AddPlayer(player3, new Rating(26, 5));
            // Create players for the second team
            var player4 = new Player(4);
            var player5 = new Player(5);
            var team2   = new Team()
                          .AddPlayer(player4, new Rating(30, 4))
                          .AddPlayer(player5, new Rating(31, 3));
            // The default parameters are fine
            var gameInfo = GameInfo.DefaultGameInfo;
            // We only have two teams, combine the teams into one parameter
            var teams = Teams.Concat(team1, team2);
            // Specify that the outcome was a 1st and 2nd place
            var newRatingsWinLoseExpected = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2);

            // Winners
            AssertRating(28.658, 6.770, newRatingsWinLoseExpected[player1]);
            AssertRating(27.484, 5.856, newRatingsWinLoseExpected[player2]);
            AssertRating(26.336, 4.917, newRatingsWinLoseExpected[player3]);
            // Losers
            AssertRating(29.785, 3.958, newRatingsWinLoseExpected[player4]);
            AssertRating(30.879, 2.983, newRatingsWinLoseExpected[player5]);
            // For fun, let's see what would have happened if there was an "upset" and the better players lost
            var newRatingsWinLoseUpset = TrueSkillCalculator.CalculateNewRatings(gameInfo, Teams.Concat(team1, team2), 2, 1);

            // Winners
            AssertRating(32.012, 3.877, newRatingsWinLoseUpset[player4]);
            AssertRating(32.132, 2.949, newRatingsWinLoseUpset[player5]);
            // Losers
            AssertRating(21.840, 6.314, newRatingsWinLoseUpset[player1]);
            AssertRating(22.474, 5.575, newRatingsWinLoseUpset[player2]);
            AssertRating(22.857, 4.757, newRatingsWinLoseUpset[player3]);
            // Note that we could have predicted this wasn't a very balanced game ahead of time because
            // it had low match quality.
            AssertMatchQuality(0.254, TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams));
        }
Beispiel #10
0
        private void UpdateTrueSkill(int player1_position, int player2_position)
        {
            // setup teams with updated ratings
            var _team1 = new Team(_player1, _rating1);
            var _team2 = new Team(_player2, _rating2);
            var _teams = Teams.Concat(_team1, _team2);

            // update the ratings
            _rating        = TrueSkillCalculator.CalculateNewRatings(_gameInfo, _teams, player1_position, player2_position);
            _rating1       = _rating [_player1];
            _rating2       = _rating [_player2];
            _match_quality = TrueSkillCalculator.CalculateMatchQuality(_gameInfo, _teams);
        }
Beispiel #11
0
        public static MMgame RateGame(List <MMplayer> t1, List <MMplayer> t2)
        {
            int i     = 0;
            var team1 = new Team();
            var team2 = new Team();

            foreach (var pl in t1)
            {
                team1.AddPlayer(new Player(i), new Rating(pl.MU, pl.SIGMA));
                pl.Games++;
                i++;
            }
            foreach (var pl in t2)
            {
                team2.AddPlayer(new Player(i), new Rating(pl.MU, pl.SIGMA));
                pl.Games++;
                i++;
            }

            var gameInfo = GameInfo.DefaultGameInfo;
            var teams    = Teams.Concat(team1, team2);
            var newRatingsWinLoseExpected = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2);

            MMgame game = new MMgame();

            i = 0;
            foreach (var pl in team1.AsDictionary().Keys)
            {
                var res = newRatingsWinLoseExpected[pl];
                t1[i].EXP   = res.ConservativeRating;
                t1[i].MU    = res.Mean;
                t1[i].SIGMA = res.StandardDeviation;
                game.Team1.Add(new BasePlayer(t1[i]));
                i++;
            }
            i = 0;
            foreach (var pl in team2.AsDictionary().Keys)
            {
                var res = newRatingsWinLoseExpected[pl];
                t2[i].EXP   = res.ConservativeRating;
                t2[i].MU    = res.Mean;
                t2[i].SIGMA = res.StandardDeviation;
                game.Team2.Add(new BasePlayer(t2[i]));
                i++;
            }

            return(game);
        }
Beispiel #12
0
        public override bool Call(string[] arguments)
        {
            if (arguments.Length != 1)
            {
                return(false);
            }

            TeamColor?color = TeamColorExtensions.FromString(arguments[0]);

            if (!color.HasValue)
            {
                Console.WriteLine("Color not found");
                return(false);
            }

            IDictionary <Player, Rating> newRating = TrueSkillCalculator.CalculateNewRatings(
                GameInfo.DefaultGameInfo,
                Matchmaker.Logic.Teams.ConvertToMoserware(),
                color.Value is TeamColor.Blue ? 1 : 2,
                color.Value is TeamColor.Red ? 1 : 2);

            using (Context context = new Context())
            {
                foreach (KeyValuePair <Player, Rating> player in newRating)
                {
                    Participant participant = context.Participants.Find(player.Key.Id);

                    if (participant == null)
                    {
                        Console.WriteLine($"Failed to find player {player.Key.Id.ToString()}");

                        continue;
                    }

                    participant.Mean = player.Value.Mean;
                    participant.StandardDeviation = player.Value.StandardDeviation;
                    participant.Rating            = player.Value.ConservativeRating;
                }

                context.SaveChanges();
            }

            Console.WriteLine("Updated rating for all players");

            return(true);
        }
Beispiel #13
0
        public IActionResult Update(Match match)
        {
            // Lookup Gameinfo
            var game = _gameService.Get(match.GameId);

            if (game == null)
            {
                return(NotFound());
            }

            GameInfo gameInfo = new GameInfo(game.InitialMean, game.InitialStd, game.Beta, game.DynamicsFactor, game.DrawProbability);

            Dictionary <string, APIPlayer> apiPlayers = new Dictionary <string, APIPlayer>();
            List <Team> moserTeams     = new List <Team>();
            List <int>  moserTeamRanks = new List <int>();

            match.Teams.ForEach(apiteam => {
                var moserTeam = new Team();
                apiteam.Players.ForEach(playerId => {
                    var apiplayer = _playerService.Get(playerId);
                    apiPlayers.Add(playerId, apiplayer);
                    moserTeam.AddPlayer(new Player(apiplayer.Id), new Rating(apiplayer.Rating.Mean, apiplayer.Rating.Std));
                });
                moserTeams.Add(moserTeam);
                moserTeamRanks.Add(apiteam.MatchRank);
            });

            var teams = Teams.Concat(moserTeams.ToArray());

            var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, moserTeamRanks.ToArray());

            foreach (KeyValuePair <Player, Rating> newRating in newRatings)
            {
                APIPlayer player;
                apiPlayers.TryGetValue(newRating.Key.Id.ToString(), out player);
                player.Rating = new APIRating {
                    Mean       = newRating.Value.Mean,
                    Std        = newRating.Value.StandardDeviation,
                    Multiplier = newRating.Value.ConservativeRating
                };
                _playerService.Update(player.Id, player);
            }

            return(NoContent());
        }
        public async Task ApplyChallengeResults(ulong challengeId)
        {
            // Convert all solutions for the current challenge into a set of relevant data
            var teamRanks = await _solutions.GetSolutions(challengeId, uint.MaxValue)
                            .AsAsyncEnumerable()
                            .OrderBy(a => a.Rank)
                            .SelectAwait(async a => new {
                player = a.Solution.UserId,
                rank   = a.Rank,
                rating = Convert(await GetOrAddRating(a.Solution.UserId)),
            })
                            .Select(a => new {
                team = new Dictionary <ulong, Rating> {
                    { a.player, a.rating }
                },
                a.rank
            }).ToArrayAsync();

            // Trueskill can't be applied if there were less than 2 entrants
            if (teamRanks.Length > 1)
            {
                // Extract the data out of that into separate collections
                var teams = teamRanks.Select(a => a.team).ToArray();
                var ranks = teamRanks.Select(a => (int)a.rank).ToArray();

                // Calculate trueskill ratings
                var results = TrueSkillCalculator.CalculateNewRatings(
                    GameInfo.DefaultGameInfo,
                    teams,
                    ranks
                    );

                // Update database with new ratings
                foreach (var(key, rating) in results)
                {
                    await _ratings.SetRating(key, rating.Mean, rating.StandardDeviation);
                }
            }

            // Decay rank of all players who did not participate in this challenge
            await _ratings.Decay(4);
        }
Beispiel #15
0
        public async Task <IActionResult> PutPlayerInt([FromBody] TeamListModel TeamList)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }
            var         gameInfo  = GameInfo.DefaultGameInfo;
            List <Team> teamList  = new List <Team>();
            List <int>  positions = new List <int>();

            foreach (ResultTeam team in TeamList.TeamList)
            {
                var team1 = new Team();

                foreach (string ID in team.PlayerIds)
                {
                    var player = await _context.Player.Include(e => e.Rating)
                                 .FirstOrDefaultAsync(e => e.PlayfabId == ID);

                    team1.AddPlayer(player, player.Rating);
                }
                teamList.Add(team1);
                positions.Add(team.Place);
            }
            var teams      = Teams.Concat(teamList.ToArray());
            var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, positions);

            foreach (KeyValuePair <Player, Rating> item in newRatings)
            {
                item.Key.Rating = item.Value;
                _context.Entry(item.Key).State = EntityState.Modified;
            }
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                return(NotFound());
            }
            return(Ok(newRatings));
        }
Beispiel #16
0
        public static async Task <MMgame> GenMatch(List <MMplayer> qplayers, int size)
        {
            List <MMplayer> result = new List <MMplayer>();
            int             c      = 0;

            List <MMplayer> players = new List <MMplayer>();

            players = qplayers.Where(x => x.Game == null).ToList();

            if (players.Count < size)
            {
                return(null);
            }

            double bestquality = 0;

            return(await Task.Run(() => {
                while (true)
                {
                    c++;
                    int i = 0;
                    var team1 = new Team();
                    var team2 = new Team();

                    var rnd = new Random();
                    List <MMplayer> thisresult = new List <MMplayer>(players.Select(x => new { value = x, order = rnd.Next() })
                                                                     .OrderBy(x => x.order).Select(x => x.value).Take(size).ToList());


                    foreach (var pl in thisresult)
                    {
                        if (i < result.Count() / 2)
                        {
                            team1.AddPlayer(new Player(i), new Rating(pl.MU, pl.SIGMA));
                        }
                        else
                        {
                            team2.AddPlayer(new Player(i), new Rating(pl.MU, pl.SIGMA));
                        }
                        i++;
                    }

                    var gameInfo = GameInfo.DefaultGameInfo;
                    var teams = Teams.Concat(team1, team2);

                    double thisquality = TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams);

                    if (thisquality > bestquality)
                    {
                        bestquality = thisquality;
                        result = new List <MMplayer>(thisresult);
                    }

                    if (c > 10 && bestquality > 0.5)
                    {
                        break;
                    }
                    if (c > 50 && bestquality > 0.4)
                    {
                        break;
                    }
                    if (c > 200)
                    {
                        break;
                    }
                }

                MMgame game = new MMgame();
                game.Quality = bestquality;
                game.ID = 1;
                int j = 0;
                foreach (var pl in result)
                {
                    if (j < result.Count() / 2)
                    {
                        game.Team1.Add(new BasePlayer(pl));
                    }
                    else
                    {
                        game.Team2.Add(new BasePlayer(pl));
                    }
                    j++;
                }

                return game;
            }));
        }
Beispiel #17
0
        public void Play(ColdBot.Models.Magic.Command command, String channel)
        {
            var teams          = new List <Team>();
            var decks          = command.Decks;
            var gameMode       = command.GameMode;
            var ratings        = getRatings(decks, gameMode, channel);
            int playersPerTeam = command.GameMode.ShortName.Equals("ffa") ? 1 : 2;

            if (ratings == null)
            {
                slackService.SendMessage("Rating were not properly fetched. The game was not recorded.", channel);
                return;
            }

            if (decks.Count % playersPerTeam != 0)
            {
                slackService.SendMessage("Actual numbers players are not divisible by players per team. The game was not recorded.", channel);
                return;
            }

            var playersWithRating = new List <Tuple <Player, Rating> >();

            // Player names and their rating from the database to TrueSkill objects
            for (int i = 0; i < decks.Count; i++)
            {
                var player = new Player(decks[i].Player.Name);
                var rating = new Rating(ratings[i].Mean, ratings[i].StandardDeviation);
                playersWithRating.Add((new Tuple <Player, Rating>(player, rating)));
            }

            // Divide players to teams
            while (playersWithRating.Count > 0)
            {
                var playersInTeam = new List <Tuple <Player, Rating> >();

                for (int i = 0; i < playersPerTeam; i++)
                {
                    playersInTeam.Add(new Tuple <Player, Rating>(playersWithRating[0].Item1, playersWithRating[0].Item2));
                    playersWithRating.RemoveAt(0);
                }

                var team = new Team();

                foreach (var player in playersInTeam)
                {
                    team.AddPlayer(player.Item1, player.Item2);
                }

                teams.Add(team);
            }

            // Calculate new rating
            var newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(teams.ToArray()), generateRanking(teams.Count).ToArray());

            // For each new rating match with fetched ratings and update values in DB
            foreach (var playerWithRating in newRatings)
            {
                var rating = ratings
                             .Where(x => x.Player.Name.ToLower().Equals(playerWithRating.Key.Id.ToString().ToLower()))
                             .Where(x => x.GameMode.Equals(gameMode))
                             .FirstOrDefault();

                rating.Mean = playerWithRating.Value.Mean;
                rating.StandardDeviation  = playerWithRating.Value.StandardDeviation;
                rating.ConservativeRating = playerWithRating.Value.ConservativeRating;
            }

            context.SaveChanges();
        }
Beispiel #18
0
        /// <summary>
        /// Gets players that are most suited for competition (would provide as close as possible to an even match).  Both @candidates and @target need to have the TSCharacterComponent attached.
        /// </summary>
        /// <param name="candidates">the possible candidates to match against</param>
        /// <param name="target">the player for whom we wish to find matches</param>
        /// <returns>a list of character IDs in order of </returns>
        public static List <SkillMatchInfo> GetTopQualityMatches(IEnumerable <ICharacterInfo> candidates, ICharacterInfo target, int maxResults)
        {
            DateTime start = DateTime.UtcNow;
            List <SkillMatchInfo> matches = new List <SkillMatchInfo>();

            try
            {
                GameInfo gi = GameInfo.DefaultGameInfo;

                Player targetPlayer  = new Player(target.ID);
                double targetMu      = target.Properties.GetDoubleProperty((int)TSPropertyID.RatingMean).GetValueOrDefault();
                double targetSigma   = target.Properties.GetDoubleProperty((int)TSPropertyID.RatingStandardDeviation).GetValueOrDefault();
                Rating targetRating  = new Rating(targetMu, targetSigma);
                Team   targetTeam    = new Team(targetPlayer, targetRating);
                int    numCandidates = 0;

                IEnumerator <ICharacterInfo> enu = candidates.GetEnumerator();
                while (enu.MoveNext())
                {
                    numCandidates++;
                    Player player  = new Player(enu.Current.ID);
                    double mu      = enu.Current.Properties.GetDoubleProperty((int)TSPropertyID.RatingMean).GetValueOrDefault();
                    double sigma   = enu.Current.Properties.GetDoubleProperty((int)TSPropertyID.RatingStandardDeviation).GetValueOrDefault();
                    Rating rating  = new Rating(mu, sigma);
                    Team   team    = new Team(player, rating);
                    double quality = TrueSkillCalculator.CalculateMatchQuality(gi, Teams.Concat(targetTeam, team));

                    matches.Add(new SkillMatchInfo(enu.Current.ID, quality));
                }

                // Sort it
                matches.OrderBy(i => i.MatchQuality);

                // trim it, if necessary
                if (maxResults > 0)
                {
                    if (maxResults > matches.Count)
                    {
                        maxResults = matches.Count;
                    }

                    matches = matches.GetRange(0, maxResults - 1);
                }

                DateTime end            = DateTime.UtcNow;
                TimeSpan exeTime        = end - start;
                int      highestQuality = 0;
                if (matches.Count > 0)
                {
                    highestQuality = (int)Math.Floor(matches[0].MatchQuality * 100);
                }

                Log.LogMsg("TrueSkill match maker tested [" + numCandidates + "] candidates for character [" + target.CharacterName + " | " + target.ID + "]. Returned [" + matches.Count + "] possible matches in [" + exeTime.TotalMilliseconds + " ms]. Best match found had a [" + highestQuality + "%] quality rating.");
            }
            catch (Exception e)
            {
                Log.LogMsg("TrueSkill match maker encountered an error when searching for match candidates. " + e.Message);
            }

            return(matches);
        }
Beispiel #19
0
        public void UpdateMetrics(Models.Team Team1, Models.Team Team2, int Score1, int Score2)
        {
            using (var dbContext = new Foostats2.Models.FoostatsContext()){
                Team1 = dbContext.Teams.Include(x => x.Player1).Include(x => x.Player2).SingleOrDefault(x => x.Id == Team1.Id);
                Team2 = dbContext.Teams.Include(x => x.Player1).Include(x => x.Player2).SingleOrDefault(x => x.Id == Team2.Id); // reload

                var gameInfo      = GameInfo.DefaultGameInfo;
                var t1p1Trueskill = dbContext.Trueskill.
                                    Include(x => x.Player).
                                    FirstOrDefault(x => x.Player.Id == Team1.Player1.Id);
                var t1p2Trueskill = Team1.Player2 == null ? null :
                                    dbContext.Trueskill.
                                    Include(x => x.Player).
                                    FirstOrDefault(x => x.Player.Id == Team1.Player2.Id);
                var t2p1Trueskill = dbContext.Trueskill.
                                    Include(x => x.Player).
                                    FirstOrDefault(x => x.Player.Id == Team2.Player1.Id);
                var t2p2Trueskill = Team2.Player2 == null ? null :
                                    dbContext.Trueskill.
                                    Include(x => x.Player).
                                    FirstOrDefault(x => x.Player.Id == Team2.Player2.Id);
                Rating t1p1, t1p2, t2p1, t2p2;
                t1p1 = t1p1Trueskill != null ? new Rating(t1p1Trueskill.Mean, t1p1Trueskill.StandardDeviation) : gameInfo.DefaultRating;
                t1p2 = t1p2Trueskill != null ? new Rating(t1p2Trueskill.Mean, t1p2Trueskill.StandardDeviation) : gameInfo.DefaultRating;
                t2p1 = t2p1Trueskill != null ? new Rating(t2p1Trueskill.Mean, t2p1Trueskill.StandardDeviation) : gameInfo.DefaultRating;
                t2p2 = t2p2Trueskill != null ? new Rating(t2p2Trueskill.Mean, t2p2Trueskill.StandardDeviation) : gameInfo.DefaultRating;

                var team1player1 = new Player(Team1.Player1.Id);
                var team1player2 = Team1.Player2 == null ? null : new Player(Team1.Player2.Id);
                var team2player1 = new Player(Team2.Player1.Id);
                var team2player2 = Team2.Player2 == null ? null : new Player(Team2.Player2.Id);

                var team1 = new Team();
                team1.AddPlayer(team1player1, t1p1);
                if (team1player2 != null)
                {
                    team1.AddPlayer(team1player2, t1p2);
                }

                var team2 = new Team();
                team2.AddPlayer(team2player1, t2p1);
                if (team2player2 != null)
                {
                    team2.AddPlayer(team2player2, t2p2);
                }

                var teams = Teams.Concat(team1, team2);

                var team1Place = Score1 >= Score2 ? 1 : 2;
                var team2Place = Score2 >= Score1 ? 1 : 2;
                var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, team1Place, team2Place);

                var    team1player1NewRating = newRatings[team1player1];
                Rating team1player2NewRating = team1player2 == null ? null : newRatings[team1player2];
                var    team2player1NewRating = newRatings[team2player1];
                Rating team2player2NewRating = team2player2 == null ? null : newRatings[team2player2];


                if (t1p1Trueskill != null)
                {
                    t1p1Trueskill.Mean = team1player1NewRating.Mean;
                    t1p1Trueskill.StandardDeviation  = team1player1NewRating.StandardDeviation;
                    t1p1Trueskill.ConservativeRating = team1player1NewRating.ConservativeRating;
                }
                else
                {
                    dbContext.Trueskill.Add(new Models.Trueskill()
                    {
                        Player             = Team1.Player1,
                        Mean               = team1player1NewRating.Mean,
                        StandardDeviation  = team1player1NewRating.StandardDeviation,
                        ConservativeRating = team1player1NewRating.ConservativeRating
                    });
                }

                if (team1player2 != null)
                {
                    if (t1p2Trueskill != null)
                    {
                        t1p2Trueskill.Mean = team1player2NewRating.Mean;
                        t1p2Trueskill.StandardDeviation  = team1player2NewRating.StandardDeviation;
                        t1p2Trueskill.ConservativeRating = team1player2NewRating.ConservativeRating;
                    }
                    else
                    {
                        dbContext.Trueskill.Add(new Models.Trueskill()
                        {
                            Player             = Team1.Player2,
                            Mean               = team1player2NewRating.Mean,
                            StandardDeviation  = team1player2NewRating.StandardDeviation,
                            ConservativeRating = team1player2NewRating.ConservativeRating
                        });
                    }
                }

                if (t2p1Trueskill != null)
                {
                    t2p1Trueskill.Mean = team2player1NewRating.Mean;
                    t2p1Trueskill.StandardDeviation  = team2player1NewRating.StandardDeviation;
                    t2p1Trueskill.ConservativeRating = team2player1NewRating.ConservativeRating;
                }
                else
                {
                    dbContext.Trueskill.Add(new Models.Trueskill()
                    {
                        Player             = Team2.Player1,
                        Mean               = team2player1NewRating.Mean,
                        StandardDeviation  = team2player1NewRating.StandardDeviation,
                        ConservativeRating = team2player1NewRating.ConservativeRating
                    });
                }

                if (team2player2 != null)
                {
                    if (t2p2Trueskill != null)
                    {
                        t2p2Trueskill.Mean = team2player2NewRating.Mean;
                        t2p2Trueskill.StandardDeviation  = team2player2NewRating.StandardDeviation;
                        t2p2Trueskill.ConservativeRating = team2player2NewRating.ConservativeRating;
                    }
                    else
                    {
                        dbContext.Trueskill.Add(new Models.Trueskill()
                        {
                            Player             = Team2.Player2,
                            Mean               = team2player2NewRating.Mean,
                            StandardDeviation  = team2player2NewRating.StandardDeviation,
                            ConservativeRating = team2player2NewRating.ConservativeRating
                        });
                    }
                }

                dbContext.SaveChanges();
            }
        }
Beispiel #20
0
        public static void recalcMatches(List <Person> playerList, List <Match> matchList, Double startMu, Double startSigma, Double multiplier, UInt16 decay, UInt32 decayValue, DateTime lastDate, ProgressBar progress)
        {
            lastDate += new TimeSpan(23, 59, 59);

            Dictionary <String, Person> playerMap = new Dictionary <string, Person>();
            DateTime latestMatch = DateTime.MinValue;
            int      matchTotal  = matchList.Count;
            int      counted     = 0;

            if (progress != null)
            {
                progress.Value = 0;
                progress.Refresh();
            }

            foreach (Person person in playerList)
            {
                person.Mu          = startMu;
                person.Sigma       = startSigma;
                person.Wins        = 0;
                person.Losses      = 0;
                person.Draws       = 0;
                person.Multiplier  = multiplier;
                person.DecayDays   = 0;
                person.DecayMonths = 0;

                playerMap.Add(person.Name, person);
            }

            foreach (Match match in matchList)
            {
                if (progress != null)
                {
                    counted++;
                    progress.Value = (counted * 100) / matchTotal;
                    progress.PerformStep();
                }

                if (match.Timestamp <= lastDate)
                {
                    Person p1 = playerMap[match.Player1];
                    Person p2 = playerMap[match.Player2];

                    if (decay > 0)
                    {
                        uint i = 0;
                        if (decay < 3)
                        {
                            while (p1.LastMatch.AddDays(i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p1.DecayDays += i;
                            i             = 0;
                            while (p2.LastMatch.AddDays(i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p2.DecayDays += i;
                        }
                        else
                        {
                            i = 0;
                            while (p1.LastMatch.AddMonths((int)i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p1.DecayMonths += i;
                            i = 0;
                            while (p2.LastMatch.AddMonths((int)i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p2.DecayMonths += i;
                        }

                        switch (decay)
                        {
                        case 1:
                            while (p1.DecayDays > decayValue - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayDays -= decayValue;
                            }
                            while (p2.DecayDays > decayValue - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayDays -= decayValue;
                            }
                            break;

                        case 2:
                            while (p1.DecayDays > (7 * decayValue) - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayDays -= 7 * decayValue;
                            }
                            while (p2.DecayDays > (7 * decayValue) - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayDays -= 7 * decayValue;
                            }
                            break;

                        case 3:
                            while (p1.DecayMonths > decayValue - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayMonths -= decayValue;
                            }
                            while (p2.DecayMonths > decayValue - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayMonths -= decayValue;
                            }
                            break;

                        case 4:
                            while (p1.DecayMonths > (12 * decayValue) - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayMonths -= 12 * decayValue;
                            }
                            while (p2.DecayMonths > (12 * decayValue) - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayMonths -= 12 * decayValue;
                            }
                            break;
                        }
                    }

                    match.P1Score = p1.Score;
                    match.P2Score = p2.Score;

                    Player p1s = new Player(1);
                    Player p2s = new Player(2);
                    Rating p1r = new Rating(p1.Mu, p1.Sigma);
                    Rating p2r = new Rating(p2.Mu, p2.Sigma);
                    Team   t1  = new Team(p1s, p1r);
                    Team   t2  = new Team(p2s, p2r);

                    IDictionary <Player, Rating> newRatings = null;

                    if (match.Winner == 0)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 1, 1);
                    }
                    else if (match.Winner == 1)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 1, 2);
                    }
                    else if (match.Winner == 2)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 2, 1);
                    }

                    p1.Mu    = newRatings[p1s].Mean;
                    p1.Sigma = newRatings[p1s].StandardDeviation;
                    p2.Mu    = newRatings[p2s].Mean;
                    p2.Sigma = newRatings[p2s].StandardDeviation;

                    match.P1Score2 = p1.Score;
                    match.P2Score2 = p2.Score;

                    p1.LastMatch = match.Timestamp;
                    p2.LastMatch = match.Timestamp;
                    if (latestMatch < match.Timestamp)
                    {
                        latestMatch = match.Timestamp;
                    }

                    if (match.Winner == 0)
                    {
                        p1.Draws++;
                        p2.Draws++;
                    }
                    else if (match.Winner == 1)
                    {
                        p1.Wins++;
                        p2.Losses++;
                    }
                    else if (match.Winner == 2)
                    {
                        p1.Losses++;
                        p2.Wins++;
                    }
                }
                else
                {
                    break;
                }
            }

            foreach (Person p in playerList)
            {
                if (decay > 0)
                {
                    uint i = 0;
                    while (p.LastMatch.AddDays(i).CompareTo(latestMatch) < 0)
                    {
                        i++;
                    }
                    p.DecayDays += i;
                    i            = 0;
                    while (p.LastMatch.AddMonths((int)i).CompareTo(latestMatch) < 0)
                    {
                        i++;
                    }
                    p.DecayMonths += i;

                    switch (decay)
                    {
                    case 1:
                        while (p.DecayDays > 0)
                        {
                            p.decayScore(startSigma);
                            p.DecayDays--;
                        }
                        break;

                    case 2:
                        while (p.DecayDays > 6)
                        {
                            p.decayScore(startSigma);
                            p.DecayDays -= 7;
                        }
                        break;

                    case 3:
                        while (p.DecayMonths > 0)
                        {
                            p.decayScore(startSigma);
                            p.DecayMonths--;
                        }
                        break;

                    case 4:
                        while (p.DecayMonths > 11)
                        {
                            p.decayScore(startSigma);
                            p.DecayMonths -= 12;
                        }
                        break;
                    }
                }
            }
        }
Beispiel #21
0
 public static double GetRatingFor(List <Participant> redPlayers, List <Participant> bluePlayers)
 {
     return(TrueSkillCalculator.CalculateMatchQuality(
                GameInfo.DefaultGameInfo,
                ConvertToMoserware(bluePlayers, redPlayers)));
 }
Beispiel #22
0
 public static double GetRatingFor(IEnumerable <IDictionary <Player, Rating> > teams)
 {
     return(TrueSkillCalculator.CalculateMatchQuality(
                GameInfo.DefaultGameInfo,
                teams));
 }
Beispiel #23
0
        public static void recalcMatches(List <Person> playerList, List <Match> matchList, Double startMu, Double startSigma, Double multiplier, UInt16 decay, UInt32 decayValue, DateTime lastDate, ProgressBar progress)
        {
            lastDate += new TimeSpan(23, 59, 59);

            Dictionary <String, Person> playerMap = new Dictionary <string, Person>();
            DateTime latestMatch = DateTime.MinValue;
            int      matchTotal  = matchList.Count;
            int      counted     = 0;

            if (progress != null)
            {
                progress.Value = 0;
                progress.Refresh();
            }

            foreach (Person person in playerList)
            {
                person.Mu          = startMu;
                person.Sigma       = startSigma;
                person.Wins        = 0;
                person.Losses      = 0;
                person.Draws       = 0;
                person.Multiplier  = multiplier;
                person.DecayDays   = 0;
                person.DecayMonths = 0;

                playerMap.Add(person.Name, person);
            }

            foreach (Match match in matchList)
            {
                if (progress != null)
                {
                    counted++;
                    progress.Value = (counted * 100) / matchTotal;
                    progress.PerformStep();
                }

                if (match.Timestamp <= lastDate)
                {
                    Person p1 = playerMap[match.Player1];
                    Person p2 = playerMap[match.Player2];

                    //Explained on line 177
                    p1.DecayDays   = 0;
                    p2.DecayDays   = 0;
                    p1.DecayMonths = 0;
                    p2.DecayMonths = 0;

                    if (decay > 0)
                    {
                        uint i = 0;
                        if (decay < 3)
                        {
                            while (p1.LastMatch.AddDays(i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p1.DecayDays += i;
                            i             = 0;
                            while (p2.LastMatch.AddDays(i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p2.DecayDays += i;
                        }
                        else
                        {
                            i = 0;
                            while (p1.LastMatch.AddMonths((int)i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p1.DecayMonths += i;
                            i = 0;
                            while (p2.LastMatch.AddMonths((int)i).CompareTo(match.Timestamp) < 0)
                            {
                                i++;
                            }
                            p2.DecayMonths += i;
                        }

                        switch (decay)
                        {
                        case 1:
                            while (p1.DecayDays > decayValue - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayDays -= decayValue;
                            }
                            while (p2.DecayDays > decayValue - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayDays -= decayValue;
                            }
                            break;

                        case 2:
                            while (p1.DecayDays > (7 * decayValue) - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayDays -= 7 * decayValue;
                            }
                            while (p2.DecayDays > (7 * decayValue) - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayDays -= 7 * decayValue;
                            }
                            break;

                        case 3:
                            while (p1.DecayMonths > decayValue - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayMonths -= decayValue;
                            }
                            while (p2.DecayMonths > decayValue - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayMonths -= decayValue;
                            }
                            break;

                        case 4:
                            while (p1.DecayMonths > (12 * decayValue) - 1)
                            {
                                p1.decayScore(startSigma);
                                p1.DecayMonths -= 12 * decayValue;
                            }
                            while (p2.DecayMonths > (12 * decayValue) - 1)
                            {
                                p2.decayScore(startSigma);
                                p2.DecayMonths -= 12 * decayValue;
                            }
                            break;
                        }
                    }

                    /*
                     * Correction to v1.0.1.6:
                     * While decayDays/Months can be removed if they exceed the decayInterval,
                     * if they do not they remain in the players cummulative decayDays/Months.
                     * This means that players that would ordinarily not receive decay would.
                     *
                     * Ex. 6 Days between Matches with a week decayInterval.
                     * Day 0  | Match 1 : No decayDays; No decay
                     * DecayDays for player: 0
                     * Day 6  | Match 2 : +6 decayDays; 6 > 7 days for week interval? No; No decay
                     * DecayDays for player: 6
                     * Day 12 | Match 3 : +6 decayDays; 12 > 7? Yes; unexpected decay
                     * DecayDays for player: 5
                     *
                     * To correct this after each player is selected from the match they will have
                     * the decayDays/Months reset on line 85 and 246.
                     */
                    match.P1Score = p1.Score;
                    match.P2Score = p2.Score;

                    Player p1s = new Player(1);
                    Player p2s = new Player(2);
                    Rating p1r = new Rating(p1.Mu, p1.Sigma);
                    Rating p2r = new Rating(p2.Mu, p2.Sigma);
                    Team   t1  = new Team(p1s, p1r);
                    Team   t2  = new Team(p2s, p2r);

                    IDictionary <Player, Rating> newRatings = null;

                    if (match.Winner == 0)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 1, 1);
                    }
                    else if (match.Winner == 1)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 1, 2);
                    }
                    else if (match.Winner == 2)
                    {
                        newRatings = TrueSkillCalculator.CalculateNewRatings(GameInfo.DefaultGameInfo, Teams.Concat(t1, t2), 2, 1);
                    }

                    p1.Mu    = newRatings[p1s].Mean;
                    p1.Sigma = newRatings[p1s].StandardDeviation;
                    p2.Mu    = newRatings[p2s].Mean;
                    p2.Sigma = newRatings[p2s].StandardDeviation;

                    match.P1Score2 = p1.Score;
                    match.P2Score2 = p2.Score;

                    p1.LastMatch = match.Timestamp;
                    p2.LastMatch = match.Timestamp;
                    if (latestMatch < match.Timestamp)
                    {
                        latestMatch = match.Timestamp;
                    }

                    if (match.Winner == 0)
                    {
                        p1.Draws++;
                        p2.Draws++;
                    }
                    else if (match.Winner == 1)
                    {
                        p1.Wins++;
                        p2.Losses++;
                    }
                    else if (match.Winner == 2)
                    {
                        p1.Losses++;
                        p2.Wins++;
                    }
                }
                else
                {
                    break;
                }
            }

            foreach (Person p in playerList)
            {
                //Explained on line 177
                p.DecayDays   = 0;
                p.DecayMonths = 0;
                if (decay > 0)
                {
                    uint i = 0;
                    while (p.LastMatch.AddDays(i).CompareTo(latestMatch) < 0)
                    {
                        i++;
                    }
                    p.DecayDays += i;
                    i            = 0;
                    while (p.LastMatch.AddMonths((int)i).CompareTo(latestMatch) < 0)
                    {
                        i++;
                    }
                    p.DecayMonths += i;

                    switch (decay)
                    {
                    /*
                     * Correction to v1.0.1.6:
                     * To correct 7 days and 1 week decayIntervals not yielding the same score,
                     * it was found that the final player score adjustment did not take into
                     * account the decayValue like in the match-to-match decay.  This was added.
                     */
                    case 1:
                        while (p.DecayDays > decayValue - 1)
                        {
                            p.decayScore(startSigma);
                            p.DecayDays -= decayValue;
                        }
                        break;

                    case 2:
                        while (p.DecayDays > (7 * decayValue) - 1)
                        {
                            p.decayScore(startSigma);
                            p.DecayDays -= 7 * decayValue;
                        }
                        break;

                    case 3:
                        while (p.DecayMonths > decayValue - 1)
                        {
                            p.decayScore(startSigma);
                            p.DecayMonths -= decayValue;
                        }
                        break;

                    case 4:
                        while (p.DecayMonths > (12 * decayValue) - 1)
                        {
                            p.decayScore(startSigma);
                            p.DecayMonths -= 12 * decayValue;
                        }
                        break;
                    }
                }
            }
        }
Beispiel #24
0
        public static MMgameNG RateGame(Team team1, Team team2, string lobby, StartUp _mm, bool cmdr = false)
        {
            var gameInfo = GameInfo.DefaultGameInfo;
            var teams    = Teams.Concat(team1, team2);
            var newRatingsWinLoseExpected = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, 1, 2);

            MMgameNG game = new MMgameNG();

            game.Lobby = lobby;
            int i = 0;

            foreach (var pl in team1.AsDictionary().Keys)
            {
                var        res   = newRatingsWinLoseExpected[pl];
                string     name  = pl.Id.ToString();
                MMplayerNG mpl   = new MMplayerNG();
                MMPlRating plrat = new MMPlRating();
                if (_mm.MMplayers.ContainsKey(name))
                {
                    mpl      = _mm.MMplayers[name];
                    plrat    = mpl.Rating[lobby].LastOrDefault().ShallowCopy();
                    plrat.Db = false;
                }
                else
                {
                    mpl.Name = "Dummy" + i;
                }

                if (cmdr == true)
                {
                    mpl      = _mm.MMraces[name];
                    plrat    = mpl.Rating[lobby].LastOrDefault().ShallowCopy();
                    plrat.Db = false;
                }

                double temp = plrat.EXP;
                plrat.EXP     = res.ConservativeRating;
                mpl.ExpChange = plrat.EXP - temp;
                plrat.MU      = res.Mean;
                plrat.SIGMA   = res.StandardDeviation;
                plrat.Games++;
                plrat.Time = DateTime.UtcNow;
                mpl.Rating[lobby].Add(plrat);
                game.Team1.Add(mpl);
                i++;
            }
            foreach (var pl in team2.AsDictionary().Keys)
            {
                var        res   = newRatingsWinLoseExpected[pl];
                string     name  = pl.Id.ToString();
                MMplayerNG mpl   = new MMplayerNG();
                MMPlRating plrat = new MMPlRating();
                if (_mm.MMplayers.ContainsKey(name))
                {
                    mpl      = _mm.MMplayers[name];
                    plrat    = mpl.Rating[lobby].LastOrDefault().ShallowCopy();
                    plrat.Db = false;
                }
                else
                {
                    mpl.Name = "Dummy" + i;
                }

                if (cmdr == true)
                {
                    mpl      = _mm.MMraces[name];
                    plrat    = mpl.Rating[lobby].LastOrDefault().ShallowCopy();
                    plrat.Db = false;
                }

                double temp = plrat.EXP;
                plrat.EXP     = res.ConservativeRating;
                mpl.ExpChange = plrat.EXP - temp;
                plrat.MU      = res.Mean;
                plrat.SIGMA   = res.StandardDeviation;
                plrat.Games++;
                plrat.Time = DateTime.UtcNow;
                mpl.Rating[lobby].Add(plrat);
                game.Team2.Add(mpl);
                i++;
            }

            return(game);
        }
        public async Task <ReplayData> TwoPlayerTestNotDrawn(ReplayData data, string type, Dictionary <string, uint> mmrIds, Dictionary <string, string> role)
        {
            // The algorithm has several parameters that can be tweaked that are
            // found in the "GameInfo" class. If you're just starting out, simply
            // use the defaults:
            var gameInfo = GameInfo.DefaultGameInfo;


            // Here's the most simple case: you have two players and one wins
            // against the other.

            // Let's new up two players. Note that the argument passed into to Player
            // can be anything. This allows you to wrap any object. Here I'm just
            // using a simple integer to represent the player, but you could just as
            // easily pass in a database entity representing a person/user or any
            var playerRatings = new Rating[10];

            for (var i = 0; i < 10; i++)
            {
                _playerMmRs[i]    = 0;
                _playerConserv[i] = 0;
                playerRatings[i]  = gameInfo.DefaultRating;
            }

            for (var i = 0; i < 10; i++)
            {
                _typeId = type switch
                {
                    "player" => mmrIds["player"],
                    "hero" => mmrIds[data.ReplayPlayer[i].Hero],
                    "role" => mmrIds[role[data.ReplayPlayer[i].Hero]],
                    _ => _typeId
                };

                var masterMmrData = await _context.MasterMmrData.Where(x => x.TypeValue == _typeId &&
                                                                       x.GameType.ToString() == data.GameTypeId &&
                                                                       x.BlizzId == data.ReplayPlayer[i].BlizzId &&
                                                                       x.Region == data.Region).ToListAsync();

                var count = 0;
                foreach (var mmrData in masterMmrData)
                {
                    _playerConserv[count] = mmrData.ConservativeRating;
                    playerRatings[count]  = new Rating(mmrData.Mean, mmrData.StandardDeviation);
                    count++;
                }
            }

            _teamOneWinner = data.ReplayPlayer[0].Winner;
            _teamTwoWinner = data.ReplayPlayer[9].Winner;

            var players = new Player[10];

            for (var i = 0; i < 10; i++)
            {
                players[i] = new Player(i);
            }

            var team1 = new Team()
                        .AddPlayer(players[0], playerRatings[0])
                        .AddPlayer(players[1], playerRatings[1])
                        .AddPlayer(players[2], playerRatings[2])
                        .AddPlayer(players[3], playerRatings[3])
                        .AddPlayer(players[4], playerRatings[4]);

            var team2 = new Team()
                        .AddPlayer(players[5], playerRatings[5])
                        .AddPlayer(players[6], playerRatings[6])
                        .AddPlayer(players[7], playerRatings[7])
                        .AddPlayer(players[8], playerRatings[8])
                        .AddPlayer(players[9], playerRatings[9]);


            // A "Team" is a collection of "Player" objects. Here we have a team
            // that consists of single players.

            // Note that for each player on the team, we indicate that they have
            // the "DefaultRating" which means that the algorithm has never seen
            // them before. In a real implementation, you'd pull this previous
            // rating for the player based on the player.Id value. It could come
            // from a database.

            //Rating r1 = new Rating();



            // We bundle up all of our teams together so that we can feed them to
            // the algorithm.
            var teams = Teams.Concat(team1, team2);

            // Before we know the actual results of the game, we can ask the
            // calculator for what it perceives as the quality of the match (higher
            // means more fair/equitable)
            //AssertMatchQuality(0.447, TrueSkillCalculator.CalculateMatchQuality(gameInfo, teams));

            // This is the key line. We ask the calculator to calculate new ratings
            // Pay careful attention to the numbers at the end. This indicates that
            // team1 came in first place and team2 came in second place. TrueSkill
            // is flexible and allows scenarios such as team1 and team2 drawing which
            // could be represented as "1,1" since they both came in first place.
            var teamOneValue = 2;
            var teamTwoValue = 2;

            if (_teamOneWinner)
            {
                teamOneValue = 1;
            }
            else if (_teamTwoWinner)
            {
                teamTwoValue = 1;
            }

            var newRatings = TrueSkillCalculator.CalculateNewRatings(gameInfo, teams, teamOneValue, teamTwoValue);

            // The result of the calculation is a dictionary mapping the players to
            // their new rating. Here we get the ratings out for each player


            var playerNewRatings = new Rating[10];

            for (var i = 0; i < 10; i++)
            {
                playerNewRatings[i] = newRatings[players[i]];

                switch (type)
                {
                case "player":
                    data.ReplayPlayer[i].PlayerConservativeRating = playerNewRatings[i].ConservativeRating;
                    data.ReplayPlayer[i].PlayerMean = playerNewRatings[i].Mean;
                    data.ReplayPlayer[i].PlayerStandardDeviation = playerNewRatings[i].StandardDeviation;
                    break;

                case "role":
                    data.ReplayPlayer[i].RoleConservativeRating = playerNewRatings[i].ConservativeRating;
                    data.ReplayPlayer[i].RoleMean = playerNewRatings[i].Mean;
                    data.ReplayPlayer[i].RoleStandardDeviation = playerNewRatings[i].StandardDeviation;
                    break;

                case "hero":
                    data.ReplayPlayer[i].HeroConservativeRating = playerNewRatings[i].ConservativeRating;
                    data.ReplayPlayer[i].HeroMean = playerNewRatings[i].Mean;
                    data.ReplayPlayer[i].HeroStandardDeviation = playerNewRatings[i].StandardDeviation;
                    break;
                }
            }

            return(data);
        }
    }