mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-25 23:12:56 +00:00
improved and fixed rng
This commit is contained in:
parent
57176d5d0e
commit
11a8cb9e83
42
src/rng.rs
42
src/rng.rs
|
@ -1,23 +1,51 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
pub struct RNG(Cell<i32>);
|
||||
pub struct RNG(Cell<(u64, u64, u64, u64)>);
|
||||
|
||||
fn rol64(x: u64, shift: u64) -> u64
|
||||
{
|
||||
if shift == 0 || shift == 64 {
|
||||
x
|
||||
} else {
|
||||
(x << shift) | (x >> (64 - shift))
|
||||
}
|
||||
}
|
||||
|
||||
impl RNG {
|
||||
pub fn new(seed: i32) -> Self {
|
||||
Self(Cell::new(seed))
|
||||
Self(Cell::new((seed as u64,
|
||||
(seed as u64).wrapping_add(0x9e3779b97f4a7c15),
|
||||
(seed as u64).wrapping_add(0xbdd3944475a73cf0),
|
||||
0
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn next_u64(&self) -> i32 {
|
||||
let mut state = self.0.get();
|
||||
let result = rol64(state.1.wrapping_mul(5), 7).wrapping_mul(9);
|
||||
let t = state.1 << 17;
|
||||
|
||||
state.2 ^= state.0;
|
||||
state.3 ^= state.1;
|
||||
state.1 ^= state.2;
|
||||
state.0 ^= state.3;
|
||||
|
||||
state.2 ^= t;
|
||||
state.3 = rol64(state.3, 45);
|
||||
|
||||
self.0.replace(state);
|
||||
result as i32
|
||||
}
|
||||
|
||||
pub fn next(&self) -> i32 {
|
||||
// MSVC LCG values
|
||||
self.0.replace(self.0.get().wrapping_mul(214013).wrapping_add(2531011));
|
||||
self.0.get()
|
||||
self.next_u64() as i32
|
||||
}
|
||||
|
||||
pub fn next_u32(&self) -> u32 {
|
||||
self.next() as u32
|
||||
self.next_u64() as u32
|
||||
}
|
||||
|
||||
pub fn range(&self, range: std::ops::Range<i32>) -> i32 {
|
||||
range.start.wrapping_add(self.next() % (range.end.wrapping_sub(range.start).wrapping_add(1)))
|
||||
range.start.wrapping_add((self.next_u32() >> 2) as i32 % (range.end.wrapping_sub(range.start).wrapping_add(1)))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue