/* * Do the rating calculation for each player the number of times specified */ public async Task <Dictionary <int, Player> > DoCalculation(int count, Dictionary <int, Player> players, RatingRule rule, Dictionary <int, List <Result> > playerResults) { for (int i = 0; i < count; i++) { await LogStatus($"Running calculations - Iteration {i + 1}"); foreach (var player in players.Values) { // update progress counters int playerId = player.Id; //Get Player ID ArrayList results = GetRatingResults(player, players, playerResults[playerId], rule); //Get the results of the player's matches RatingInfo rating = new RatingInfo(); if (results != null && results.Count > 0) // skip player if they have no results { rating = CalculatePlayerUTR(player, results, players, rule); } else //No recent result case, this needs to be improved to place players in an inactive & currated state { rating.Rating = (float)player.Stats.Rating; rating.Reliability = 0; } player.Stats.ActualRating = Math.Truncate(rating.Rating * 100) / 100; // store actual value, even for benchmarks player.Stats.RatingReliability = rating.Reliability; player.Stats.SubRating = rating.SubRating; player.Stats.Rating = rating.Rating; player.Stats.Reliability = rating.Reliability; } } return(players); }
public RatingInfo CalculatePlayerUTR(Player player, ArrayList results, Dictionary <int, Player> playerRepo, RatingRule rule) { RatingInfo playerUTR = new RatingInfo(); // store player's UTR and reliability ArrayList resultRatingInfoList = new ArrayList(); // stores the RatingInfo for each match var activeResultsIds = new List <int>(); float SumRatingXReliability = 0; float SumReliabilityRating = 0; float SumReliabilityPlayerReliability = 0; //stores unique opponent IDs and number of times played Dictionary <int, int> opponentsMatchFrequency = CalculateMatchFrequencyReliability(player.Id, results); foreach (Result r in results) { // Calculate Dynamcic Rating and Match Result Reliability Factor for each match, store in list var ri = DoResultsCalculation(player, r, results, playerRepo, rule, opponentsMatchFrequency); resultRatingInfoList.Add(ri); if (ri.weightingFactors.MatchWeight >= rule.eligibleResultsWeightThreshold) { activeResultsIds.Add(r.Id); } } // Store active results used in calculation player.Stats.ActiveSinglesResults = JsonConvert.SerializeObject(activeResultsIds.ToArray()); foreach (RatingInfo ri in resultRatingInfoList) { SumRatingXReliability += ri.Rating * ri.Reliability; // For each match, Dynmic Ratch x Match Reliability SumReliabilityRating += ri.Reliability; // Sum of Match Reliabilities // divide by interpool coefficient so it doesn't skew player reliability SumReliabilityPlayerReliability += ri.Reliability / ri.weightingFactors.InterpoolCoeffecient; } float rating = (SumReliabilityRating == 0.0) ? 0 : (SumRatingXReliability / SumReliabilityRating); playerUTR.Rating = (float)SmoothRating(rating); // Player rating is these number divided playerUTR.Rating = (float)Math.Truncate(100 * playerUTR.Rating) / 100; playerUTR.Reliability = CalculatePlayerReliability(SumReliabilityPlayerReliability, rule); if (float.IsNaN(playerUTR.Rating)) { System.Diagnostics.Debug.WriteLine(playerUTR.Rating); } if (player.IsTop700()) { CalculatePlayerSubUTRs(resultRatingInfoList, playerUTR, player.Stats.Id); } return(playerUTR); }
public RatingInfo DoResultsCalculation(Player playerInfo, Result r, ArrayList results, Dictionary <int, Player> playerRepo, RatingRule rule, Dictionary <int, int> matchFrequency) { RatingInfo ratingInfo = new RatingInfo { SurfaceType = r.SurfaceType, Date = r.ResultDate, IsMastersOrGrandslam = r.IsMastersOrGrandslam }; var opponent = playerRepo[GetOpponentId(playerInfo.Id, r)]; //info about opponent //var opponent = GetOpponent(playerInfo.Id, r, playerRepo); if (opponent.BenchmarkRating != null && opponent.BenchmarkRating > 0) { opponent.Stats.Rating = (double)opponent.BenchmarkRating; } ratingInfo.Rating = CalculateDynamicRating(playerInfo, opponent, r, playerRepo, rule); if (float.IsNaN(ratingInfo.Rating)) { System.Diagnostics.Debug.WriteLine(ratingInfo.Rating); } ratingInfo.AgainstBenchmark = (opponent.Stats.IsBenchmark) ? true : false; float opponentFrequency = 0; try { opponentFrequency = (float)matchFrequency[opponent.Id]; // value from dictionary } catch (Exception e) { _logger.LogWarning(e, opponent.Id.ToString()); } RatingInfo.WeightingFactors wf = CalculateMatchResultRelibilityFactor(playerInfo, r, opponent, opponentFrequency, ratingInfo.AgainstBenchmark, rule); ratingInfo.Reliability = wf.MatchWeight; //reliability for match ratingInfo.weightingFactors = wf; return(ratingInfo); }
public void CalculatePlayerSubUTRs(ArrayList resultRatingInfoList, RatingInfo ratingInfo, int playerRatingId) { ratingInfo.SubRating = new SubRating { PlayerRatingId = playerRatingId, ResultCount = resultRatingInfoList.Count }; ratingInfo.SubRating.HardCourt = CalculatePlayerSurfaceUTR(resultRatingInfoList, SurfaceType.Hard, out int hardCount); ratingInfo.SubRating.HardCourtCount = hardCount; ratingInfo.SubRating.ClayCourt = CalculatePlayerSurfaceUTR(resultRatingInfoList, SurfaceType.Clay, out int clayCount); ratingInfo.SubRating.ClayCourtCount = clayCount; ratingInfo.SubRating.GrassCourt = CalculatePlayerSurfaceUTR(resultRatingInfoList, SurfaceType.Grass, out int grassCount); ratingInfo.SubRating.GrassCourtCount = grassCount; ratingInfo.SubRating.SixWeek = CalculatePlayerTimeUTR(DateTime.Now.AddDays(-42), resultRatingInfoList, out int sixCount); ratingInfo.SubRating.SixWeekCount = sixCount; ratingInfo.SubRating.EightWeek = CalculatePlayerTimeUTR(DateTime.Now.AddDays(-56), resultRatingInfoList, out int eightCount); ratingInfo.SubRating.EightWeekCount = eightCount; ratingInfo.SubRating.OneMonth = CalculatePlayerTimeUTR(DateTime.Now.AddMonths(-1), resultRatingInfoList, out int oneCount); ratingInfo.SubRating.OneMonthCount = oneCount; ratingInfo.SubRating.ThreeMonth = CalculatePlayerTimeUTR(DateTime.Now.AddMonths(-3), resultRatingInfoList, out int threeCount); ratingInfo.SubRating.ThreeMonthCount = threeCount; ratingInfo.SubRating.GrandSlamMasters = CalculateAtpMastersUTR(resultRatingInfoList, out int gmCount); ratingInfo.SubRating.GrandSlamMastersCount = gmCount; }