1use rand::{Rng as RandRng, SeedableRng};
4use rand_chacha::ChaCha8Rng;
5
6#[derive(Debug, Clone)]
11pub struct Rng {
12 inner: ChaCha8Rng,
13}
14
15impl Rng {
16 pub fn new(seed: u64) -> Self {
18 Self {
19 inner: ChaCha8Rng::seed_from_u64(seed),
20 }
21 }
22
23 pub fn range(&mut self, min: i32, max: i32) -> i32 {
25 self.inner.gen_range(min..max)
26 }
27
28 pub fn range_usize(&mut self, min: usize, max: usize) -> usize {
30 self.inner.gen_range(min..max)
31 }
32
33 pub fn random(&mut self) -> f64 {
35 self.inner.gen()
36 }
37
38 pub fn next_u64(&mut self) -> u64 {
40 self.inner.gen()
41 }
42
43 pub fn chance(&mut self, probability: f64) -> bool {
45 self.random() < probability
46 }
47
48 pub fn pick<'a, T>(&mut self, slice: &'a [T]) -> Option<&'a T> {
50 if slice.is_empty() {
51 None
52 } else {
53 Some(&slice[self.range_usize(0, slice.len())])
54 }
55 }
56
57 pub fn shuffle<T>(&mut self, slice: &mut [T]) {
59 for i in (1..slice.len()).rev() {
60 let j = self.range_usize(0, i + 1);
61 slice.swap(i, j);
62 }
63 }
64}