1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub struct DeterministicRng {
8 state: u64,
9}
10
11impl DeterministicRng {
12 #[must_use]
14 pub const fn new(seed: u64) -> Self {
15 Self {
16 state: seed ^ 0x9E37_79B9_7F4A_7C15,
17 }
18 }
19
20 #[must_use]
22 pub const fn next_u64(&mut self) -> u64 {
23 self.state = self
24 .state
25 .wrapping_mul(6_364_136_223_846_793_005)
26 .wrapping_add(1_442_695_040_888_963_407);
27 self.state
28 }
29
30 #[must_use]
32 pub const fn next_bounded(&mut self, upper_exclusive: u64) -> u64 {
33 if upper_exclusive == 0 {
34 return 0;
35 }
36 self.next_u64() % upper_exclusive
37 }
38
39 #[must_use]
41 pub fn hit_rate_percent(&mut self, percent: u8) -> bool {
42 if percent == 0 {
43 return false;
44 }
45 if percent >= 100 {
46 return true;
47 }
48 self.next_bounded(100) < u64::from(percent)
49 }
50}