Skip to main content

terrain_forge/
rng.rs

1//! Seeded random number generator for deterministic generation
2
3use rand::{Rng as RandRng, SeedableRng};
4use rand_chacha::ChaCha8Rng;
5
6/// Seeded RNG wrapper for deterministic generation
7pub struct Rng {
8    inner: ChaCha8Rng,
9}
10
11impl Rng {
12    pub fn new(seed: u64) -> Self {
13        Self {
14            inner: ChaCha8Rng::seed_from_u64(seed),
15        }
16    }
17
18    pub fn range(&mut self, min: i32, max: i32) -> i32 {
19        self.inner.gen_range(min..max)
20    }
21
22    pub fn range_usize(&mut self, min: usize, max: usize) -> usize {
23        self.inner.gen_range(min..max)
24    }
25
26    pub fn random(&mut self) -> f64 {
27        self.inner.gen()
28    }
29
30    pub fn next_u64(&mut self) -> u64 {
31        self.inner.gen()
32    }
33
34    pub fn chance(&mut self, probability: f64) -> bool {
35        self.random() < probability
36    }
37
38    pub fn pick<'a, T>(&mut self, slice: &'a [T]) -> Option<&'a T> {
39        if slice.is_empty() {
40            None
41        } else {
42            Some(&slice[self.range_usize(0, slice.len())])
43        }
44    }
45
46    pub fn shuffle<T>(&mut self, slice: &mut [T]) {
47        for i in (1..slice.len()).rev() {
48            let j = self.range_usize(0, i + 1);
49            slice.swap(i, j);
50        }
51    }
52}