1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const LCG_MULT: i64 = 6364136223846793005;
const LCG_ADD: i64 = 1442695040888963407;
#[inline(always)]
fn twist(seed: i64) -> i64 {
seed.wrapping_mul(seed.wrapping_mul(LCG_MULT).wrapping_add(LCG_ADD))
}
#[derive(Clone)]
pub struct LayerLCG {
base_seed: i64,
world_seed: i64,
pos_seed: i64,
}
impl LayerLCG {
pub fn new(base_seed: i64, world_seed: i64) -> LayerLCG {
let mut lcg = LayerLCG {
base_seed: base_seed,
world_seed: base_seed,
pos_seed: 0,
};
lcg.seed_world(world_seed);
lcg
}
pub fn seed_world(&mut self, world_seed: i64) {
self.world_seed = twist(world_seed);
self.world_seed = self.world_seed.wrapping_add(self.base_seed);
self.world_seed = twist(self.world_seed);
self.world_seed = self.world_seed.wrapping_add(self.base_seed);
self.world_seed = twist(self.world_seed);
self.world_seed = self.world_seed.wrapping_add(self.base_seed);
}
pub fn world_seed(&self) -> i64 {
self.world_seed
}
pub fn seed_pos(&mut self, x: i64, z: i64) {
self.pos_seed = twist(self.world_seed);
self.pos_seed = self.pos_seed.wrapping_add(x);
self.pos_seed = twist(self.pos_seed);
self.pos_seed = self.pos_seed.wrapping_add(z);
self.pos_seed = twist(self.pos_seed);
self.pos_seed = self.pos_seed.wrapping_add(x);
self.pos_seed = twist(self.pos_seed);
self.pos_seed = self.pos_seed.wrapping_add(z);
}
pub fn next_int(&mut self, max: i32) -> i32 {
let mut number = (self.pos_seed >> 24).wrapping_rem(max as i64) as i32;
if number < 0 { number += max; }
self.pos_seed = twist(self.pos_seed);
self.pos_seed = self.pos_seed.wrapping_add(self.world_seed);
number
}
pub fn random_from_2<T>(&mut self, i1: T, i2: T) -> T {
match self.next_int(2) {
0 => i1,
1 => i2,
_ => unreachable!(),
}
}
pub fn random_from_4<T>(&mut self, i1: T, i2: T, i3: T, i4: T) -> T {
match self.next_int(4) {
0 => i1,
1 => i2,
2 => i3,
3 => i4,
_ => unreachable!(),
}
}
}