#[derive(Clone, Debug)]
pub struct Rng {
state: u64,
}
impl Rng {
pub fn new(seed: u64) -> Rng {
Rng { state: seed }
}
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)
}
pub fn below(&mut self, n: u64) -> u64 {
self.next_u64() % n
}
pub fn u8(&mut self) -> u8 {
(self.next_u64() & 0xFF) as u8
}
pub fn bool(&mut self) -> bool {
self.next_u64() & 1 == 1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deterministic() {
let mut a = Rng::new(42);
let mut b = Rng::new(42);
for _ in 0..100 {
assert_eq!(a.next_u64(), b.next_u64());
}
}
#[test]
fn below_in_range() {
let mut r = Rng::new(7);
for _ in 0..1000 {
assert!(r.below(5) < 5);
}
}
}