Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Givikap120 committed Nov 15, 2024
1 parent 89b8f3b commit 66b20a6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 28 deletions.
4 changes: 3 additions & 1 deletion PerformanceCalculator/Simulate/CatchSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public class CatchSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new CatchRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood)
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countGood)
{
var maxCombo = beatmap.GetMaxCombo();
int maxTinyDroplets = beatmap.HitObjects.OfType<JuiceStream>().Sum(s => s.NestedHitObjects.OfType<TinyDroplet>().Count());
Expand Down
28 changes: 15 additions & 13 deletions PerformanceCalculator/Simulate/ManiaSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,23 @@ public class ManiaSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new ManiaRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood)
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, oks, Goods, greats);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countOk, int? countGood, int? countGreat)
{
// One judgement per normal note. Two judgements per hold note (head + tail).
var totalHits = beatmap.HitObjects.Count + beatmap.HitObjects.Count(ho => ho is HoldNote);

if (countMeh != null || oks != null || countGood != null || greats != null)
if (countMeh != null || countOk != null || countGood != null || countGreat != null)
{
int countPerfect = totalHits - (countMiss + (countMeh ?? 0) + (oks ?? 0) + (countGood ?? 0) + (greats ?? 0));
int countPerfect = totalHits - (countMiss + (countMeh ?? 0) + (countOk ?? 0) + (countGood ?? 0) + (countGreat ?? 0));

return new Dictionary<HitResult, int>
{
[HitResult.Perfect] = countPerfect,
[HitResult.Great] = greats ?? 0,
[HitResult.Great] = countGreat ?? 0,
[HitResult.Good] = countGood ?? 0,
[HitResult.Ok] = oks ?? 0,
[HitResult.Ok] = countOk ?? 0,
[HitResult.Meh] = countMeh ?? 0,
[HitResult.Miss] = countMiss
};
Expand All @@ -66,28 +68,28 @@ protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy
// Each great and perfect increases total by 5 (great-meh=5)
// There is no difference in accuracy between them, so just halve arbitrarily (favouring perfects for an odd number).
int greatsAndPerfects = Math.Min(delta / 5, remainingHits);
int countGreat = greatsAndPerfects / 2;
int perfects = greatsAndPerfects - countGreat;
delta -= (countGreat + perfects) * 5;
remainingHits -= countGreat + perfects;
int greats = greatsAndPerfects / 2;
int perfects = greatsAndPerfects - greats;
delta -= (greats + perfects) * 5;
remainingHits -= greats + perfects;

// Each good increases total by 3 (good-meh=3).
countGood = Math.Min(delta / 3, remainingHits);
delta -= countGood.Value * 3;
remainingHits -= countGood.Value;

// Each ok increases total by 1 (ok-meh=1).
int countOk = delta;
remainingHits -= countOk;
int oks = delta;
remainingHits -= oks;

// Everything else is a meh, as initially assumed.
countMeh = remainingHits;

return new Dictionary<HitResult, int>
{
{ HitResult.Perfect, perfects },
{ HitResult.Great, countGreat },
{ HitResult.Ok, countOk },
{ HitResult.Great, greats },
{ HitResult.Ok, oks },
{ HitResult.Good, countGood.Value },
{ HitResult.Meh, countMeh.Value },
{ HitResult.Miss, countMiss }
Expand Down
42 changes: 32 additions & 10 deletions PerformanceCalculator/Simulate/OsuSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ public class OsuSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new OsuRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood)
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, Goods, largeTickMisses, sliderTailMisses);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses, int? countSliderTailMisses)
{
int countGreat;

Expand Down Expand Up @@ -119,15 +121,21 @@ protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy
countGreat = (int)(totalResultCount - countGood - countMeh - countMiss);
}

return new Dictionary<HitResult, int>
var result = new Dictionary<HitResult, int>
{
{ HitResult.Great, countGreat },
{ HitResult.Ok, countGood ?? 0 },
{ HitResult.Meh, countMeh ?? 0 },
{ HitResult.LargeTickMiss, largeTickMisses },
{ HitResult.SliderTailHit, beatmap.HitObjects.Count(x => x is Slider) - sliderTailMisses },
{ HitResult.Miss, countMiss }
};

if (countLargeTickMisses != null)
result[HitResult.LargeTickMiss] = countLargeTickMisses.Value;

if (countSliderTailMisses != null)
result[HitResult.SliderTailHit] = beatmap.HitObjects.Count(x => x is Slider) - countSliderTailMisses.Value;

return result;
}

protected override double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics)
Expand All @@ -137,14 +145,28 @@ protected override double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, in
var countMeh = statistics[HitResult.Meh];
var countMiss = statistics[HitResult.Miss];

var countSliders = beatmap.HitObjects.Count(x => x is Slider);
var countSliderTailHit = statistics[HitResult.SliderTailHit];
var countLargeTicks = beatmap.HitObjects.Sum(obj => obj.NestedHitObjects.Count(x => x is SliderTick or SliderRepeat));
var countLargeTickHit = countLargeTicks - statistics[HitResult.LargeTickMiss];
double total = 6 * countGreat + 2 * countGood + countMeh;
double max = 6 * (countGreat + countGood + countMeh + countMiss);

if (statistics.ContainsKey(HitResult.SliderTailHit))

Check notice on line 151 in PerformanceCalculator/Simulate/OsuSimulateCommand.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Dictionary lookup can be simplified with 'TryGetValue' in PerformanceCalculator\Simulate\OsuSimulateCommand.cs on line 151
{
var countSliders = beatmap.HitObjects.Count(x => x is Slider);
var countSliderTailHit = statistics[HitResult.SliderTailHit];

double total = 6 * (countGreat + countGood + countMeh + countMiss) + 3 * countSliders + 0.6 * countLargeTicks;
total += 3 * countSliderTailHit;
max += 3 * countSliders;
}

if (statistics.ContainsKey(HitResult.LargeTickMiss))

Check notice on line 160 in PerformanceCalculator/Simulate/OsuSimulateCommand.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Dictionary lookup can be simplified with 'TryGetValue' in PerformanceCalculator\Simulate\OsuSimulateCommand.cs on line 160
{
var countLargeTicks = beatmap.HitObjects.Sum(obj => obj.NestedHitObjects.Count(x => x is SliderTick or SliderRepeat));
var countLargeTickHit = countLargeTicks - statistics[HitResult.LargeTickMiss];

total += 0.6 * countLargeTickHit;
max += 0.6 * countLargeTicks;
}

return (6 * countGreat + 2 * countGood + countMeh + 3 * countSliderTailHit + 0.6 * countLargeTickHit) / total;
return total / max;
}
}
}
6 changes: 3 additions & 3 deletions PerformanceCalculator/Simulate/SimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ public override void Execute()

var workingBeatmap = ProcessorWorkingBeatmap.FromFileOrId(Beatmap);
var mods = ParseMods(ruleset, Mods, ModOptions);
var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo, mods);
var beatmap = workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo);

var beatmapMaxCombo = beatmap.GetMaxCombo();
var statistics = GenerateHitResults(Accuracy / 100, beatmap, Misses, Mehs, Goods);
var statistics = GenerateHitResults(beatmap);
var scoreInfo = new ScoreInfo(beatmap.BeatmapInfo, ruleset.RulesetInfo)
{
Accuracy = GetAccuracy(beatmap, statistics),
Expand All @@ -83,7 +83,7 @@ public override void Execute()
OutputPerformance(scoreInfo, performanceAttributes, difficultyAttributes);
}

protected abstract Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood);
protected abstract Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap);

protected virtual double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics) => 0;
}
Expand Down
4 changes: 3 additions & 1 deletion PerformanceCalculator/Simulate/TaikoSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ public class TaikoSimulateCommand : SimulateCommand

public override Ruleset Ruleset => new TaikoRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood)
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap) => generateHitResults(Accuracy / 100, beatmap, Misses, Goods);

private static Dictionary<HitResult, int> generateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countGood)
{
var totalResultCount = beatmap.GetMaxCombo();

Expand Down

0 comments on commit 66b20a6

Please sign in to comment.