humphrey_server/server/
rand.rs1use std::time::SystemTime;
4
5#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct Lcg {
8 modulus: usize,
9 multiplier: usize,
10 increment: usize,
11 seed: usize,
12}
13
14pub trait Choose {
16 type Item;
18
19 fn choose(&self, lcg: &mut Lcg) -> Option<&Self::Item>;
21}
22
23impl Lcg {
24 pub fn new() -> Self {
28 Lcg {
29 modulus: 2_usize.pow(31) - 1,
30 multiplier: 1103515245,
31 increment: 12345,
32 seed: SystemTime::now()
33 .duration_since(SystemTime::UNIX_EPOCH)
34 .unwrap()
35 .as_secs() as usize,
36 }
37 }
38
39 #[allow(dead_code)]
41 pub fn with_parameters(
42 modulus: usize,
43 multiplier: usize,
44 increment: usize,
45 seed: usize,
46 ) -> Self {
47 Lcg {
48 modulus,
49 multiplier,
50 increment,
51 seed,
52 }
53 }
54}
55
56impl Default for Lcg {
57 fn default() -> Self {
58 Self::new()
59 }
60}
61
62impl Iterator for Lcg {
63 type Item = u32;
64
65 fn next(&mut self) -> Option<Self::Item> {
66 let value = (self.multiplier * self.seed + self.increment) % self.modulus;
67 self.seed = value;
68
69 Some(value as u32)
70 }
71}
72
73impl<T> Choose for [T] {
74 type Item = T;
75
76 fn choose(&self, lcg: &mut Lcg) -> Option<&Self::Item> {
77 let value = lcg.next().unwrap();
78 self.get((value % self.len() as u32) as usize)
79 }
80}