public void TestUpdateRatings(IReadOnlyCollection <IReadOnlyCollection <KeyValuePair <int, int> > > gameResult, Dictionary <int, int> expectedNewRatings) { var calculator = new EloCalculator(32); var gameResultRatingHolders = gameResult .Select(rs => rs.Select(r => new RatingHolder(r.Key, r.Value)).ToList()) .ToList(); var newRatingHolders = calculator.UpdateRatings(gameResultRatingHolders).ToList(); Assert.AreEqual(newRatingHolders.Count, expectedNewRatings.Count); Assert.AreEqual(newRatingHolders.Count, newRatingHolders.Select(rh => rh.Identifier).Distinct().Count()); foreach (var rh in newRatingHolders) { Assert.AreEqual(rh.Rating, expectedNewRatings[rh.Identifier]); } }
public void RegisterCompletedGame(string gameName, DateTime startTime, string location, IReadOnlyCollection <IReadOnlyCollection <string> > playerNamesByPosition) { using (var gameRepository = repositoryFactory.GetRepository <Game>()) using (var playerRepository = repositoryFactory.GetRepository <Player>()) using (var gameResultRepository = repositoryFactory.GetRepository <GameResult>()) { var game = gameRepository.Get(new Game { Name = gameName }); if (game == null) { throw new ArgumentException($"Unrecogised game name: {gameName}", nameof(gameName)); } var playerCount = playerNamesByPosition.Sum(pns => pns.Count); if (playerCount < game.MinimumPlayerCount || playerCount > game.MaximumPlayerCount) { throw new ArgumentException($"Invalid number of players for {gameName}: {playerCount}", nameof(playerNamesByPosition)); } var recognisedPlayerNames = new HashSet <string>(); var duplicatePlayerNames = new HashSet <string>(); var unrecognisedPlayerNames = new HashSet <string>(); var playersByPosition = playerNamesByPosition .Select(pns => pns.Select(pn => { if (recognisedPlayerNames.Contains(pn)) { duplicatePlayerNames.Add(pn); return(null); } var player = playerRepository.Get(new Player { Name = pn }); if (player == null) { unrecognisedPlayerNames.Add(pn); return(null); } recognisedPlayerNames.Add(pn); return(player); }).ToList()).ToList(); if (duplicatePlayerNames.Count > 0) { throw new ArgumentException($"Duplicate player name(s): {string.Join(", ", duplicatePlayerNames)}", nameof(playerNamesByPosition)); } if (unrecognisedPlayerNames.Count > 0) { throw new ArgumentException($"Duplicate player name(s): {string.Join(", ", duplicatePlayerNames)}", nameof(playerNamesByPosition)); } var playersWithRatingsAfter = eloCalculator.UpdateRatings(playersByPosition); var playerResultsByPosition = playersByPosition .Select((ps, psi) => ps.Select((p, pi) => new PlayerResult { PlayerName = p.Name, RatingBefore = p.Rating, RatingAfter = playersWithRatingsAfter.Single(a => p.IdentifiesWith(a)).Rating }).ToList()) .ToList(); var gameResult = new GameResult { Game = game.Name, StartTime = startTime, Location = location, PlayerResultsByPosition = playerResultsByPosition }; gameResultRepository.Put(gameResult); foreach (var player in playersWithRatingsAfter) { playerRepository.Put(player); } } }