use rand::distributions::{Distribution, Uniform}; use rand::{rngs::ThreadRng, thread_rng}; // TODO: We'd want move to constant generics here and for DiceThrows, // but that requires new lang features https://github.com/rust-lang/rust/issues/44580 #[derive(Copy, Clone)] pub struct Dice { pub sides: u8, } impl Dice { pub fn new(sides: u8) -> Dice { Dice { sides } } pub fn throw_multiple(&self, amount: u8) -> Vec { let mut results = Vec::new(); for _ in 0..amount { results.push(self.throw()); } results } pub fn throw(&self) -> DiceThrow { self.throw_with_result(Uniform::from(1..self.sides).sample::(&mut thread_rng())) } pub fn throw_with_result(&self, result: u8) -> DiceThrow { DiceThrow { sides: self.sides, throw: result, } } } #[derive(Copy, Clone)] pub struct DiceThrow { pub sides: u8, pub throw: u8, } #[cfg(test)] mod tests { use super::Dice; #[test] fn create_dice() { assert_eq!(Dice::new(20).sides, 20) } #[test] fn throw_dice() { let throw = Dice::new(20).throw(); assert!(throw.throw < 21); assert!(throw.throw > 0); } #[test] fn throw_dice_with_result() { let throw = Dice::new(20).throw_with_result(15); assert_eq!(throw.throw, 15); } }