rosu_pp/mania/
score_state.rs

1/// Aggregation for a score's current state.
2#[derive(Clone, Debug, PartialEq, Eq)]
3pub struct ManiaScoreState {
4    /// Amount of current 320s.
5    pub n320: u32,
6    /// Amount of current 300s.
7    pub n300: u32,
8    /// Amount of current 200s.
9    pub n200: u32,
10    /// Amount of current 100s.
11    pub n100: u32,
12    /// Amount of current 50s.
13    pub n50: u32,
14    /// Amount of current misses.
15    pub misses: u32,
16}
17
18impl ManiaScoreState {
19    /// Create a new empty score state.
20    pub const fn new() -> Self {
21        Self {
22            n320: 0,
23            n300: 0,
24            n200: 0,
25            n100: 0,
26            n50: 0,
27            misses: 0,
28        }
29    }
30
31    /// Return the total amount of hits by adding everything up.
32    pub const fn total_hits(&self) -> u32 {
33        self.n320 + self.n300 + self.n200 + self.n100 + self.n50 + self.misses
34    }
35
36    /// Calculate the accuracy between `0.0` and `1.0` for this state.
37    pub fn accuracy(&self, classic: bool) -> f64 {
38        let total_hits = self.total_hits();
39
40        if total_hits == 0 {
41            return 0.0;
42        }
43
44        let perfect_weight = if classic { 60 } else { 61 };
45
46        let numerator = perfect_weight * self.n320
47            + 60 * self.n300
48            + 40 * self.n200
49            + 20 * self.n100
50            + 10 * self.n50;
51
52        let denominator = perfect_weight * total_hits;
53
54        f64::from(numerator) / f64::from(denominator)
55    }
56}
57
58impl Default for ManiaScoreState {
59    fn default() -> Self {
60        Self::new()
61    }
62}