1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
7 use parking_lot::Mutex;
8 use rand::distributions::uniform::SampleUniform;
10 #[derive(Deserialize,Debug,Clone,Default)]
12 pub struct FakeRngSpec(Option<Vec<String>>);
14 #[derive(Serialize,Deserialize,Error,Debug,Clone)]
15 #[error("RNG is real")]
19 pub fn make_game_rng(self) -> RngWrap { RngWrap( match self.0 {
21 Some(ents) => Some(Mutex::new(FakeRng {
30 Option<Mutex<FakeRng>>
40 pub fn is_fake(&self) -> bool { self.0.is_some() }
43 pub fn set_fake(&self, v: Vec<String>, _: AuthorisationSuperuser) {
44 let mut fake = self.0.as_ref().ok_or(RngIsReal)?.lock();
50 fn next_fake(&self) -> String {
51 let mut fake = self.0.as_ref()?.lock();
52 let e = fake.ents.get(fake.i)?.clone();
54 fake.i %= fake.ents.len();
58 pub fn shuffle<T:Copy>(&self, slice: &mut [T]) { match self.next_fake() {
60 let mut rng = thread_rng();
61 slice.shuffle(&mut rng);
65 let n: usize = s.parse().unwrap_or(0);
66 let front = slice[0..n].to_owned();
67 slice.copy_within(n.., 0);
68 slice[l-n..].copy_from_slice(&front);
72 pub fn range<T>(&self, range: std::ops::Range<T>) -> T
73 where T: SampleUniform + FromStr + Ord + Default
75 match self.next_fake() {
77 let mut rng = thread_rng();
81 let n: T = s.parse().ok()?;
82 range.contains(&n).then(|| n)
83 })().unwrap_or_default(),