#[derive(Clone, Debug)]
pub(crate) struct SmallRng {
state: u64,
}
impl SmallRng {
pub(crate) fn new(seed: u64) -> Self {
let state = if seed == 0 {
0x9e37_79b9_7f4a_7c15
} else {
seed
};
Self { state }
}
pub(crate) fn next_u64(&mut self) -> u64 {
let mut x = self.state;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
self.state = x;
x.wrapping_mul(0x2545_f491_4f6c_dd1d)
}
pub(crate) fn f32(&mut self) -> f32 {
let value = self.next_u64() >> 40;
value as f32 / ((1u64 << 24) - 1) as f32
}
pub(crate) fn range_f32(&mut self, min: f32, max: f32) -> f32 {
min + (max - min) * self.f32()
}
pub(crate) fn usize(&mut self, max: usize) -> usize {
if max == 0 {
0
} else {
(self.next_u64() as usize) % max
}
}
pub(crate) fn shuffle<T>(&mut self, values: &mut [T]) {
for i in (1..values.len()).rev() {
let j = self.usize(i + 1);
values.swap(i, j);
}
}
}
pub(crate) fn hash(seed: u64, a: u64, b: u64, c: u64) -> u64 {
let mut x = seed
^ a.wrapping_mul(0x9e37_79b9_7f4a_7c15)
^ b.wrapping_mul(0xbf58_476d_1ce4_e5b9)
^ c.wrapping_mul(0x94d0_49bb_1331_11eb);
x ^= x >> 30;
x = x.wrapping_mul(0xbf58_476d_1ce4_e5b9);
x ^= x >> 27;
x = x.wrapping_mul(0x94d0_49bb_1331_11eb);
x ^ (x >> 31)
}
pub(crate) fn hash_f32(seed: u64, a: u64, b: u64, c: u64) -> f32 {
let value = hash(seed, a, b, c) >> 40;
value as f32 / ((1u64 << 24) - 1) as f32
}