nois/
dice.rs

1use crate::int_in_range;
2
3/// Returns a number from 1-6.
4///
5/// # Example
6///
7/// Single dice
8///
9/// ```
10/// use nois::{randomness_from_str, roll_dice};
11///
12/// let randomness = randomness_from_str("9e8e26615f51552aa3b18b6f0bcf0dae5afbe30321e8d7ea7fa51ebeb1d8fe62").unwrap();
13///
14/// let number = roll_dice(randomness);
15/// assert_eq!(number, 2);
16/// ```
17///
18/// Double dice
19///
20/// ```
21/// use nois::{sub_randomness, randomness_from_str, roll_dice};
22///
23/// let randomness = randomness_from_str("e2ee31c20afbb20530f6a18d5d96fb20f766fe11799d3611b04bf9edbd2cffcb").unwrap();
24///
25/// let mut provider = sub_randomness(randomness);
26///
27/// let number1 = roll_dice(provider.provide());
28/// assert_eq!(number1, 3);
29///
30/// let number2 = roll_dice(provider.provide());
31/// assert_eq!(number2, 6);
32/// ```
33pub fn roll_dice(randomness: [u8; 32]) -> u8 {
34    int_in_range(randomness, 1, 6)
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use crate::sub_randomness;
41    use hex_literal::hex;
42    use std::collections::HashMap;
43
44    #[test]
45    fn roll_dice_works() {
46        let randomness: [u8; 32] =
47            hex!("9e8e26615f51552aa3b18b6f0bcf0dae5afbe30321e8d7ea7fa51ebeb1d8fe62");
48        let number = roll_dice(randomness);
49        assert_eq!(number, 2);
50    }
51
52    #[test]
53    fn roll_dice_is_uniformly_distributes() {
54        let randomness: [u8; 32] =
55            hex!("5ec7020fe74dff44d50b255c1a680c362dc83de69bd3c865e0ef5f914bea6f7b");
56        let mut results = HashMap::<u8, usize>::new();
57        for sub_randomness in sub_randomness(randomness).take(600_000) {
58            let number = roll_dice(sub_randomness);
59            let current = results.get(&number).copied().unwrap_or_default();
60            results.insert(number, current + 1);
61        }
62        let ones = results.get(&1).copied().unwrap_or_default();
63        let twos = results.get(&2).copied().unwrap_or_default();
64        let threes = results.get(&3).copied().unwrap_or_default();
65        let fours = results.get(&4).copied().unwrap_or_default();
66        let fives = results.get(&5).copied().unwrap_or_default();
67        let sixes = results.get(&6).copied().unwrap_or_default();
68        // println!("{ones} {twos} {threes} {fours} {fives} {sixes}");
69        assert!(ones > 99_000 && ones < 101_000);
70        assert!(twos > 99_000 && twos < 101_000);
71        assert!(threes > 99_000 && threes < 101_000);
72        assert!(fours > 99_000 && fours < 101_000);
73        assert!(fives > 99_000 && fives < 101_000);
74        assert!(sixes > 99_000 && sixes < 101_000);
75        assert_eq!(results.values().sum::<usize>(), 600_000);
76    }
77}