Skip to content

Commit

Permalink
count strain difficulty
Browse files Browse the repository at this point in the history
  • Loading branch information
jeenyuhs committed Jul 22, 2024
1 parent 6cbeb39 commit 7c5f059
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/osu/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ use crate::osu::performance::OsuPerformance;
pub struct OsuDifficultyAttributes {
/// The difficulty of the aim skill.
pub aim: f64,
/// The difficulty strain of the aim skill.
pub aim_strain_difficulty: f64,
/// The difficulty of the speed skill.
pub speed: f64,
/// The difficulty strain of the aim skill.
pub speed_strain_difficulty: f64,
/// The difficulty of the flashlight skill.
pub flashlight: f64,
/// The ratio of the aim strain with and without considering sliders
Expand Down
3 changes: 3 additions & 0 deletions src/osu/difficulty/gradual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ impl Iterator for OsuGradualDifficulty {
flashlight_difficulty_value,
);

attrs.aim_strain_difficulty = Skill::new(&mut self.skills.aim, &self.diff_objects).count_difficult_strains();
attrs.speed_strain_difficulty = Skill::new(&mut self.skills.speed, &self.diff_objects).count_difficult_strains();

Some(attrs)
}

Expand Down
4 changes: 4 additions & 0 deletions src/osu/difficulty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub fn difficulty(difficulty: &Difficulty, converted: &OsuBeatmap<'_>) -> OsuDif
} = DifficultyValues::calculate(difficulty, converted);

let aim_difficulty_value = aim.difficulty_value();

let aim_no_sliders_difficulty_value = aim_no_sliders.difficulty_value();
let speed_relevant_note_count = speed.relevant_note_count();
let speed_difficulty_value = speed.difficulty_value();
Expand Down Expand Up @@ -138,6 +139,9 @@ impl DifficultyValues {
speed.process(hit_object);
flashlight.process(hit_object);
}

attrs.aim_strain_difficulty = aim.count_difficult_strains();
attrs.speed_strain_difficulty = speed.count_difficult_strains();
}

Self { skills, attrs }
Expand Down
18 changes: 18 additions & 0 deletions src/osu/difficulty/skills/aim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const STRAIN_DECAY_BASE: f64 = 0.15;
pub struct Aim {
with_sliders: bool,
curr_strain: f64,
object_strains: Vec<f64>,
inner: OsuStrainSkill,
}

Expand All @@ -26,6 +27,7 @@ impl Aim {
Self {
with_sliders,
curr_strain: 0.0,
object_strains: vec![],
inner: OsuStrainSkill::default(),
}
}
Expand Down Expand Up @@ -106,8 +108,24 @@ impl<'a> Skill<'a, Aim> {
AimEvaluator::evaluate_diff_of(curr, self.diff_objects, self.inner.with_sliders)
* SKILL_MULTIPLIER;

self.inner.object_strains.push(self.inner.curr_strain);

self.inner.curr_strain
}

pub fn count_difficult_strains(&self) -> f64 {
let difficulty = self.inner.as_difficulty_value();

if difficulty == 0.0 {
0.0
} else {
println!("object strains: {:?}", self.inner.object_strains);
self.inner.object_strains
.iter()
.map(|&strain| 1.1 / (1.0 + ((-10.0 * (strain / (difficulty - 10.0) - 0.88)) as f64).exp()))
.sum()
}
}
}

struct AimEvaluator;
Expand Down
13 changes: 13 additions & 0 deletions src/osu/difficulty/skills/speed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,19 @@ impl<'a> Skill<'a, Speed> {

total_strain
}

pub fn count_difficult_strains(&self) -> f64 {
let difficulty = self.inner.as_difficulty_value();

if difficulty == 0.0 {
0.0
} else {
self.inner.object_strains
.iter()
.map(|&strain| 1.1 / (1.0 + ((-10.0 * (strain / (difficulty - 10.0) - 0.88)) as f64).exp()))
.sum()
}
}
}

struct SpeedEvaluator;
Expand Down
5 changes: 3 additions & 2 deletions src/osu/performance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ impl OsuPerformanceInner {
// In the "remove combo scaling" rework, they assume
// the scores misses, are done at the hardest parts of the map.
// https://github.com/ppy/osu/blob/c25e1bdeb586db8a2def47232632be61b4d4242e/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs#L261-L264
aim_value *= 0.96 / ((self.effective_miss_count / (4.0 * self.attrs.aim.log10().powf(0.94))) + 1.0);
aim_value *= 0.96 / ((self.effective_miss_count / (4.0 * self.attrs.aim_strain_difficulty.log10().max(0.0).powf(0.94))) + 1.0);

}

Expand Down Expand Up @@ -674,11 +674,12 @@ impl OsuPerformanceInner {

// * Penalize misses by assessing # of misses relative to the total # of objects.
// * Default a 3% reduction for any # of misses.
println!("{}", self.attrs.speed_strain_difficulty);
if self.effective_miss_count > 0.0 {
// In the "remove combo scaling" rework, they assume
// the scores misses, are done at the hardest parts of the map.
// https://github.com/ppy/osu/blob/c25e1bdeb586db8a2def47232632be61b4d4242e/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs#L261-L264
speed_value *= 0.96 / ((self.effective_miss_count / (4.0 * self.attrs.speed.log10().powf(0.94))) + 1.0);
speed_value *= 0.96 / ((self.effective_miss_count / (4.0 * self.attrs.speed_strain_difficulty.log10().max(0.0).powf(0.94))) + 1.0);
}

let ar_factor = if self.attrs.ar > 10.33 {
Expand Down
1 change: 0 additions & 1 deletion src/taiko/difficulty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ pub fn difficulty(
peaks.rhythm_difficulty_value()
};

println!("{}", color_rating);
let stamina_rating = peaks.stamina_difficulty_value();
let combined_rating = peaks.difficulty_value();

Expand Down
29 changes: 29 additions & 0 deletions tests/difficulty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ macro_rules! test_cases {
};
( @Osu {
aim: $aim:literal,
aim_strain_difficulty: $aim_strain_difficulty:literal,
speed: $speed:literal,
speed_strain_difficulty: $speed_strain_difficulty:literal,
flashlight: $flashlight:literal,
slider_factor: $slider_factor:literal,
speed_note_count: $speed_note_count:literal,
Expand All @@ -46,6 +48,8 @@ macro_rules! test_cases {
}) => {
OsuDifficultyAttributes {
aim: $aim,
aim_strain_difficulty: $aim_strain_difficulty,
speed_strain_difficulty: $speed_strain_difficulty,
speed: $speed,
flashlight: $flashlight,
slider_factor: $slider_factor,
Expand Down Expand Up @@ -122,7 +126,9 @@ fn basic_osu() {
Osu: OSU {
NM => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.288770487900865,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -137,7 +143,9 @@ fn basic_osu() {
};
HD => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.606877929965889,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -152,7 +160,9 @@ fn basic_osu() {
};
HR => {
aim: 3.2385394176190507,
aim_strain_difficulty: 0.0,
speed: 2.7009854505234308,
speed_strain_difficulty: 0.0,
flashlight: 2.8549217213059936,
slider_factor: 0.9690667605258665,
speed_note_count: 184.01205359079387,
Expand All @@ -167,7 +177,9 @@ fn basic_osu() {
};
DT => {
aim: 4.041442573946681,
aim_strain_difficulty: 0.0,
speed: 3.6784866216272474,
speed_strain_difficulty: 0.0,
flashlight: 3.319522943625448,
slider_factor: 0.9776943279272041,
speed_note_count: 214.80421464205617,
Expand All @@ -182,7 +194,9 @@ fn basic_osu() {
};
FL => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.288770487900865,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -197,7 +211,9 @@ fn basic_osu() {
};
HD FL => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.606877929965889,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -217,7 +233,9 @@ fn basic_osu() {
Osu: OSU {
NM => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.288770487900865,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -232,7 +250,9 @@ fn basic_osu() {
};
HD => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.606877929965889,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -247,7 +267,9 @@ fn basic_osu() {
};
HR => {
aim: 3.2385394176190507,
aim_strain_difficulty: 0.0,
speed: 2.7009854505234308,
speed_strain_difficulty: 0.0,
flashlight: 2.8549217213059936,
slider_factor: 0.9690667605258665,
speed_note_count: 184.01205359079387,
Expand All @@ -262,7 +284,9 @@ fn basic_osu() {
};
DT => {
aim: 4.041442573946681,
aim_strain_difficulty: 0.0,
speed: 3.6784866216272474,
speed_strain_difficulty: 0.0,
flashlight: 3.319522943625448,
slider_factor: 0.9776943279272041,
speed_note_count: 214.80421464205617,
Expand All @@ -277,7 +301,9 @@ fn basic_osu() {
};
FL => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.288770487900865,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand All @@ -292,7 +318,9 @@ fn basic_osu() {
};
HD FL => {
aim: 2.8693628443424104,
aim_strain_difficulty: 0.0,
speed: 2.533869745015772,
speed_strain_difficulty: 0.0,
flashlight: 2.606877929965889,
slider_factor: 0.9803052946037858,
speed_note_count: 210.36373973116545,
Expand Down Expand Up @@ -521,6 +549,7 @@ where

impl AssertEq for OsuDifficultyAttributes {
fn assert_eq(&self, expected: &Self) {
println!("{} - {}", self.aim_strain_difficulty, expected.aim);
assert_eq_float(self.aim, expected.aim);
assert_eq_float(self.speed, expected.speed);
assert_eq_float(self.flashlight, expected.flashlight);
Expand Down

0 comments on commit 7c5f059

Please sign in to comment.