1
0
Fork 0
mirror of https://github.com/ppy/osu-tools.git synced 2025-06-07 23:07:01 +09:00
osu-tools/PerformanceCalculator/Simulate/TaikoSimulateCommand.cs
2019-01-24 18:48:24 +09:00

106 lines
4.8 KiB
C#

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using JetBrains.Annotations;
using McMaster.Extensions.CommandLineUtils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Scoring;
namespace PerformanceCalculator.Simulate
{
[Command(Name = "simulate taiko", Description = "Computes the performance (pp) of a simulated osu!taiko play.")]
public class TaikoSimulateCommand : SimulateCommand
{
[UsedImplicitly]
[Required, FileExists]
[Argument(0, Name = "beatmap", Description = "Required. The beatmap file (.osu).")]
public override string Beatmap { get; }
[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.")]
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();
protected override Dictionary<HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood)
{
var totalResultCount = GetMaxCombo(beatmap);
int countGreat;
if (countGood != null)
{
countGreat = (int)(totalResultCount - countGood - countMiss);
}
else
{
// Let Great=2, Good=1, Miss=0. The total should be this.
var targetTotal = (int)Math.Round(accuracy * totalResultCount * 2);
countGreat = targetTotal - (totalResultCount - countMiss);
countGood = totalResultCount - countGreat - countMiss;
}
return new Dictionary<HitResult, int>
{
{ HitResult.Great, countGreat },
{ HitResult.Good, (int)countGood },
{ HitResult.Meh, 0 },
{ HitResult.Miss, countMiss }
};
}
protected override double GetAccuracy(Dictionary<HitResult, int> statistics)
{
var countGreat = statistics[HitResult.Great];
var countGood = statistics[HitResult.Good];
var countMiss = statistics[HitResult.Miss];
var total = countGreat + countGood + countMiss;
return (double)((2 * countGreat) + countGood) / (2 * total);
}
protected override void WritePlayInfo(ScoreInfo scoreInfo, IBeatmap beatmap)
{
WriteAttribute("Accuracy", (scoreInfo.Accuracy * 100).ToString(CultureInfo.InvariantCulture) + "%");
WriteAttribute("Combo", FormattableString.Invariant($"{scoreInfo.MaxCombo} ({Math.Round(100.0 * scoreInfo.MaxCombo / GetMaxCombo(beatmap), 2)}%)"));
WriteAttribute("Misses", scoreInfo.Statistics[HitResult.Miss].ToString(CultureInfo.InvariantCulture));
WriteAttribute("Goods", scoreInfo.Statistics[HitResult.Good].ToString(CultureInfo.InvariantCulture));
WriteAttribute("Greats", scoreInfo.Statistics[HitResult.Great].ToString(CultureInfo.InvariantCulture));
}
}
}