private void EvaluateMatrix(string path) { string content = File.ReadAllText(path); var pattern = new Regex("([^\"]+) killed ([^\"]+) (\\d+) times, [^\"]+ killed [^\"]+ (\\d+) times"); var matches = pattern.Matches(content); if (matches.Count == 0) { Console.WriteLine("Failed to process {0}", path); return; } foreach (Match match in matches) { var groups = match.Groups; string name1 = groups[1].Value; string name2 = groups[2].Value; int kills1 = int.Parse(groups[3].Value); int kills2 = int.Parse(groups[4].Value); var player1 = new Player(name1); var player2 = new Player(name2); while (kills1 + kills2 > 0) { var playerData1 = GetPlayerData(name1); var playerData2 = GetPlayerData(name2); var team1 = new Team(player1, playerData1.Rating); var team2 = new Team(player2, playerData2.Rating); var teams = Teams.Concat(team1, team2); kills1 = AdjustRatings(kills1, true, GameInfo, teams, name1, name2); kills2 = AdjustRatings(kills2, false, GameInfo, teams, name1, name2); } } Console.WriteLine("Processed {0}", path); }
public static void AssertChessRating(TwoPlayerEloCalculator calculator, double player1BeforeRating, double player2BeforeRating, PairwiseComparison player1Result, double player1AfterRating, double player2AfterRating) { var player1 = new Player(1); var player2 = new Player(2); var teams = Teams.Concat( new Team(player1, new EloRating(player1BeforeRating)), new Team(player2, new EloRating(player2BeforeRating))); var chessGameInfo = new GameInfo(1200, 0, 200, 0, 0); var result = calculator.CalculateNewRatings(chessGameInfo, teams, (player1Result == PairwiseComparison.Win) ? new[] { 1, 2 } : (player1Result == PairwiseComparison.Lose) ? new[] { 2, 1 } : new[] { 1, 1 }); Assert.AreEqual(player1AfterRating, result[player1].Mean, ErrorTolerance); Assert.AreEqual(player2AfterRating, result[player2].Mean, ErrorTolerance); }
private static void OneOnTwoDrawTest(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating); var player2 = new Player(2); var player3 = new Player(3); var team2 = new Team() .AddPlayer(player2, gameInfo.DefaultRating) .AddPlayer(player3, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, new int[] { 1, 1 }); // Winners AssertRating(31.660, 7.138, newRatingsWinLose[player1]); // Losers AssertRating(18.340, 7.138, newRatingsWinLose[player2]); AssertRating(18.340, 7.138, newRatingsWinLose[player3]); AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void OneOnThreeSimpleTest(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player2, gameInfo.DefaultRating) .AddPlayer(player3, gameInfo.DefaultRating) .AddPlayer(player4, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, new int[] { 1, 2 }); // Winners AssertRating(36.337, 7.527, newRatingsWinLose[player1]); // Losers AssertRating(13.663, 7.527, newRatingsWinLose[player2]); AssertRating(13.663, 7.527, newRatingsWinLose[player3]); AssertRating(13.663, 7.527, newRatingsWinLose[player4]); AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams)); }
public override double CalculateMatchQuality <TPlayer>(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams) { // HACK! Need a better algorithm, this is just to have something there and it isn't good double minQuality = 1.0; var teamList = teams.ToList(); for (int ixCurrentTeam = 0; ixCurrentTeam < teamList.Count; ixCurrentTeam++) { EloRating currentTeamAverageRating = new EloRating(teamList[ixCurrentTeam].Values.Average(r => r.Mean)); var currentTeam = new Team(new Player(ixCurrentTeam), currentTeamAverageRating); for (int ixOtherTeam = ixCurrentTeam + 1; ixOtherTeam < teamList.Count; ixOtherTeam++) { EloRating otherTeamAverageRating = new EloRating(teamList[ixOtherTeam].Values.Average(r => r.Mean)); var otherTeam = new Team(new Player(ixOtherTeam), otherTeamAverageRating); minQuality = Math.Min(minQuality, _TwoPlayerEloCalc.CalculateMatchQuality(gameInfo, Teams.Concat(currentTeam, otherTeam))); } } return(minQuality); }
private static void OneOnThreeDrawTest(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player2, gameInfo.DefaultRating) .AddPlayer(player3, gameInfo.DefaultRating) .AddPlayer(player4, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); // Winners AssertRating(34.990, 7.455, newRatingsWinLose[player1]); // Losers AssertRating(15.010, 7.455, newRatingsWinLose[player2]); AssertRating(15.010, 7.455, newRatingsWinLose[player3]); AssertRating(15.010, 7.455, newRatingsWinLose[player4]); AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void TwoOnTwoUpsetTest(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, new Rating(20, 8)) .AddPlayer(player2, new Rating(25, 6)); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player3, new Rating(35, 7)) .AddPlayer(player4, new Rating(40, 5)); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); // Winners AssertRating(29.698, 7.008, newRatingsWinLose[player1]); AssertRating(30.455, 5.594, newRatingsWinLose[player2]); // Losers AssertRating(27.575, 6.346, newRatingsWinLose[player3]); AssertRating(36.211, 4.768, newRatingsWinLose[player4]); AssertMatchQuality(0.084, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void OneOnTwoSomewhatBalanced(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, new Rating(40, 6)); var player2 = new Player(2); var player3 = new Player(3); var team2 = new Team() .AddPlayer(player2, new Rating(20, 7)) .AddPlayer(player3, new Rating(25, 8)); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); // Winners AssertRating(42.744, 5.602, newRatingsWinLose[player1]); // Losers AssertRating(16.266, 6.359, newRatingsWinLose[player2]); AssertRating(20.123, 7.028, newRatingsWinLose[player3]); AssertMatchQuality(0.478, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void ThreeTeamsOfOneDrawn(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team(player1, gameInfo.DefaultRating); var team2 = new Team(player2, gameInfo.DefaultRating); var team3 = new Team(player3, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2, team3); var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1); var player1NewRating = newRatings[player1]; AssertRating(25.000, 5.698, player1NewRating); var player2NewRating = newRatings[player2]; AssertRating(25.000, 5.695, player2NewRating); var player3NewRating = newRatings[player3]; AssertRating(25.000, 5.698, player3NewRating); AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void OneOnTwoSimpleTest(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating); var player2 = new Player(2); var player3 = new Player(3); var team2 = new Team() .AddPlayer(player2, gameInfo.DefaultRating) .AddPlayer(player3, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); // Winners AssertRating(33.730, 7.317, newRatingsWinLose[player1]); // Losers AssertRating(16.270, 7.317, newRatingsWinLose[player2]); AssertRating(16.270, 7.317, newRatingsWinLose[player3]); AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void TwoOnTwoUnbalancedDrawTest(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, new Rating(15, 8)) .AddPlayer(player2, new Rating(20, 6)); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player3, new Rating(25, 4)) .AddPlayer(player4, new Rating(30, 3)); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); // Winners AssertRating(21.570, 6.556, newRatingsWinLose[player1]); AssertRating(23.696, 5.418, newRatingsWinLose[player2]); // Losers AssertRating(23.357, 3.833, newRatingsWinLose[player3]); AssertRating(29.075, 2.931, newRatingsWinLose[player4]); AssertMatchQuality(0.214, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void FourTeamsOfOneNotDrawn(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team(player1, gameInfo.DefaultRating); var team2 = new Team(player2, gameInfo.DefaultRating); var team3 = new Team(player3, gameInfo.DefaultRating); var team4 = new Team(player4, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2, team3, team4); var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4); var player1NewRating = newRatings[player1]; AssertRating(33.206680965631264, 6.3481091698077057, player1NewRating); var player2NewRating = newRatings[player2]; AssertRating(27.401454693843323, 5.7871629348447584, player2NewRating); var player3NewRating = newRatings[player3]; AssertRating(22.598545306188374, 5.7871629348413451, player3NewRating); var player4NewRating = newRatings[player4]; AssertRating(16.793319034361271, 6.3481091698144967, player4NewRating); AssertMatchQuality(0.089, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void OneOnOneMassiveUpsetDrawTest(SkillCalculator calculator) { var player1 = new Player(1); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating); var player2 = new Player(2); var team2 = new Team() .AddPlayer(player2, new Rating(50, 12.5)); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1); // Winners AssertRating(31.662, 7.137, newRatingsWinLose[player1]); // Losers AssertRating(35.010, 7.910, newRatingsWinLose[player2]); AssertMatchQuality(0.110, calculator.CalculateMatchQuality(gameInfo, teams)); }
//------------------------------------------------------------------------------ // Two Team Tests //------------------------------------------------------------------------------ private static void TwoOnTwoSimpleTest(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating) .AddPlayer(player2, gameInfo.DefaultRating); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player3, gameInfo.DefaultRating) .AddPlayer(player4, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); // Winners AssertRating(28.108, 7.774, newRatingsWinLose[player1]); AssertRating(28.108, 7.774, newRatingsWinLose[player2]); // Losers AssertRating(21.892, 7.774, newRatingsWinLose[player3]); AssertRating(21.892, 7.774, newRatingsWinLose[player4]); AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); }
public void TwoOnTwoDuellingTest() { var calculator = new DuellingEloCalculator(new GaussianEloCalculator()); var player1 = new Player(1); var player2 = new Player(2); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating) .AddPlayer(player2, gameInfo.DefaultRating); var player3 = new Player(3); var player4 = new Player(4); var team2 = new Team() .AddPlayer(player3, gameInfo.DefaultRating) .AddPlayer(player4, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, new int[] { 1, 2 }); // TODO: Verify? AssertRating(37, newRatingsWinLose[player1]); AssertRating(37, newRatingsWinLose[player2]); AssertRating(13, newRatingsWinLose[player3]); AssertRating(13, newRatingsWinLose[player4]); var quality = calculator.CalculateMatchQuality(gameInfo, teams); Assert.AreEqual(1.0, quality, 0.001); }
private static void ThreeTeamsOfOneNotDrawn(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team(player1, gameInfo.DefaultRating); var team2 = new Team(player2, gameInfo.DefaultRating); var team3 = new Team(player3, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2, team3); var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3); var player1NewRating = newRatings[player1]; AssertRating(31.675352419172107, 6.6559853776206905, player1NewRating); var player2NewRating = newRatings[player2]; AssertRating(25.000000000003912, 6.2078966412243233, player2NewRating); var player3NewRating = newRatings[player3]; AssertRating(18.324647580823971, 6.6559853776218318, player3NewRating); AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams)); }
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); }
private static void EightTeamsOfOneDrawn(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var player5 = new Player(5); var player6 = new Player(6); var player7 = new Player(7); var player8 = new Player(8); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team(player1, gameInfo.DefaultRating); var team2 = new Team(player2, gameInfo.DefaultRating); var team3 = new Team(player3, gameInfo.DefaultRating); var team4 = new Team(player4, gameInfo.DefaultRating); var team5 = new Team(player5, gameInfo.DefaultRating); var team6 = new Team(player6, gameInfo.DefaultRating); var team7 = new Team(player7, gameInfo.DefaultRating); var team8 = new Team(player8, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8); var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1, 1, 1, 1, 1, 1); var player1NewRating = newRatings[player1]; AssertRating(25.000, 4.592, player1NewRating); var player2NewRating = newRatings[player2]; AssertRating(25.000, 4.583, player2NewRating); var player3NewRating = newRatings[player3]; AssertRating(25.000, 4.576, player3NewRating); var player4NewRating = newRatings[player4]; AssertRating(25.000, 4.573, player4NewRating); var player5NewRating = newRatings[player5]; AssertRating(25.000, 4.573, player5NewRating); var player6NewRating = newRatings[player6]; AssertRating(25.000, 4.576, player6NewRating); var player7NewRating = newRatings[player7]; AssertRating(25.000, 4.583, player7NewRating); var player8NewRating = newRatings[player8]; AssertRating(25.000, 4.592, player8NewRating); AssertMatchQuality(0.004, calculator.CalculateMatchQuality(gameInfo, teams)); }
private static void EightTeamsOfOneUpset(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var player5 = new Player(5); var player6 = new Player(6); var player7 = new Player(7); var player8 = new Player(8); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team(player1, new Rating(10, 8)); var team2 = new Team(player2, new Rating(15, 7)); var team3 = new Team(player3, new Rating(20, 6)); var team4 = new Team(player4, new Rating(25, 5)); var team5 = new Team(player5, new Rating(30, 4)); var team6 = new Team(player6, new Rating(35, 3)); var team7 = new Team(player7, new Rating(40, 2)); var team8 = new Team(player8, new Rating(45, 1)); var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8); var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4, 5, 6, 7, 8); var player1NewRating = newRatings[player1]; AssertRating(35.135, 4.506, player1NewRating); var player2NewRating = newRatings[player2]; AssertRating(32.585, 4.037, player2NewRating); var player3NewRating = newRatings[player3]; AssertRating(31.329, 3.756, player3NewRating); var player4NewRating = newRatings[player4]; AssertRating(30.984, 3.453, player4NewRating); var player5NewRating = newRatings[player5]; AssertRating(31.751, 3.064, player5NewRating); var player6NewRating = newRatings[player6]; AssertRating(34.051, 2.541, player6NewRating); var player7NewRating = newRatings[player7]; AssertRating(38.263, 1.849, player7NewRating); var player8NewRating = newRatings[player8]; AssertRating(44.118, 0.983, player8NewRating); AssertMatchQuality(0.000, calculator.CalculateMatchQuality(gameInfo, teams)); }
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); }
public static void Main(string[] args) { var calculator = new TwoTeamTrueSkillCalculator(); var gameInfo = GameInfo.DefaultGameInfo; var ratings = new Dictionary <object, Rating>(); var lines = File.ReadLines(args[0]); foreach (var line in lines) { var newline = line; string[] tokens = line.Split(','); for (int i = 1; i <= 22; i++) { if (!ratings.ContainsKey(tokens[i])) { ratings[tokens[i]] = gameInfo.DefaultRating; } } var players = new List <Player>(); var team1 = new Team(); for (int i = 1; i <= 11; i++) { var player = new Player(tokens[i]); team1.AddPlayer(player, ratings[tokens[i]]); players.Add(player); } var team2 = new Team(); for (int i = 12; i <= 22; i++) { var player = new Player(tokens[i]); team2.AddPlayer(player, ratings[tokens[i]]); players.Add(player); } var teams = Teams.Concat(team1, team2); var rank1 = 1; var rank2 = 1; if (tokens[23] == "-1") { rank1 = 1; rank2 = 2; } if (tokens[23] == "1") { rank1 = 2; rank2 = 1; } var newRatings = calculator.CalculateNewRatings(gameInfo, teams, rank1, rank2); foreach (var player in players) { ratings[player.Id] = newRatings[player]; newline = newline + "," + newRatings [player].Mean; } Console.WriteLine(newline); } }
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)); }
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; } }
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)); }
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); }
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); }
private static void ThreeOnTwoTests(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var team1 = new Team() .AddPlayer(player1, new Rating(28, 7)) .AddPlayer(player2, new Rating(27, 6)) .AddPlayer(player3, new Rating(26, 5)); 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)); var gameInfo = GameInfo.DefaultGameInfo; var teams = Teams.Concat(team1, team2); var newRatingsWinLoseExpected = calculator.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]); var newRatingsWinLoseUpset = calculator.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]); AssertMatchQuality(0.254, calculator.CalculateMatchQuality(gameInfo, teams)); }
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()); }
private static void FourOnFourSimpleTest(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var player3 = new Player(3); var player4 = new Player(4); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, gameInfo.DefaultRating) .AddPlayer(player2, gameInfo.DefaultRating) .AddPlayer(player3, gameInfo.DefaultRating) .AddPlayer(player4, gameInfo.DefaultRating); var player5 = new Player(5); var player6 = new Player(6); var player7 = new Player(7); var player8 = new Player(8); var team2 = new Team() .AddPlayer(player5, gameInfo.DefaultRating) .AddPlayer(player6, gameInfo.DefaultRating) .AddPlayer(player7, gameInfo.DefaultRating) .AddPlayer(player8, gameInfo.DefaultRating); var teams = Teams.Concat(team1, team2); var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2); // Winners AssertRating(27.198, 8.059, newRatingsWinLose[player1]); AssertRating(27.198, 8.059, newRatingsWinLose[player2]); AssertRating(27.198, 8.059, newRatingsWinLose[player3]); AssertRating(27.198, 8.059, newRatingsWinLose[player4]); // Losers AssertRating(22.802, 8.059, newRatingsWinLose[player5]); AssertRating(22.802, 8.059, newRatingsWinLose[player6]); AssertRating(22.802, 8.059, newRatingsWinLose[player7]); AssertRating(22.802, 8.059, newRatingsWinLose[player8]); AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams)); }
//------------------------------------------------------------------------------ // Multiple Teams Tests //------------------------------------------------------------------------------ private static void TwoOnFourOnTwoWinDraw(SkillCalculator calculator) { var player1 = new Player(1); var player2 = new Player(2); var gameInfo = GameInfo.DefaultGameInfo; var team1 = new Team() .AddPlayer(player1, new Rating(40, 4)) .AddPlayer(player2, new Rating(45, 3)); 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); var team3 = new Team() .AddPlayer(player7, new Rating(50, 5)) .AddPlayer(player8, new Rating(30, 2)); var teams = Teams.Concat(team1, team2, team3); var newRatingsWinLose = calculator.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]); AssertMatchQuality(0.367, calculator.CalculateMatchQuality(gameInfo, teams)); }