diff options
| author | Freya Murphy <freya@freyacat.org> | 2025-11-18 11:02:14 -0500 |
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2025-11-18 11:02:14 -0500 |
| commit | d9c41b9b6bdbccebe9f14c229dcee40543498d7e (patch) | |
| tree | de47fbc517f60adf32017833bfa252d33fe92da8 /dungeon | |
| parent | dungeon: port rands SmallRng to be reproducible (diff) | |
| download | DungeonCrawl-d9c41b9b6bdbccebe9f14c229dcee40543498d7e.tar.gz DungeonCrawl-d9c41b9b6bdbccebe9f14c229dcee40543498d7e.tar.bz2 DungeonCrawl-d9c41b9b6bdbccebe9f14c229dcee40543498d7e.zip | |
dungeon: switch rng to rand_xoshiro
Diffstat (limited to 'dungeon')
| -rw-r--r-- | dungeon/Cargo.toml | 1 | ||||
| -rw-r--r-- | dungeon/src/rng.rs | 58 |
2 files changed, 12 insertions, 47 deletions
diff --git a/dungeon/Cargo.toml b/dungeon/Cargo.toml index 213fc3b..cef2cf5 100644 --- a/dungeon/Cargo.toml +++ b/dungeon/Cargo.toml @@ -10,6 +10,7 @@ rust-version.workspace = true [dependencies] getrandom.workspace = true rand.workspace = true +rand_xoshiro.workspace = true strum.workspace = true strum_macros.workspace = true diff --git a/dungeon/src/rng.rs b/dungeon/src/rng.rs index bb9151b..ae8cae6 100644 --- a/dungeon/src/rng.rs +++ b/dungeon/src/rng.rs @@ -1,74 +1,38 @@ //! Implements rng using the xoshiro256++ algorithm -use rand::{ - SeedableRng, - rand_core::{RngCore, le}, -}; +use rand::rand_core::{RngCore, SeedableRng}; +use rand_xoshiro::Xoshiro256PlusPlus; /// Deterministic pseudo random number generator. -/// -/// Is is a copy of `SmallRng` from `rand`, but is gurenteed -/// to be reproducible across versions and platforms. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct DungeonRng { - s: [u64; 4], -} +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DungeonRng(Xoshiro256PlusPlus); impl SeedableRng for DungeonRng { // Fix to 256 bits. Changing this is a breaking change! - type Seed = [u8; 32]; + type Seed = <Xoshiro256PlusPlus as SeedableRng>::Seed; #[inline] fn from_seed(seed: Self::Seed) -> Self { - let mut state = [0; 4]; - le::read_u64_into(&seed, &mut state); - Self { s: state } + Self(Xoshiro256PlusPlus::from_seed(seed)) } #[inline] - fn seed_from_u64(mut state: u64) -> Self { - const PHI: u64 = 0x9e3779b97f4a7c15; - let mut s = [0; 4]; - for i in &mut s { - state = state.wrapping_add(PHI); - let mut z = state; - z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9); - z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb); - z = z ^ (z >> 31); - *i = z; - } - Self { s } + fn seed_from_u64(state: u64) -> Self { + Self(Xoshiro256PlusPlus::seed_from_u64(state)) } } impl RngCore for DungeonRng { #[inline] fn next_u32(&mut self) -> u32 { - let val = self.next_u64(); - (val >> 32) as u32 + self.0.next_u32() } #[inline] fn next_u64(&mut self) -> u64 { - let res = self.s[0] - .wrapping_add(self.s[3]) - .rotate_left(23) - .wrapping_add(self.s[0]); - - let t = self.s[1] << 17; - - self.s[2] ^= self.s[0]; - self.s[3] ^= self.s[1]; - self.s[1] ^= self.s[2]; - self.s[0] ^= self.s[3]; - - self.s[2] ^= t; - - self.s[3] = self.s[3].rotate_left(45); - - res + self.0.next_u64() } #[inline] fn fill_bytes(&mut self, dst: &mut [u8]) { - le::fill_bytes_via_next(self, dst); + self.0.fill_bytes(dst); } } |