/// <inheritdoc/> public override IDictionary <TPlayer, Rating> CalculateNewRatings <TPlayer>(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, params int[] teamRanks) { Guard.ArgumentNotNull(gameInfo, "gameInfo"); ValidateTeamCountAndPlayersCountPerTeam(teams); RankSorter.Sort(ref teams, ref teamRanks); List <IDictionary <TPlayer, Rating> > teamList = teams.ToList(); IDictionary <TPlayer, Rating> winningTeam = teamList[0]; TPlayer winner = winningTeam.Keys.First(); Rating winnerPreviousRating = winningTeam[winner]; IDictionary <TPlayer, Rating> losingTeam = teamList[1]; TPlayer loser = losingTeam.Keys.First(); Rating loserPreviousRating = losingTeam[loser]; var wasDraw = (teamRanks[0] == teamRanks[1]); var results = new Dictionary <TPlayer, Rating> { [winner] = CalculateNewRating(gameInfo, winnerPreviousRating, loserPreviousRating, wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Win), [loser] = CalculateNewRating(gameInfo, loserPreviousRating, winnerPreviousRating, wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose) }; return(results); }
/// <summary> /// Calculates the new ELO ratings for players based on the results of a match. /// </summary> /// <typeparam name="TPlayer">The type used to identify the player.</typeparam> /// <param name="gameInfo">Information on how the game calculates win probabilities.</param> /// <param name="teams">A list of teams and their players.</param> /// <param name="teamRanks">The ranks of the teams.</param> /// <returns>A list of players and their new rating.</returns> public override IDictionary <TPlayer, Rating> CalculateNewRatings <TPlayer>(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, params int[] teamRanks) { ValidateTeamCountAndPlayersCountPerTeam(teams); RankSorter.Sort(ref teams, ref teamRanks); var teamsList = teams.ToList(); var deltas = new Dictionary <TPlayer, IDictionary <TPlayer, double> >(); for (var iCurrentTeam = 0; iCurrentTeam < teamsList.Count; ++iCurrentTeam) { for (var iOtherTeam = 0; iOtherTeam < teamsList.Count; ++iOtherTeam) { if (iOtherTeam == iCurrentTeam) { continue; } var currentTeam = teamsList[iCurrentTeam]; var otherTeam = teamsList[iOtherTeam]; var comparison = (PairwiseComparison)Math.Sign(teamRanks[iOtherTeam] - teamRanks[iCurrentTeam]); foreach (var currentTeamPlayerRatingPair in currentTeam) { foreach (var otherTeamPlayerRatingPair in otherTeam) { UpdateDuels(gameInfo, deltas, currentTeamPlayerRatingPair.Key, currentTeamPlayerRatingPair.Value, otherTeamPlayerRatingPair.Key, otherTeamPlayerRatingPair.Value, comparison); } } } } var result = new Dictionary <TPlayer, Rating>(); foreach (var currentTeam in teamsList) { foreach (var currentTeamPlayerPair in currentTeam) { var currentPlayerAverageDuellingDelta = deltas[currentTeamPlayerPair.Key].Values.Average(); result[currentTeamPlayerPair.Key] = new EloRating(currentTeamPlayerPair.Value.Mean + currentPlayerAverageDuellingDelta); } } return(result); }
public override IDictionary <TPlayer, Rating> CalculateNewRatings <TPlayer>(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, params int[] teamRanks) { Guard.ArgumentNotNull(gameInfo, "gameInfo"); ValidateTeamCountAndPlayersCountPerTeam(teams); RankSorter.Sort(ref teams, ref teamRanks); var factorGraph = new TrueSkillFactorGraph <TPlayer>(gameInfo, teams, teamRanks); factorGraph.BuildGraph(); factorGraph.RunSchedule(); var probabilityOfOutCome = factorGraph.GetProbabilityOfRanking(); return(factorGraph.GetUpdatedRatings()); }
/// <summary> /// Calculates the new ELO ratings for players based on the results of a match. /// </summary> /// <typeparam name="TPlayer">The type used to identify the player.</typeparam> /// <param name="gameInfo">Information on how the game calculates win probabilities.</param> /// <param name="teams">A list of teams and their players (in this case should always be two teams with /// one player each).</param> /// <param name="teamRanks">The ranks of the teams (i.e. which player came first and which player came /// second).</param> /// <returns>A list of players and their new rating</returns> public override IDictionary <TPlayer, Rating> CalculateNewRatings <TPlayer>( GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, params int[] teamRanks) { ValidateTeamCountAndPlayersCountPerTeam(teams); RankSorter.Sort(ref teams, ref teamRanks); var result = new Dictionary <TPlayer, Rating>(); var isDraw = (teamRanks[0] == teamRanks[1]); var player1 = teams.First().First(); var player2 = teams.Last().First(); var player1Rating = player1.Value.Mean; var player2Rating = player2.Value.Mean; result[player1.Key] = CalculateNewRating(gameInfo, player1Rating, player2Rating, isDraw ? PairwiseComparison.Draw : PairwiseComparison.Win); result[player2.Key] = CalculateNewRating(gameInfo, player2Rating, player1Rating, isDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose); return(result); }
/// <inheritdoc/> public override IDictionary <TPlayer, Rating> CalculateNewRatings <TPlayer>(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, params int[] teamRanks) { Guard.ArgumentNotNull(gameInfo, "gameInfo"); ValidateTeamCountAndPlayersCountPerTeam(teams); RankSorter.Sort(ref teams, ref teamRanks); var team1 = teams.First(); var team2 = teams.Last(); var wasDraw = (teamRanks[0] == teamRanks[1]); var results = new Dictionary <TPlayer, Rating>(); UpdatePlayerRatings(gameInfo, results, team1, team2, wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Win); UpdatePlayerRatings(gameInfo, results, team2, team1, wasDraw ? PairwiseComparison.Draw : PairwiseComparison.Lose); return(results); }