//! Repeatable pseudo random numbers (SplitMix64). //! //! The core never uses any other source of randomness. The same seed always //! gives the same sequence, on every machine. /// Pseudo random number generator with 64 bits of state. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Rng { state: u64, } impl Rng { pub fn new(seed: u64) -> Self { Self { state: seed } } /// Returns the next value of the sequence. pub fn next_u64(&mut self) -> u64 { self.state = self.state.wrapping_add(0x9E37_79B9_7F4A_7C15); let mut z = self.state; z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); z ^ (z >> 31) } /// Returns a value in `0..bound`. /// /// # Panics /// Panics if `bound` is zero. pub fn below(&mut self, bound: u32) -> u32 { assert!(bound > 0, "bound must be greater than zero"); ((u128::from(self.next_u64()) * u128::from(bound)) >> 64) as u32 } }