First one-shot pass
This commit is contained in:
45
src/engine/scoring.rs
Normal file
45
src/engine/scoring.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use crate::session::result::LessonResult;
|
||||
|
||||
pub fn compute_score(result: &LessonResult, complexity: f64) -> f64 {
|
||||
let speed = result.cpm;
|
||||
let errors = result.incorrect as f64;
|
||||
let length = result.total_chars as f64;
|
||||
(speed * complexity) / (errors + 1.0) * (length / 50.0)
|
||||
}
|
||||
|
||||
pub fn compute_complexity(unlocked_count: usize) -> f64 {
|
||||
(unlocked_count as f64 / 26.0).max(0.1)
|
||||
}
|
||||
|
||||
pub fn level_from_score(total_score: f64) -> u32 {
|
||||
let level = (total_score / 100.0).sqrt() as u32;
|
||||
level.max(1)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn score_to_next_level(total_score: f64) -> f64 {
|
||||
let current_level = level_from_score(total_score);
|
||||
let next_level_score = ((current_level + 1) as f64).powi(2) * 100.0;
|
||||
next_level_score - total_score
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_level_starts_at_one() {
|
||||
assert_eq!(level_from_score(0.0), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_level_increases_with_score() {
|
||||
assert!(level_from_score(1000.0) > level_from_score(100.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complexity_scales_with_letters() {
|
||||
assert!(compute_complexity(26) > compute_complexity(6));
|
||||
assert!((compute_complexity(26) - 1.0).abs() < 0.001);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user