quaver_rs/difficulty_processor/
helpers.rs

1use crate::rulesets::structs::{Hand, FingerState};
2use crate::enums::{GameMode, ModIdentifier};
3
4/// Helper functions for difficulty calculation
5
6/// Assumes that the assigned hand will be the one to press that key
7pub fn lane_to_hand(lane: i32, key_count: i32) -> Result<Hand, String> {
8    if lane < 1 || lane > key_count {
9        return Err(format!("Lane must be between 1 and keyCount, got {}", lane));
10    }
11
12    let half = key_count / 2;
13
14    if key_count % 2 == 0 {
15        if lane <= half {
16            Ok(Hand::Left)
17        } else {
18            Ok(Hand::Right)
19        }
20    } else {
21        if lane <= half {
22            Ok(Hand::Left)
23        } else if lane == half + 1 {
24            Ok(Hand::Ambiguous)
25        } else {
26            Ok(Hand::Right)
27        }
28    }
29}
30
31/// Assumes that the assigned finger will be the one to press that key.
32pub fn lane_to_finger(lane: i32, key_count: i32) -> Result<FingerState, String> {
33    if lane < 1 || lane > key_count {
34        return Err(format!("Lane must be between 1 and keyCount, got {}", lane));
35    }
36
37    let half = key_count / 2;
38
39    if key_count <= 9 {
40        // even key count
41        if key_count % 2 == 0 {
42            if lane <= half {
43                Ok(FingerState::from_bits(1 << (half - lane)).unwrap_or(FingerState::NONE))
44            } else {
45                Ok(FingerState::from_bits(1 << (lane - (half + 1))).unwrap_or(FingerState::NONE))
46            }
47        } else {
48            // odd key count
49            if lane <= half {
50                Ok(FingerState::from_bits(1 << (half - lane)).unwrap_or(FingerState::NONE))
51            } else if lane == half + 1 {
52                Ok(FingerState::THUMB)
53            } else {
54                Ok(FingerState::from_bits(1 << (lane - (half + 2))).unwrap_or(FingerState::NONE))
55            }
56        }
57    } else if key_count == 10 {
58        if lane <= half - 1 {
59            Ok(FingerState::from_bits(1 << (half - 1 - lane)).unwrap_or(FingerState::NONE))
60        } else if lane == half || lane == half + 1 {
61            Ok(FingerState::THUMB)
62        } else {
63            Ok(FingerState::from_bits(1 << (lane - (half + 2))).unwrap_or(FingerState::NONE))
64        }
65    } else {
66        Err(format!("Key count must be between 1 and 10, got {}", key_count))
67    }
68}
69
70/// Get rate from mods
71pub fn get_rate_from_mods(mods: ModIdentifier) -> f32 {
72    mods.get_rate_from_mods()
73}
74
75/// Convert mode to key count
76pub fn mode_to_key_count(mode: GameMode) -> i32 {
77    mode.to_key_count(false) // Default to no scratch
78}
79
80/// Get key count from map (placeholder implementation)
81pub fn get_key_count(_has_scratch_key: bool) -> i32 {
82    // TODO: Implement proper key count calculation
83    4
84}