feat: calculate dx rating func

This commit is contained in:
mokurin000
2025-08-20 21:05:16 +08:00
parent 68b6a36fc8
commit f1886a9302

View File

@@ -1,4 +1,4 @@
use std::sync::LazyLock; use std::{ops::RangeInclusive, sync::LazyLock};
use rust_decimal::{Decimal, dec, serde::DecimalFromString}; use rust_decimal::{Decimal, dec, serde::DecimalFromString};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@@ -58,13 +58,19 @@ impl Level {
/// ///
/// On invalid input, it returns 0. /// On invalid input, it returns 0.
pub fn dx_rating(&self, achievement: i32) -> (&'static str, u32) { pub fn dx_rating(&self, achievement: i32) -> (&'static str, u32) {
let difficulty_rank: Decimal = self.difficulty.value;
let achievement = achievement.min(1005000); // SSS+ case let achievement = achievement.min(1005000); // SSS+ case
dx_rating(difficulty_rank, achievement)
}
}
pub fn dx_rating(difficulty_rank: Decimal, achievement: i32) -> (&'static str, u32) {
let (rank, _, factor) = RANKS let (rank, _, factor) = RANKS
.into_iter() .into_iter()
.rev() .rev()
.find(|&(_, threshold, _)| threshold <= achievement) .find(|(_, threshold, _)| threshold.contains(&achievement))
.unwrap(); // save here, due to zero threshold .unwrap(); // save here, due to zero threshold
let difficulty_rank: Decimal = self.difficulty.value;
let achievement = Decimal::new(achievement as _, 4); let achievement = Decimal::new(achievement as _, 4);
#[cfg(feature = "log")] #[cfg(feature = "log")]
@@ -75,34 +81,34 @@ impl Level {
.floor() .floor()
.try_into() .try_into()
.unwrap_or_default(); .unwrap_or_default();
(rank, rating) (rank, rating)
} }
}
const RANKS: [(&'static str, i32, Decimal); 23] = [ const RANKS: [(&'static str, RangeInclusive<i32>, Decimal); 23] = [
("D", 0, dec!(0.0)), ("D", 0..=99999, dec!(0.0)),
("D", 100000, dec!(0.016)), ("D", 100000..=199999, dec!(0.016)),
("D", 200000, dec!(0.032)), ("D", 200000..=299999, dec!(0.032)),
("D", 300000, dec!(0.048)), ("D", 300000..=399999, dec!(0.048)),
("D", 400000, dec!(0.064)), ("D", 400000..=499999, dec!(0.064)),
("C", 500000, dec!(0.080)), ("C", 500000..=599999, dec!(0.080)),
("B", 600000, dec!(0.096)), ("B", 600000..=699999, dec!(0.096)),
("BB", 700000, dec!(0.112)), ("BB", 700000..=749999, dec!(0.112)),
("BBB", 750000, dec!(0.120)), ("BBB", 750000..=799998, dec!(0.120)),
("BBB", 799999, dec!(0.128)), ("BBB", 799999..=799999, dec!(0.128)),
("A", 800000, dec!(0.136)), ("A", 800000..=899999, dec!(0.136)),
("AA", 900000, dec!(0.152)), ("AA", 900000..=939999, dec!(0.152)),
("AAA", 940000, dec!(0.168)), ("AAA", 940000..=969998, dec!(0.168)),
("AAA", 969999, dec!(0.176)), ("AAA", 969999..=969999, dec!(0.176)),
("S", 970000, dec!(0.200)), ("S", 970000..=979999, dec!(0.200)),
("S+", 980000, dec!(0.203)), ("S+", 980000..=989998, dec!(0.203)),
("S+", 989999, dec!(0.206)), ("S+", 989999..=989999, dec!(0.206)),
("SS", 990000, dec!(0.208)), ("SS", 990000..=994999, dec!(0.208)),
("SS+", 995000, dec!(0.211)), ("SS+", 995000..=999998, dec!(0.211)),
("SS+", 999999, dec!(0.214)), ("SS+", 999999..=999999, dec!(0.214)),
("SSS", 1000000, dec!(0.216)), ("SSS", 1000000..=1004998, dec!(0.216)),
("SSS", 1004999, dec!(0.222)), ("SSS", 1004999..=1004999, dec!(0.222)),
("SSS+", 1005000, dec!(0.224)), ("SSS+", 1005000..=1005000, dec!(0.224)),
]; ];
#[cfg(test)] #[cfg(test)]