/// <summary> /// Constructor. Takes the rating, deviation, and volatility default values /// from the rating system. /// </summary> /// <param name="ratingSystem"></param> public Rating(RatingCalculator ratingSystem) { _ratingSystem = ratingSystem; _rating = _ratingSystem.GetDefaultRating(); _ratingDeviation = _ratingSystem.GetDefaultRatingDeviation(); _volatility = ratingSystem.GetDefaultVolatility(); }
public IEnumerable <PlayerRankingEntry> DetermineRanking(Records data) { var calculator = new RatingCalculator(); var players = new Dictionary <Player, Rating>(); foreach (var player in data.GetPlayers()) { players[player] = new Rating(calculator); } var results = new RatingPeriodResults(); foreach (var game in data.Games) { foreach (var winner in game.Winners()) { foreach (var loser in game.Losers()) { results.AddResult(players[winner], players[loser]); } } } calculator.UpdateRatings(results); foreach (var player in players) { yield return(new PlayerRankingEntry() { Player = player.Key, Score = player.Value.GetRating() }); } }
private void UpdatePlayerRatingsCore() { if (Games.Any()) { Players.ForEach(player => player.Rating = Constants.BaseRating); (double WinnerUpdatedRating, double LoserUpdatedRating)updatedRatings; var ratingCalculator = new RatingCalculator(kFactor: 100, baseRating: Constants.BaseRating); foreach (Game game in Games) { updatedRatings = ratingCalculator.GetNewRatings(game.WasAStalemate, game.Winner.Rating, game.Loser.Rating); Players.First(player => player.RankOnLoad == game.Winner.RankOnLoad).Rating = updatedRatings.WinnerUpdatedRating; Players.First(player => player.RankOnLoad == game.Loser.RankOnLoad).Rating = updatedRatings.LoserUpdatedRating; } } else { foreach (Player player in Players) { player.Rating = Constants.BaseRating; } } Players = Players.OrderByDescending(player => player.Rating).ThenBy(player => player.FirstName).ToList(); for (int i = 0; i < Players.Count; i++) { Players[i].CurrentRank = i + 1; } }
public void Save_rating() { var calculator = new RatingCalculator(DateTime.Today.AddDays(-7), DateTime.Today); var ratings = calculator.Ratings(); RatingCalculator.Save(DateTime.Today.FirstDayOfMonth(), ratings); }
/// <summary> /// Constructor. Allows you to pass in the rating, deviation, and volatility. /// </summary> /// <param name="ratingSystem"></param> /// <param name="initRating"></param> /// <param name="initRatingDeviation"></param> /// <param name="initVolatility"></param> public Rating(RatingCalculator ratingSystem, double initRating, double initRatingDeviation, double initVolatility) { _ratingSystem = ratingSystem; _rating = initRating; _ratingDeviation = initRatingDeviation; _volatility = initVolatility; }
private void Start() { dayUI = GetComponent <DayUI>(); ratingCalculator = GetComponent <RatingCalculator>(); starRatingUI = GetComponent <StarRatingUI>(); descriptionLibrary = GetComponent <DescriptionLibrary>(); StartDay(); }
private void CalcRating() { string text = null, output; isCalculating = true; try { #if DEBUG var sw = new Stopwatch(); sw.Start(); #endif Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate { text = PathText.Text; })); var map = new BeatmapInfo(text); var jack = new PatternAnalyzer(map.Notes, map.LNs, map.Data.Keys, map.Data.Bpms, map.Data.SpecialStyle); var specialStyle = map.Data.SpecialStyle || (map.Data.Keys == 8 && PatternAnalyzer.IsSpecialStyle(map.Notes, map.LNs)); var maxBpm = Math.Round(map.Data.Bpms.Select(cur => cur.Item1).Max(), 2); var minBpm = Math.Round(map.Data.Bpms.Select(cur => cur.Item1).Min(), 2); output = map.Data.Artist + " - " + map.Data.Title + " [" + map.Data.Diff + "]\nMade by " + map.Data.Creator + "\nBPM: " + (Math.Abs(maxBpm - minBpm) < 0.001 ? $"{maxBpm}" : $"{minBpm} - {maxBpm}\t") + "\tOD: " + map.Data.Od + "\tHP: " + map.Data.Hp + "\tKeys: " + (map.Data.Keys == 8 || specialStyle ? Convert.ToString(map.Data.Keys - 1) + "+1" : Convert.ToString(map.Data.Keys)) #if DEBUG + "\nJack Score: " + Math.Round(RatingCalculator.CalcJackScore(jack), 2) + " " + "\tVibro Ratio: " + Math.Round(jack.GetVibroRatio() * 100, 2) + "%" + "\tSpam Ratio: " + Math.Round(jack.GetSpamRatio() * 100, 2) + "%" + "\nDensity Score: " + Math.Round(map.JenksDensity, 2) + "\tSpeed Score: " + Math.Round(map.JenksSpeed, 2) #endif + "\nRating: " + Math.Round(RatingCalculator.CalcRating(map, jack), 2); #if DEBUG sw.Stop(); output += "\nElapsed Time: " + sw.ElapsedMilliseconds; #endif } catch (Exception ex) { output = ex.Message; } Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate { StateBlock.Text = output; })); isCalculating = false; }
public void Calculate_client_rating() { var calculator = new RatingCalculator(); var regional = new[] { Tuple.Create(500m, 1ul) }; var clients = new[] { new ClientRating(100u, 1ul, 100m), }; var rating = calculator.Calculate(regional, clients); var result = new[] { new ClientRating(100u, 1ul, 0.2m) }; Assert.That(rating.ToArray(), Is.EquivalentTo(result)); }
private void CalcRating() { string text = null, output; isCalculating = true; try { var sw = new Stopwatch(); sw.Start(); Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate { text = PathText.Text; })); var map = new BeatmapInfo(text); var jack = new PatternAnalyzer(map.Notes, map.LNs, map.Data.Keys, map.Data.SpecialStyle); var specialStyle = map.Data.SpecialStyle || (map.Data.Keys == 8 && (double)(jack.Notes[0].Count + jack.LNs[0].Count) / jack.Count < 0.06); output = map.Data.Artist + " - " + map.Data.Title + " [" + map.Data.Diff + "]\nMade by " + map.Data.Creator + "\nBPM: " + (Math.Abs(map.Data.MaxBpm - map.Data.MinBpm) < 0.001 ? Convert.ToString(map.Data.MaxBpm, CultureInfo.CurrentCulture) : map.Data.MinBpm + " - " + map.Data.MaxBpm + "\t") + "\tOD: " + map.Data.Od + "\tHP: " + map.Data.Hp + "\tKeys: " + (specialStyle ? Convert.ToString(map.Data.Keys - 1) + "+1" : Convert.ToString(map.Data.Keys)) + "\nMax Density: " + Math.Round(map.MaxDen, 2) + "\tAverage Density: " + Math.Round(map.AvgDen, 2) + "\tJack Ratio: " + Math.Round(jack.GetJackRatio() * 100, 2) + "%" #if DEBUG + "\nSpam Ratio: " + Math.Round(jack.GetSpamRatio() * 100, 2) + "%" + "\nCorrected Max Density: " + Math.Round(map.CorMaxDen, 2) + "\tCorrected Average Density: " + Math.Round(map.CorAvgDen, 2) #endif + "\nRating: " + Math.Round(RatingCalculator.CalcRating(map), 2); sw.Stop(); #if DEBUG output += "\nElapsed Time: " + sw.ElapsedMilliseconds; #endif } catch (Exception ex) { output = ex.Message; } Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate { StateBlock.Text = output; })); isCalculating = false; }
public void Calculate_and_save_rating() { var runTime = DateTime.Now.FirstDayOfMonth(); if (DateTime.Today == DateTime.Today.FirstDayOfMonth()) { runTime = runTime.AddMonths(-1); } var ratings = RatingCalculator.CaclucatedAndSave(runTime); Assert.That(ratings.Count(), Is.GreaterThan(0)); }
public ActionResult Teams() { var ratingCalculator = new RatingCalculator(new InMemoryRatingRepository()); foreach (var match in GetMatchesInHistoricalOrder()) { ratingCalculator.CalculateStatisticsForMatch(match); } var model = ratingCalculator.GetTeamRatingList(); return View(model); }
static void Main(string[] args) { Console.WriteLine("Hello World!"); // Instantiate a RatingCalculator object. // At instantiation, you can set the default rating for a player's volatility and // the system constant for your game ("τ", which constrains changes in volatility // over time) or just accept the defaults. var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a Rating object for each player. var player1 = new Rating(calculator /* , rating, ratingDeviation, volatility */); var player2 = new Rating(calculator /* , rating, ratingDeviation, volatility */); var player3 = new Rating(calculator /* , rating, ratingDeviation, volatility */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); // Add game results to the RatingPeriodResults object until you reach the end of your rating period. // Use addResult(winner, loser) for games that had an outcome. results.AddResult(player1, player2); // Use addDraw(player1, player2) for games that resulted in a draw. results.AddDraw(player1, player2); // Use addParticipant(player) to add players that played no games in the rating period. results.AddParticipant(player3); // Once you've reached the end of your rating period, call the updateRatings method // against the RatingCalculator; this takes the RatingPeriodResults object as argument. // * Note that the RatingPeriodResults object is cleared down of game results once // the new ratings have been calculated. // * Participants remain within the RatingPeriodResults object, however, and will // have their rating deviations recalculated at the end of future rating periods // even if they don't play any games. This is in-line with Glickman's algorithm. calculator.UpdateRatings(results); // Access the getRating, getRatingDeviation, and getVolatility methods of each // player's Rating to see the new values. var players = new[] { player1, player2, player3 }; for (var index = 0; index < players.Length; index++) { var player = players[index]; Console.WriteLine("Player #" + index + " values: " + player.GetRating() + ", " + player.GetRatingDeviation() + ", " + player.GetVolatility()); } }
public async Task <double?> Measure(string text) { logger.LogDebug("Measure"); try { var result = await Measure(text, CancellationToken.None).ConfigureAwait(false); if (result == null) { logger.LogWarning("No meaningful response"); return(null); } logger.LogDebug("MeasureSentiment Calculated: {0}", result.Stars); return(result.Stars.HasValue ? RatingCalculator.ConvertToRaw(result.Stars.Value) : null); } catch (Exception ex) { logger.LogError(ex, "Failed sentiment processing"); return(null); } }
public void Setup() { supplier = TestSupplier.CreateNaked(session); supplier.CreateSampleCore(session); supplier.Prices[0].Core.Where(c => c.Producer != null) .Each(c => TestAssortment.CheckAndCreate(session, c.Product, c.Producer)); var client = TestClient.CreateNaked(session); var order = new TestOrder(client.Users[0], supplier.Prices[0]); order.Processed = false; order.WriteTime = DateTime.Today.AddDays(-1); order.AddItem(supplier.Prices[0].Core[0], 1); session.Save(order); supplier.Maintain(session); session.Transaction.Commit(); calculator = new CostCalculator(); ratings = RatingCalculator .Caclucated(DateTime.Today.AddDays(-10), DateTime.Today) .Take(3) .ToArray(); }
public void Load() { double positive = 0; double negative = 0; foreach (var sentenceItem in Text.Sentences) { foreach (var word in sentenceItem.Words) { double?value = null; if (word.Value.HasValue) { value = word.Value; } if (word.CalculatedValue.HasValue) { value = word.CalculatedValue.Value; } if (value != null) { if (value > 0) { positive += Math.Abs(value.Value); } else { negative += Math.Abs(value.Value); } } } } Sentiment = RatingCalculator.Calculate(positive, negative); }
public HistoryAnalysis Analyse(IReadOnlyCollection <Period> history) { List <Result> ratings = new List <Result>(); Result result; double unDocumentedDuration = 0; double duration = 0; decimal rating = 0; //Return 0 duration and 0 rating if no periods available or if configuration is not set if (AnalyserConfiguration == null || history == null || history.Count == 0) { return(new HistoryAnalysis { AnalysedDuration = new TimeSpan(0, 0, 0), DriverRating = 0 }); } //Sort the given list of periods in the ascending order of start time history = history.OrderBy(x => x.Start).ToArray(); var entriesToConsider = history.ToList(); //Take the index of record with first non zero average speed var begin = entriesToConsider.IndexOf(history.FirstOrDefault(x => x.AverageSpeed > 0)); //Take the index of record with last non zero average speed var end = entriesToConsider.IndexOf(history.LastOrDefault(x => x.AverageSpeed > 0)); //Check if there is any period with non zero average speed, if yes then proceed to calculate duration and ratings if (begin != -1) { //Calculate the duration and ratings for periods that fall between (and including) first and last records with non zero average speeds for (int i = begin; i <= end; i++) { //For intermediate records, Check for the gaps between current record's start time and previous record's end time //If there is a gap, then calculate undocumented period and rating if (i > begin && history.ElementAt(i).Start > history.ElementAt(i - 1).End) { duration = (history.ElementAt(i).Start - history.ElementAt(i - 1).End).TotalMinutes; unDocumentedDuration += duration; ratings.Add(new Result() { StartTime = history.ElementAt(i - 1).End.TimeOfDay, EndTime = history.ElementAt(i).Start.TimeOfDay, Duration = (decimal)duration, Rating = 0 }); } //Check if average speed is greater than maximum permitted speed. //If yes, then assign rating configured for exceeding maximum speed //If no, then calculate the rating by linearly mapping the average speeds between 0 and maximum speed to 0-1 rating = (history.ElementAt(i).AverageSpeed > AnalyserConfiguration.MaxSpeed) ? AnalyserConfiguration.RatingForExceedingMaxSpeed : (history.ElementAt(i).AverageSpeed / AnalyserConfiguration.MaxSpeed); //Create result set containing Start and End time along with calculated rating result = new Result() { StartTime = history.ElementAt(i).Start.TimeOfDay, EndTime = history.ElementAt(i).End.TimeOfDay, Rating = rating }; //Get the duration for the current result set result.Duration = (decimal)(result.EndTime - result.StartTime).TotalMinutes; ratings.Add(result); } } //If no period is considered valid during analysis, return 0 duration and 0 rating if (!ratings.Any()) { return(new HistoryAnalysis { AnalysedDuration = new TimeSpan(0, 0, 0), DriverRating = 0 }); } //Sort the rating resultsets in ascending order of start time ratings = ratings.OrderBy(x => x.StartTime).ToList(); //Calculate overall rating for periods considered var overallRating = RatingCalculator.CalculateOverallRating(ratings); //Return analysis duration (excluding undocumented duration), overall rating and apply penalty if any undocumented periods recorded return(new HistoryAnalysis { AnalysedDuration = ratings.Last().EndTime - ratings.First().StartTime - new TimeSpan(0, (int)unDocumentedDuration, 0), DriverRating = overallRating, DriverRatingAfterPenalty = unDocumentedDuration > 0 ? overallRating * AnalyserConfiguration.PenaltyForFaultyRecording : overallRating }); }
private void UpdatePlayerRatings() { var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); var ratingsPlayers = new List <Tuple <User, Rating> >(); double team1Rating = Team1.Sum(x => x.SkillRating) / Team1.Count; double team2Rating = Team2.Sum(x => x.SkillRating) / Team2.Count; double team1RatingsDeviation = Team1.Sum(x => x.RatingsDeviation) / Team1.Count; double team2RatingsDeviation = Team2.Sum(x => x.RatingsDeviation) / Team2.Count; double team1Volatility = Team1.Sum(x => x.Volatility) / Team1.Count; double team2Volatility = Team2.Sum(x => x.Volatility) / Team2.Count; var team1RatingCalc = new Rating(calculator, team1Rating, team1RatingsDeviation, team1Volatility); var team2RatingCalc = new Rating(calculator, team2Rating, team2RatingsDeviation, team2Volatility); foreach (var player in Team1) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <User, Rating>(player, playerRating)); if (WinningTeam == Team1) { results.AddResult(playerRating, team2RatingCalc); } else if (WinningTeam == Team2) { results.AddResult(team2RatingCalc, playerRating); } } foreach (var player in Team2) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <User, Rating>(player, playerRating)); if (WinningTeam == Team1) { results.AddResult(team1RatingCalc, playerRating); } else if (WinningTeam == Team2) { results.AddResult(playerRating, team1RatingCalc); } } calculator.UpdateRatings(results); foreach (var player in ratingsPlayers) { player.Item1.PreviousSkillRating = player.Item1.SkillRating; player.Item1.SkillRating = player.Item2.GetRating(); player.Item1.RatingsDeviation = player.Item2.GetRatingDeviation(); player.Item1.Volatility = player.Item2.GetVolatility(); db.Users.Update(player.Item1); } db.SaveChanges(); }
public HistoryAnalysis Analyse(IReadOnlyCollection <Period> history) { List <Result> ratings = new List <Result>(); Result result; double unDocumentedDuration = 0; double duration = 0; decimal rating = 0; //Return 0 duration and 0 rating if no periods available or if configuration is not set if (AnalyserConfiguration == null || history == null || history.Count == 0) { return(new HistoryAnalysis { AnalysedDuration = new TimeSpan(0, 0, 0), DriverRating = 0 }); } //Sort the given list of periods in the ascending order of start time history = history.OrderBy(x => x.Start).ToArray(); for (int i = 0; i < history.Count; i++) { //Ignore anything outside the permitted time slot if ((history.ElementAt(i).Start.TimeOfDay >= AnalyserConfiguration.EndTime) || history.ElementAt(i).End.TimeOfDay <= AnalyserConfiguration.StartTime) { continue; } //Check for undocumented periods for the first record by determining gap between record's start time and permitted start time if (i == 0 && history.ElementAt(i).Start.TimeOfDay > AnalyserConfiguration.StartTime) { duration = (history.ElementAt(i).Start.TimeOfDay - AnalyserConfiguration.StartTime).TotalMinutes; unDocumentedDuration += duration; ratings.Add(new Result() { StartTime = AnalyserConfiguration.StartTime, EndTime = history.ElementAt(i).Start.TimeOfDay, Duration = (decimal)duration, Rating = 0 }); } //Check for undocumented periods for the last record by determining gap between record's end time and permitted end time else if (i == history.Count - 1 && history.ElementAt(i).End.TimeOfDay < AnalyserConfiguration.EndTime) { duration = (AnalyserConfiguration.EndTime - history.ElementAt(i).End.TimeOfDay).TotalMinutes; unDocumentedDuration += duration; ratings.Add(new Result() { StartTime = history.ElementAt(i).End.TimeOfDay, EndTime = AnalyserConfiguration.EndTime, Duration = (decimal)duration, Rating = 0 }); } //For intermediate records, Check for the gaps between current record's start time and previous record's end time //If there is a gap, then calculate undocumented period and rating if (i > 0 && history.ElementAt(i).Start.TimeOfDay > AnalyserConfiguration.StartTime && history.ElementAt(i).Start > history.ElementAt(i - 1).End) { duration = (history.ElementAt(i).Start - history.ElementAt(i - 1).End).TotalMinutes; unDocumentedDuration += duration; ratings.Add(new Result() { StartTime = history.ElementAt(i - 1).End.TimeOfDay, EndTime = history.ElementAt(i).Start.TimeOfDay, Duration = (decimal)duration, Rating = 0 }); } //Check if average speed is greater than maximum permitted speed. //If yes, then assign rating configured for exceeding maximum speed //If no, then calculate the rating by linearly mapping the average speeds between 0 and maximum speed to 0-1 rating = (history.ElementAt(i).AverageSpeed > AnalyserConfiguration.MaxSpeed) ? AnalyserConfiguration.RatingForExceedingMaxSpeed : (history.ElementAt(i).AverageSpeed / AnalyserConfiguration.MaxSpeed); //Create result set containing Start and End time along with calculated rating result = new Result() { StartTime = history.ElementAt(i).Start.TimeOfDay, EndTime = history.ElementAt(i).End.TimeOfDay, Rating = rating }; //Set start time to permitted start time if it starts before permitted start time if (history.ElementAt(i).Start.TimeOfDay < AnalyserConfiguration.StartTime) { result.StartTime = AnalyserConfiguration.StartTime; } //Set end time to permitted end time if it ends after permitted end time if (history.ElementAt(i).End.TimeOfDay > AnalyserConfiguration.EndTime) { result.EndTime = AnalyserConfiguration.EndTime; } //Get the duration for the current result set result.Duration = (decimal)(result.EndTime - result.StartTime).TotalMinutes; ratings.Add(result); } //If no period is considered valid during analysis, return 0 duration and 0 rating if (!ratings.Any()) { return(new HistoryAnalysis { AnalysedDuration = new TimeSpan(0, 0, 0), DriverRating = 0 }); } //Sort the rating resultsets in ascending order of start time ratings = ratings.OrderBy(x => x.StartTime).ToList(); //Calculate overall rating for periods considered var overallRating = RatingCalculator.CalculateOverallRating(ratings); //Return analysis duration (excluding undocumented duration), overall rating and apply penalty if any undocumented periods recorded return(new HistoryAnalysis { AnalysedDuration = ratings.Last().EndTime - ratings.First().StartTime - new TimeSpan(0, (int)unDocumentedDuration, 0), DriverRating = overallRating, DriverRatingAfterPenalty = unDocumentedDuration > 0 ? overallRating * AnalyserConfiguration.PenaltyForFaultyRecording : overallRating }); }
public GlickoSystem() { playerlist = new Dictionary <string, Rating>(); calculator = new RatingCalculator(); results = new RatingPeriodResults(); }
private void UpdatePlayersRating(Matches match) { foreach (var player in match.GetAllUsers(datastore)) { player.PreviousSkillRating = player.SkillRating; } var calculator = new RatingCalculator(/* initVolatility, tau */); // Instantiate a RatingPeriodResults object. var results = new RatingPeriodResults(); var ratingsPlayers = new List <Tuple <Users, Rating> >(); double team1Rating = match.GetTeam1Users(datastore).Sum(x => x.SkillRating) / match.GetTeam1Users(datastore).Count; double team2Rating = match.GetTeam2Users(datastore).Sum(x => x.SkillRating) / match.GetTeam2Users(datastore).Count; double team1RatingsDeviation = match.GetTeam1Users(datastore).Sum(x => x.RatingsDeviation) / match.GetTeam1Users(datastore).Count; double team2RatingsDeviation = match.GetTeam2Users(datastore).Sum(x => x.RatingsDeviation) / match.GetTeam2Users(datastore).Count; double team1Volatility = match.GetTeam1Users(datastore).Sum(x => x.Volatility) / match.GetTeam1Users(datastore).Count; double team2Volatility = match.GetTeam2Users(datastore).Sum(x => x.Volatility) / match.GetTeam2Users(datastore).Count; var team1RatingCalc = new Rating(calculator, team1Rating, team1RatingsDeviation, team1Volatility); var team2RatingCalc = new Rating(calculator, team2Rating, team2RatingsDeviation, team2Volatility); foreach (var player in match.GetTeam1Users(datastore)) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <Users, Rating>(player, playerRating)); if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamOne) { results.AddResult(playerRating, team2RatingCalc); } else if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamTwo) { results.AddResult(team2RatingCalc, playerRating); } } foreach (var player in match.GetTeam2Users(datastore)) { var playerRating = new Rating(calculator, player.SkillRating, player.RatingsDeviation, player.Volatility); ratingsPlayers.Add(new Tuple <Users, Rating>(player, playerRating)); if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamOne) { results.AddResult(team1RatingCalc, playerRating); } else if ((DataStore.Teams)match.TeamWinner == DataStore.Teams.TeamTwo) { results.AddResult(playerRating, team1RatingCalc); } } calculator.UpdateRatings(results); foreach (var player in ratingsPlayers) { player.Item1.SkillRating = player.Item2.GetRating(); player.Item1.RatingsDeviation = player.Item2.GetRatingDeviation(); player.Item1.Volatility = player.Item2.GetVolatility(); } datastore.db.SaveChangesAsync(); }
public static void CalculateRatingFromStart() { var calculator = new RatingCalculator(); var results = new RatingPeriodResults(); var allChars = new List <CharacterModel>(); var allKillmails = new List <KillmailModel>(); using (var connection = DatabaseConnection.CreateConnection(DbConnectionString)) { var query = @" WITH hours AS ( SELECT generate_series( date_trunc('hour', (SELECT killed_at FROM killmail ORDER BY killed_at LIMIT 1)), date_trunc('hour', (SELECT killed_at FROM killmail ORDER BY killed_at DESC LIMIT 1)), '1 hour'::interval ) AS hour ) SELECT hours.hour, killmail.id, killmail.killed_at, killmail.victim_id, killmail.attacker_id FROM hours LEFT JOIN killmail ON date_trunc('hour', killmail.killed_at) = hours.hour LEFT JOIN killmail AS prev ON prev.killed_at = (SELECT MAX(killed_at) FROM killmail AS k1 WHERE k1.victim_id = killmail.victim_id AND k1.killed_at < killmail.killed_at ) WHERE prev.killed_at IS NULL OR (killmail.killed_at - prev.killed_at) > make_interval(mins => 10) ORDER BY hours.hour, killmail.killed_at ; "; try { allKillmails = connection.Query <KillmailModel>(query) .ToList(); } catch (Exception ex) { Console.WriteLine(ex); } } using (var connection = DatabaseConnection.CreateConnection(DbConnectionString)) { var query = @" SELECT id, name FROM character "; try { allChars = connection.Query <CharacterModel>(query).ToList(); } catch (Exception ex) { Console.WriteLine(ex); } } // Set initial rating and rd for all characters foreach (var character in allChars) { character.rating = new Rating(calculator); } var killmailsGroupedByTimeslice = allKillmails.ToLookup(x => x.Timeslice); foreach (var timesliceGroup in killmailsGroupedByTimeslice) { // Console.WriteLine(timesliceGroup); // No games in rating period. if (timesliceGroup.Count() == 1 && timesliceGroup.First().victim_id == null) { // Perform Rating calculation decay for all characters involved in kills so far calculator.UpdateRatings(results); } else { foreach (var killmailInTimesliceGroup in timesliceGroup) { if (killmailInTimesliceGroup.attacker_id == null) { continue; } // Perform Rating calculation var attacker = allChars.Find(x => x.id == killmailInTimesliceGroup.attacker_id.Value); var victim = allChars.Find(x => x.id == killmailInTimesliceGroup.victim_id.Value); results.AddResult(attacker.rating, victim.rating); // Set updated_at property for later checks on updating rating var timesliceOffset = new TimeSpan(0, 1, 0, 0);; attacker.updated_at = killmailInTimesliceGroup.Timeslice + timesliceOffset; victim.updated_at = killmailInTimesliceGroup.Timeslice + timesliceOffset; } // Perform Rating calculations (includes decay for all characters that are not in rating period if they were involved in kills in earlier timeslices) calculator.UpdateRatings(results); } } foreach (var character in allChars) { InsertRating(character); } }