public float GetAcc(SongID songID) { // First check for song specific accuracy if (_songSpecificAcc.ContainsKey(songID)) { return(RoundedAcc(_songSpecificAcc[songID])); } double bestAcc = 0; // Next check for max of current best acc and star acc if (ProfileDataLoader.instance.songDataInfo.ContainsKey(songID)) { bestAcc = ProfileDataLoader.instance.songDataInfo[songID].acc; } // Next check for star acc var star = SongDataUtils.GetRoundedStars(songID); if (_starAcc.ContainsKey(star)) { bestAcc = Math.Max(bestAcc, _starAcc[star]); } if (bestAcc > 0) { return(RoundedAcc(bestAcc)); } // Finally resort to default return(Config.defaultAcc); }
// Loops through all songs and finds the highest star difficulty saved (rounded to nearest multiple of starRange) private static double CalculateMaxStarValue() { double maxStarValue = 0; foreach (var kvp in ProfileDataLoader.instance.songDataInfo) { if (SongDataCore.Plugin.Songs.Data.Songs.TryGetValue(kvp.Key.id, out var song)) { var difficultyStats = SongDataCore.Plugin.Songs.Data.Songs[kvp.Key.id].diffs; foreach (var difficultyStat in difficultyStats) { if (difficultyStat.diff.Equals(SongDataUtils.GetDifficultyAsString(kvp.Key.difficulty))) { var star = SongDataUtils.GetRoundedStars(difficultyStat.star); maxStarValue = star > maxStarValue ? star : maxStarValue; } } } } return(Math.Round(maxStarValue, 2)); }
public static void CalculateAcc() { Logger.log.Debug("Calculating star acc"); var range = Config.starRange; Dictionary <double, double> acc = new Dictionary <double, double>(); Dictionary <double, int> counts = new Dictionary <double, int>(); // Need SongDataCore data if (!SongDataCore.Plugin.Songs.IsDataAvailable()) { return; } // Initialize some helper vars var numberOfScores = Config.starAccChoice.Equals(CalculationType.Max) ? 1 : Config.numberOfScores; var maxScores = new Dictionary <double, List <double> >(); var maxStarValue = CalculateMaxStarValue(); var averageAll = Config.starAccChoice.Equals(CalculationType.AverageOfAll); // Initialize dicts for (double star = 0.00; star <= maxStarValue + 2 * Config.starRange; star += Config.starRange) { star = SongDataUtils.GetRoundedStars(star); acc[star] = 0; counts[star] = 0; } foreach (var kvp in ProfileDataLoader.instance.songDataInfo) { // If star data not available for song, skip it double star; try { star = SongDataUtils.GetRoundedStars(kvp.Key); } catch (Exception e) { Logger.log.Debug($"Couldn't get star rating for {kvp.Key.id}"); continue; } // Will definitely be updating acc if (averageAll || counts[star] < numberOfScores) { acc[star] = ((acc[star] * counts[star]) + kvp.Value.acc) / (counts[star] + 1); counts[star] += 1; // update maxScores if (!averageAll) { // first score for given star rating if (!maxScores.ContainsKey(star)) { maxScores[star] = new List <double>(); } maxScores[star].Add(kvp.Value.acc); maxScores[star].Sort(); // List is small enough to not matter } } // Better than the lowest sore, update average acc else if (kvp.Value.acc > maxScores[star].First()) { var accWithoutLowerScore = acc[star] * counts[star] - maxScores[star].First(); acc[star] = (accWithoutLowerScore + kvp.Value.acc) / (counts[star]); // update maxScores maxScores[star].RemoveAt(0); maxScores[star].Add(kvp.Value.acc); maxScores[star].Sort(); } } if (Config.accOverride) { CleanupStarAcc(ref acc); } Logger.log.Debug("Finished calculating star acc"); SaveFile(acc); }