PkmnLib_rs/src/static_data/growth_rates.rs

65 lines
2.1 KiB
Rust
Executable File

use crate::defines::LevelInt;
use crate::VecExt;
use anyhow::Result;
use anyhow_ext::ensure;
/// A growth rate defines how much experience is required per level.
pub trait GrowthRate {
/// Calculate the level something with this growth rate would have at a certain experience.
fn calculate_level(&self, experience: u32) -> LevelInt;
/// Calculate the experience something with this growth rate would have at a certain level.
fn calculate_experience(&self, level: LevelInt) -> Result<u32>;
}
/// An implementation of the growth rate that uses a lookup table for experience.
pub struct LookupGrowthRate {
/// The lookup Vec.
experience: Vec<u32>,
}
impl LookupGrowthRate {
/// Instantiates a new lookup growth rate. The experience vec should be the amount of experience
/// required per level, with the first element being the experience required for level 1 (generally 0).
pub fn new(experience: Vec<u32>) -> LookupGrowthRate {
LookupGrowthRate { experience }
}
}
impl GrowthRate for LookupGrowthRate {
fn calculate_level(&self, experience: u32) -> LevelInt {
for (i, v) in self.experience.iter().enumerate() {
if *v > experience {
return i as LevelInt;
}
}
self.experience.len() as LevelInt
}
fn calculate_experience(&self, level: LevelInt) -> Result<u32> {
ensure!(level > 0, "Level must be greater than 0, but was {}", level);
if level >= self.experience.len() as LevelInt {
match self.experience.last() {
Some(v) => Ok(*v),
None => anyhow::bail!("No experience values found"),
}
} else {
Ok(*self.experience.get_res((level - 1) as usize)?)
}
}
}
#[cfg(test)]
#[allow(clippy::indexing_slicing)]
pub(crate) mod tests {
use super::*;
mockall::mock! {
#[derive(Debug)]
pub GrowthRate {}
impl GrowthRate for GrowthRate {
fn calculate_level(&self, experience: u32) -> LevelInt;
fn calculate_experience(&self, level: LevelInt) -> Result<u32>;
}
}
}