1use rand::seq::SliceRandom;
2use rand::SeedableRng;
3use rand_pcg::Pcg32;
4use std::ops::{Deref, DerefMut};
5
6#[derive(Clone)]
8pub struct Random {
9 rng: Pcg32,
10}
11
12impl Random {
13 pub fn new(seed: u64) -> Self {
14 Self {
15 rng: Pcg32::seed_from_u64(seed),
16 }
17 }
18
19 pub fn reseed(&mut self, seed: u64) {
20 self.rng = Pcg32::seed_from_u64(seed);
21 }
22}
23
24impl Deref for Random {
25 type Target = Pcg32;
26 fn deref(&self) -> &Self::Target {
27 &self.rng
28 }
29}
30
31impl DerefMut for Random {
32 fn deref_mut(&mut self) -> &mut Self::Target {
33 &mut self.rng
34 }
35}
36
37impl Default for Random {
38 fn default() -> Self {
39 Self {
40 rng: Pcg32::from_entropy(),
41 }
42 }
43}
44
45pub struct ShuffleBag<T>
47where
48 T: Sized + Clone,
49{
50 rng: Random,
51 index: usize,
52 items: Vec<T>,
53 bag: Vec<usize>,
54}
55
56impl<T> ShuffleBag<T>
57where
58 T: Sized + Clone,
59{
60 pub fn new(capacity: usize) -> Self {
62 Self::new_with_random(Random::default(), capacity)
63 }
64
65 pub fn new_with_random(rng: Random, capacity: usize) -> Self {
66 Self {
67 rng,
68 index: 0,
69 items: vec![],
70 bag: Vec::with_capacity(capacity),
71 }
72 }
73
74 pub fn add(&mut self, item: T, amount: usize) {
76 self.items.push(item);
77 let index = self.items.len() - 1;
78 self.bag.extend_from_slice(&vec![index; amount]);
79 self.reset();
80 }
81
82 pub fn item(&mut self) -> Option<&T> {
84 if self.items.is_empty() {
85 return None;
86 }
87
88 if self.index >= self.bag.len() {
89 self.reset();
90 }
91
92 let item = &self.items[self.bag[self.index]];
93 self.index += 1;
94 Some(item)
95 }
96
97 pub fn reset(&mut self) {
99 self.bag.shuffle(&mut self.rng.rng);
100 self.index = 0;
101 }
102}