Add initial changes

This commit is contained in:
smoogipoo
2020-05-11 14:50:02 +09:00
parent adf9a90fc4
commit d613888803
9 changed files with 726 additions and 107 deletions

View File

@ -0,0 +1,95 @@
// 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 osu.Game.Rulesets.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
{
public class StaminaCheeseDetector
{
private const int roll_min_repetitions = 12;
private const int tl_min_repetitions = 16;
private List<TaikoDifficultyHitObject> hitObjects;
public void FindCheese(List<TaikoDifficultyHitObject> difficultyHitObjects)
{
this.hitObjects = difficultyHitObjects;
findRolls(3);
findRolls(4);
findTLTap(0, true);
findTLTap(1, true);
findTLTap(0, false);
findTLTap(1, false);
}
private void findRolls(int patternLength)
{
List<TaikoDifficultyHitObject> history = new List<TaikoDifficultyHitObject>();
int repititionStart = 0;
for (int i = 0; i < hitObjects.Count; i++)
{
history.Add(hitObjects[i]);
if (history.Count < 2 * patternLength) continue;
if (history.Count > 2 * patternLength) history.RemoveAt(0);
bool isRepeat = true;
for (int j = 0; j < patternLength; j++)
{
if (history[j].IsKat != history[j + patternLength].IsKat)
{
isRepeat = false;
}
}
if (!isRepeat)
{
repititionStart = i - 2 * patternLength;
}
int repeatedLength = i - repititionStart;
if (repeatedLength >= roll_min_repetitions)
{
// Console.WriteLine("Found Roll Cheese.\tStart: " + repititionStart + "\tEnd: " + i);
for (int j = repititionStart; j < i; j++)
{
(hitObjects[i]).StaminaCheese = true;
}
}
}
}
private void findTLTap(int parity, bool kat)
{
int tl_length = -2;
for (int i = parity; i < hitObjects.Count; i += 2)
{
if (kat == hitObjects[i].IsKat)
{
tl_length += 2;
}
else
{
tl_length = -2;
}
if (tl_length >= tl_min_repetitions)
{
// Console.WriteLine("Found TL Cheese.\tStart: " + (i - tl_length) + "\tEnd: " + i);
for (int j = i - tl_length; j < i; j++)
{
(hitObjects[i]).StaminaCheese = true;
}
}
}
}
}
}

View File

@ -1,6 +1,7 @@
// 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 osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Taiko.Objects;
@ -10,11 +11,36 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
public class TaikoDifficultyHitObject : DifficultyHitObject
{
public readonly bool HasTypeChange;
public readonly bool HasTimingChange;
public readonly TaikoDifficultyHitObjectRhythm Rhythm;
public readonly bool IsKat;
public TaikoDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate)
public bool StaminaCheese = false;
public readonly int RhythmID;
public readonly double NoteLength;
public readonly int n;
private int counter = 0;
public TaikoDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject lastLastObject, double clockRate)
: base(hitObject, lastObject, clockRate)
{
HasTypeChange = (lastObject as Hit)?.Type != (hitObject as Hit)?.Type;
NoteLength = DeltaTime;
double prevLength = (lastObject.StartTime - lastLastObject.StartTime) / clockRate;
Rhythm = TaikoDifficultyHitObjectRhythm.GetClosest(NoteLength / prevLength);
RhythmID = Rhythm.ID;
HasTypeChange = lastObject is RimHit != hitObject is RimHit;
IsKat = lastObject is RimHit;
HasTimingChange = !TaikoDifficultyHitObjectRhythm.IsRepeat(RhythmID);
n = counter;
counter++;
}
public const int CONST_RHYTHM_ID = 0;
}
}

View File

@ -0,0 +1,124 @@
// 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;
namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing
{
public class TaikoDifficultyHitObjectRhythm
{
private static TaikoDifficultyHitObjectRhythm[] commonRhythms;
private static TaikoDifficultyHitObjectRhythm constRhythm;
private static int constRhythmID;
public int ID = 0;
public readonly double Difficulty;
private readonly double ratio;
private static void initialiseCommonRhythms()
{
/*
ALCHYRS CODE
If (change < 0.48) Then 'sometimes gaps are slightly different due to position rounding
Return 0.65 'This number increases value of anything that more than doubles speed. Affects doubles.
ElseIf (change < 0.52) Then
Return 0.5 'speed doubling - this one affects pretty much every map other than stream maps
ElseIf change <= 0.9 Then
Return 1.0 'This number increases value of 1/4 -> 1/6 and other weird rhythms.
ElseIf change < 0.95 Then
Return 0.25 '.9
ElseIf change > 1.95 Then
Return 0.3 'half speed or more - this affects pretty much every map
ElseIf change > 1.15 Then
Return 0.425 'in between - this affects (mostly) 1/6 -> 1/4
ElseIf change > 1.05 Then
Return 0.15 '.9, small speed changes
*/
commonRhythms = new TaikoDifficultyHitObjectRhythm[]
{
new TaikoDifficultyHitObjectRhythm(1, 1, 0.1),
new TaikoDifficultyHitObjectRhythm(2, 1, 0.3),
new TaikoDifficultyHitObjectRhythm(1, 2, 0.5),
new TaikoDifficultyHitObjectRhythm(3, 1, 0.3),
new TaikoDifficultyHitObjectRhythm(1, 3, 0.35),
new TaikoDifficultyHitObjectRhythm(3, 2, 0.6),
new TaikoDifficultyHitObjectRhythm(2, 3, 0.4),
new TaikoDifficultyHitObjectRhythm(5, 4, 0.5),
new TaikoDifficultyHitObjectRhythm(4, 5, 0.7)
};
for (int i = 0; i < commonRhythms.Length; i++)
{
commonRhythms[i].ID = i;
}
constRhythmID = 0;
constRhythm = commonRhythms[constRhythmID];
}
public bool IsRepeat()
{
return ID == constRhythmID;
}
public static bool IsRepeat(int id)
{
return id == constRhythmID;
}
public bool IsSpeedup()
{
return ratio < 1.0;
}
public bool IsLargeSpeedup()
{
return ratio < 0.49;
}
private TaikoDifficultyHitObjectRhythm(double ratio, double difficulty)
{
this.ratio = ratio;
this.Difficulty = difficulty;
}
private TaikoDifficultyHitObjectRhythm(int numerator, int denominator, double difficulty)
{
this.ratio = ((double)numerator) / ((double)denominator);
this.Difficulty = difficulty;
}
// Code is inefficient - we are searching exhaustively through the sorted list commonRhythms
public static TaikoDifficultyHitObjectRhythm GetClosest(double ratio)
{
if (commonRhythms == null)
{
initialiseCommonRhythms();
}
TaikoDifficultyHitObjectRhythm closestRhythm = commonRhythms[0];
double closestDistance = Double.MaxValue;
foreach (TaikoDifficultyHitObjectRhythm r in commonRhythms)
{
if (Math.Abs(r.ratio - ratio) < closestDistance)
{
closestRhythm = r;
closestDistance = Math.Abs(r.ratio - ratio);
}
}
return closestRhythm;
}
}
}