diff --git a/01.workspace/oxidice_lib/examples/roll_d20_with_disadvantage.rs b/01.workspace/oxidice_lib/examples/roll_d20_with_disadvantage.rs new file mode 100644 index 0000000..e9047c1 --- /dev/null +++ b/01.workspace/oxidice_lib/examples/roll_d20_with_disadvantage.rs @@ -0,0 +1,7 @@ +use oxidice_lib::dice::*; + +fn main() { + let roll_result = Handful::grab(2, 20).roll(); + let result = roll_result.clone().min().unwrap(); + println!("{} -> {}", roll_result, result); +} diff --git a/01.workspace/oxidice_lib/src/imp/die_roll.rs b/01.workspace/oxidice_lib/src/imp/die_roll.rs index fd85aa7..b0f5dab 100644 --- a/01.workspace/oxidice_lib/src/imp/die_roll.rs +++ b/01.workspace/oxidice_lib/src/imp/die_roll.rs @@ -3,6 +3,6 @@ use crate::*; impl Die { pub fn roll(&self) -> u16 { let mut rng = rand::rng(); - rng.random_range(1..=self.sides) + rng.random_range(1..=self.sides) as u16 } } diff --git a/01.workspace/oxidice_lib/src/imp/mod.rs b/01.workspace/oxidice_lib/src/imp/mod.rs index 99a175a..f603b33 100644 --- a/01.workspace/oxidice_lib/src/imp/mod.rs +++ b/01.workspace/oxidice_lib/src/imp/mod.rs @@ -3,4 +3,5 @@ pub mod die_roll; pub mod handful_grab; pub mod handful_roll; pub mod outcome_max; +pub mod outcome_min; pub mod outcome_sum; diff --git a/01.workspace/oxidice_lib/src/imp/outcome_min.rs b/01.workspace/oxidice_lib/src/imp/outcome_min.rs new file mode 100644 index 0000000..415cb5b --- /dev/null +++ b/01.workspace/oxidice_lib/src/imp/outcome_min.rs @@ -0,0 +1,40 @@ +use crate::*; + +fn min_of(values: Vec) -> Result { + if values.is_empty() { + return Err(FailedTo::ProcessInput); + } + Ok(Outcome::Scalar(u16::MIN)).and_then(|_| { + values + .iter() + .min() + .ok_or(FailedTo::FindMin) + .map(|min| Outcome::Scalar(*min)) + }) +} + +impl Outcome { + pub fn min(self) -> Result { + match self { + Outcome::Scalar(value) => Ok(Outcome::Scalar(value)), + Outcome::List(values) => min_of(values), + } + } +} + +#[cfg(test)] +mod unit_tests { + use super::*; + #[test] + fn check_min() { + let roll_result = Handful::grab(2, 20).roll(); + let min_result = roll_result.clone().min().unwrap(); + match roll_result { + Outcome::List(values) => { + let min = values.iter().min().unwrap(); + assert_eq!(min_result, Outcome::Scalar(*min)); + } + _ => panic!("result is not a list"), + } + } +}