Skip to content

Commit

Permalink
Merge pull request #223 from minisbett/simulate-parameter-handling
Browse files Browse the repository at this point in the history
Move `SimulateCommand` option implementations to base class
  • Loading branch information
smoogipoo authored Oct 22, 2024
2 parents 290070b + 2269f1b commit 1d17138
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 95 deletions.
17 changes: 1 addition & 16 deletions PerformanceCalculator/Simulate/CatchSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,14 @@ namespace PerformanceCalculator.Simulate
[Command(Name = "catch", Description = "Computes the performance (pp) of a simulated osu!catch play.")]
public class CatchSimulateCommand : SimulateCommand
{
[UsedImplicitly]
[Option(Template = "-a|--accuracy <accuracy>", Description = "Accuracy. Enter as decimal 0-100. Defaults to 100."
+ " Scales hit results as well and is rounded to the nearest possible value for the beatmap.")]
public override double Accuracy { get; } = 100;

[UsedImplicitly]
[Option(Template = "-c|--combo <combo>", Description = "Maximum combo during play. Defaults to beatmap maximum.")]
public override int? Combo { get; }

[UsedImplicitly]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option."
+ " Enter as decimal 0-100.")]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option. Enter as decimal 0-100.")]
public override double PercentCombo { get; } = 100;

[UsedImplicitly]
[Option(CommandOptionType.MultipleValue, Template = "-m|--mod <mod>", Description = "One for each mod. The mods to compute the performance with."
+ " Values: hr, dt, hd, fl, ez, etc...")]
public override string[] Mods { get; }

[UsedImplicitly]
[Option(Template = "-X|--misses <misses>", Description = "Number of misses. Defaults to 0.")]
public override int Misses { get; }

[UsedImplicitly]
[Option(Template = "-T|--tiny-droplets <tinys>", Description = "Number of tiny droplets hit. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Mehs { get; }
Expand Down
38 changes: 12 additions & 26 deletions PerformanceCalculator/Simulate/ManiaSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,21 @@ namespace PerformanceCalculator.Simulate
[Command(Name = "mania", Description = "Computes the performance (pp) of a simulated osu!mania play.")]
public class ManiaSimulateCommand : SimulateCommand
{
[UsedImplicitly]
[Option(Template = "-a|--accuracy <accuracy>", Description = "Accuracy. Enter as decimal 0-100. Defaults to 100."
+ " Scales hit results as well and is rounded to the nearest possible value for the beatmap.")]
public override double Accuracy { get; } = 100;

[UsedImplicitly]
[Option(Template = "-X|--misses <misses>", Description = "Number of misses. Defaults to 0.")]
public override int Misses { get; }

[UsedImplicitly]
[Option(Template = "-M|--mehs <mehs>", Description = "Number of mehs. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Mehs { get; }

[UsedImplicitly]
[Option(Template = "-O|--oks <oks>", Description = "Number of oks. Will override accuracy if used. Otherwise is automatically calculated.")]
private int? oks { get; set; }

[UsedImplicitly]
[Option(Template = "-G|--goods <goods>", Description = "Number of goods. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Goods { get; }

[UsedImplicitly]
[Option(Template = "-T|--greats <greats>", Description = "Number of greats. Will override accuracy if used. Otherwise is automatically calculated.")]
private int? greats { get; set; }
[Option(Template = "-O|--oks <oks>", Description = "Number of oks. Will override accuracy if used. Otherwise is automatically calculated.")]
private int? oks { get; }

[UsedImplicitly]
[Option(CommandOptionType.MultipleValue, Template = "-m|--mod <mod>", Description = "One for each mod. The mods to compute the performance with."
+ " Values: hr, dt, fl, 4k, 5k, etc...")]
public override string[] Mods { get; }
[Option(Template = "-T|--greats <greats>", Description = "Number of greats. Will override accuracy if used. Otherwise is automatically calculated.")]
private int? greats { get; }

public override Ruleset Ruleset => new ManiaRuleset();

Expand Down Expand Up @@ -82,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);
greats = greatsAndPerfects / 2;
int perfects = greatsAndPerfects - greats.Value;
delta -= (greats.Value + perfects) * 5;
remainingHits -= greats.Value + perfects;
int countGreat = greatsAndPerfects / 2;
int perfects = greatsAndPerfects - countGreat;
delta -= (countGreat + perfects) * 5;
remainingHits -= countGreat + 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).
oks = delta;
remainingHits -= oks.Value;
int countOk = delta;
remainingHits -= countOk;

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

return new Dictionary<HitResult, int>
{
{ HitResult.Perfect, perfects },
{ HitResult.Great, greats.Value },
{ HitResult.Ok, oks.Value },
{ HitResult.Great, countGreat },
{ HitResult.Ok, countOk },
{ HitResult.Good, countGood.Value },
{ HitResult.Meh, countMeh.Value },
{ HitResult.Miss, countMiss }
Expand Down
29 changes: 7 additions & 22 deletions PerformanceCalculator/Simulate/OsuSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,21 @@ namespace PerformanceCalculator.Simulate
public class OsuSimulateCommand : SimulateCommand
{
[UsedImplicitly]
[Option(Template = "-a|--accuracy <accuracy>", Description = "Accuracy. Enter as decimal 0-100. Defaults to 100."
+ " Scales hit results as well and is rounded to the nearest possible value for the beatmap.")]
public override double Accuracy { get; } = 100;
[Option(Template = "-M|--mehs <mehs>", Description = "Number of mehs. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Mehs { get; }

[UsedImplicitly]
[Option(Template = "-G|--goods <goods>", Description = "Number of goods. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Goods { get; }

[UsedImplicitly]
[Option(Template = "-c|--combo <combo>", Description = "Maximum combo during play. Defaults to beatmap maximum.")]
public override int? Combo { get; }

[UsedImplicitly]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option."
+ " Enter as decimal 0-100.")]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option. Enter as decimal 0-100.")]
public override double PercentCombo { get; } = 100;

[UsedImplicitly]
[Option(CommandOptionType.MultipleValue, Template = "-m|--mod <mod>", Description = "One for each mod. The mods to compute the performance with."
+ " Values: hr, dt, hd, fl, ez, etc...")]
public override string[] Mods { get; }

[UsedImplicitly]
[Option(Template = "-X|--misses <misses>", Description = "Number of misses. Defaults to 0.")]
public override int Misses { get; }

[UsedImplicitly]
[Option(Template = "-M|--mehs <mehs>", Description = "Number of mehs. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Mehs { get; }

[UsedImplicitly]
[Option(Template = "-G|--goods <goods>", Description = "Number of goods. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Goods { get; }

public override Ruleset Ruleset => new OsuRuleset();

protected override int GetMaxCombo(IBeatmap beatmap) => beatmap.GetMaxCombo();
Expand Down
31 changes: 18 additions & 13 deletions PerformanceCalculator/Simulate/SimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,34 @@ public abstract class SimulateCommand : ProcessorCommand
public string Beatmap { get; }

[UsedImplicitly]
public virtual double Accuracy { get; }
[Option(Template = "-a|--accuracy <accuracy>", Description = "Accuracy. Enter as decimal 0-100. Defaults to 100. Scales hit results as well and is rounded to the nearest possible value for the beatmap.")]
public double Accuracy { get; } = 100;

[UsedImplicitly]
public virtual int? Combo { get; }

[UsedImplicitly]
public virtual double PercentCombo { get; }
[Option(CommandOptionType.MultipleValue, Template = "-m|--mod <mod>", Description = "One for each mod. The mods to compute the performance with. Values: hr, dt, hd, fl, etc...")]
public string[] Mods { get; }

[UsedImplicitly]
public virtual int Score { get; }

[Option(Template = "-X|--misses <misses>", Description = "Number of misses. Defaults to 0.")]
public int Misses { get; }

//
// Options implemented in the ruleset-specific commands
// -> Catch renames Mehs/Goods to (tiny-)droplets
// -> Mania does not have Combo
// -> Taiko does not have Mehs
//
[UsedImplicitly]
public virtual string[] Mods { get; }
public virtual int? Mehs { get; }

[UsedImplicitly]
public virtual int Misses { get; }
public virtual int? Goods { get; }

[UsedImplicitly]
public virtual int? Mehs { get; }
public virtual int? Combo { get; }

[UsedImplicitly]
public virtual int? Goods { get; }
public virtual double PercentCombo { get; }

public override void Execute()
{
Expand All @@ -63,8 +69,7 @@ public override void Execute()
Accuracy = GetAccuracy(statistics),
MaxCombo = Combo ?? (int)Math.Round(PercentCombo / 100 * beatmapMaxCombo),
Statistics = statistics,
Mods = mods,
TotalScore = Score,
Mods = mods
};

var difficultyCalculator = ruleset.CreateDifficultyCalculator(workingBeatmap);
Expand Down
21 changes: 3 additions & 18 deletions PerformanceCalculator/Simulate/TaikoSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,17 @@ namespace PerformanceCalculator.Simulate
public class TaikoSimulateCommand : SimulateCommand
{
[UsedImplicitly]
[Option(Template = "-a|--accuracy <accuracy>", Description = "Accuracy. Enter as decimal 0-100. Defaults to 100."
+ " Scales hit results as well and is rounded to the nearest possible value for the beatmap.")]
public override double Accuracy { get; } = 100;
[Option(Template = "-G|--goods <goods>", Description = "Number of goods. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Goods { get; }

[UsedImplicitly]
[Option(Template = "-c|--combo <combo>", Description = "Maximum combo during play. Defaults to beatmap maximum.")]
public override int? Combo { get; }

[UsedImplicitly]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option."
+ " Enter as decimal 0-100.")]
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option. Enter as decimal 0-100.")]
public override double PercentCombo { get; } = 100;

[UsedImplicitly]
[Option(CommandOptionType.MultipleValue, Template = "-m|--mod <mod>", Description = "One for each mod. The mods to compute the performance with."
+ " Values: hr, dt, hd, fl, ez, etc...")]
public override string[] Mods { get; }

[UsedImplicitly]
[Option(Template = "-X|--misses <misses>", Description = "Number of misses. Defaults to 0.")]
public override int Misses { get; }

[UsedImplicitly]
[Option(Template = "-G|--goods <goods>", Description = "Number of goods. Will override accuracy if used. Otherwise is automatically calculated.")]
public override int? Goods { get; }

public override Ruleset Ruleset => new TaikoRuleset();

protected override int GetMaxCombo(IBeatmap beatmap) => beatmap.HitObjects.OfType<Hit>().Count();
Expand Down

0 comments on commit 1d17138

Please sign in to comment.