rl_lang/interpreter/stdlib/random/
xoshiro.rs1pub struct Xoshiro256 {
8 state: [u64; 4],
10}
11
12impl Default for Xoshiro256 {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl Xoshiro256 {
19 fn new() -> Self {
20 let seed = std::time::SystemTime::now()
21 .duration_since(std::time::UNIX_EPOCH)
22 .map(|d| d.as_nanos() as u64)
23 .unwrap_or(12345);
24
25 let mut state = [0u64; 4];
27 let mut x = seed;
28 for i in &mut state {
29 x = x.wrapping_add(0x9e3779b97f4a7c15);
31 x = (x ^ (x >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
33 x = (x ^ (x >> 27)).wrapping_mul(0x94d049bb133111eb);
34 *i = x ^ (x >> 31);
35 }
36
37 Self { state }
38 }
39
40 fn next(&mut self) -> u64 {
42 let result = (self.state[0].wrapping_add(self.state[3]))
44 .rotate_left(23)
45 .wrapping_add(self.state[0]);
46
47 let temp = self.state[1] << 17;
49 self.state[2] ^= self.state[0];
50 self.state[3] ^= self.state[1];
51 self.state[1] ^= self.state[2];
52 self.state[0] ^= self.state[3];
53 self.state[2] ^= temp;
54 self.state[3] = self.state[3].rotate_left(45);
55 result
56 }
57
58 pub fn generate_random_int_range(&mut self, min: i64, max: i64) -> i64 {
60 let range = (max as i128 - min as i128 + 1) as u128;
61 let offset = (self.next() as u128) % range;
62 (min as i128 + offset as i128) as i64
63 }
64
65 pub fn generate_random_float(&mut self) -> f64 {
67 self.next() as f64 / u64::MAX as f64
68 }
69
70 pub fn generate_random_float_range(&mut self, min: f64, max: f64) -> f64 {
72 min + self.generate_random_float() * (max - min)
73 }
74
75 pub fn generate_random_bool(&mut self, weight: f64) -> bool {
77 self.generate_random_float() < weight.clamp(0.0, 1.0)
78 }
79}