Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Snowiiii/Pumpkin
Browse files Browse the repository at this point in the history
  • Loading branch information
Snowiiii committed Sep 1, 2024
2 parents 1f4fe2a + 0e1f8b1 commit 66b8644
Show file tree
Hide file tree
Showing 14 changed files with 442 additions and 50 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ tokio = { version = "1.39.2", features = ["net", "macros", "rt-multi-thread", "f
rayon = "1.10.0"
uuid = { version = "1.10.0", features = ["serde", "v3"] }
derive_more = { version = "1.0.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
2 changes: 1 addition & 1 deletion pumpkin-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version.workspace = true
edition.workspace = true

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde.workspace = true
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
uuid.workspace = true
colored = "2"
Expand Down
326 changes: 326 additions & 0 deletions pumpkin-core/src/random/legacy_rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
use super::{
gaussian::GaussianGenerator, hash_block_pos, java_string_hash, Random, RandomSplitter,
};

struct LegacyRand {
seed: u64,
internal_next_gaussian: f64,
internal_has_next_gaussian: bool,
}

impl LegacyRand {
fn next_random(&mut self) -> u64 {
let l = self.seed;
let m = l.wrapping_mul(0x5DEECE66D).wrapping_add(11) & 0xFFFFFFFFFFFF;
self.seed = m;
m
}
}

impl GaussianGenerator for LegacyRand {
fn has_next_gaussian(&self) -> bool {
self.internal_has_next_gaussian
}

fn stored_next_gaussian(&self) -> f64 {
self.internal_next_gaussian
}

fn set_has_next_gaussian(&mut self, value: bool) {
self.internal_has_next_gaussian = value;
}

fn set_stored_next_gaussian(&mut self, value: f64) {
self.internal_next_gaussian = value;
}
}

impl Random for LegacyRand {
fn from_seed(seed: u64) -> Self {
LegacyRand {
seed: (seed ^ 0x5DEECE66D) & 0xFFFFFFFFFFFF,
internal_has_next_gaussian: false,
internal_next_gaussian: 0f64,
}
}

fn next(&mut self, bits: u64) -> u64 {
self.next_random() >> (48 - bits)
}

fn split(&mut self) -> Self {
LegacyRand::from_seed(self.next_i64() as u64)
}

fn next_i32(&mut self) -> i32 {
self.next(32) as i32
}

fn next_i64(&mut self) -> i64 {
let i = self.next_i32();
let j = self.next_i32();
((i as i64) << 32).wrapping_add(j as i64)
}

fn next_f32(&mut self) -> f32 {
self.next(24) as f32 * 5.9604645E-8f32
}

fn next_f64(&mut self) -> f64 {
let i = self.next(26);
let j = self.next(27);
let l = (i << 27).wrapping_add(j);
l as f64 * 1.110223E-16f32 as f64
}

fn next_bool(&mut self) -> bool {
self.next(1) != 0
}

fn next_splitter(&mut self) -> impl RandomSplitter {
LegacySplitter::new(self.next_i64() as u64)
}

fn next_gaussian(&mut self) -> f64 {
self.calculate_gaussian()
}

fn next_bounded_i32(&mut self, bound: i32) -> i32 {
if bound & (bound - 1) == 0 {
(bound as u64).wrapping_mul(self.next(31) >> 31) as i32
} else {
loop {
let i = self.next(31) as i32;
let j = i % bound;
if (i - j + (bound - 1)) > 0 {
return j;
}
}
}
}
}

struct LegacySplitter {
seed: u64,
}

impl LegacySplitter {
fn new(seed: u64) -> Self {
LegacySplitter { seed }
}
}

impl RandomSplitter for LegacySplitter {
fn split_u64(&self, seed: u64) -> impl Random {
LegacyRand::from_seed(seed)
}

fn split_string(&self, seed: &str) -> impl Random {
let string_hash = java_string_hash(seed);
LegacyRand::from_seed((string_hash as u64) ^ self.seed)
}

fn split_pos(&self, x: i32, y: i32, z: i32) -> impl Random {
let pos_hash = hash_block_pos(x, y, z);
LegacyRand::from_seed((pos_hash as u64) ^ self.seed)
}
}

#[cfg(test)]
mod test {
use crate::random::{Random, RandomSplitter};

use super::LegacyRand;

#[test]
fn test_next_i32() {
let mut rand = LegacyRand::from_seed(0);

let values = [
-1155484576,
-723955400,
1033096058,
-1690734402,
-1557280266,
1327362106,
-1930858313,
502539523,
-1728529858,
-938301587,
];

for value in values {
assert_eq!(rand.next_i32(), value);
}
}

#[test]
fn test_next_bounded_i32() {
let mut rand = LegacyRand::from_seed(0);

let values = [0, 13, 4, 2, 5, 8, 11, 6, 9, 14];

for value in values {
assert_eq!(rand.next_bounded_i32(0xf), value);
}
}

#[test]
fn test_next_inbetween_i32() {
let mut rand = LegacyRand::from_seed(0);

let values = [1, 5, 2, 12, 12, 6, 12, 10, 4, 3];

for value in values {
assert_eq!(rand.next_inbetween_i32(1, 12), value);
}
}

#[test]
fn test_next_inbetween_exclusive_i32() {
let mut rand = LegacyRand::from_seed(0);

let values = [1, 7, 9, 6, 7, 3, 3, 7, 3, 1];

for value in values {
assert_eq!(rand.next_inbetween_i32_exclusive(1, 12), value);
}
}

#[test]
fn test_next_f64() {
let mut rand = LegacyRand::from_seed(0);

let values = [
0.730967787376657,
0.24053641567148587,
0.6374174253501083,
0.5504370051176339,
0.5975452777972018,
0.3332183994766498,
0.3851891847407185,
0.984841540199809,
0.8791825178724801,
0.9412491794821144,
];

for value in values {
assert_eq!(rand.next_f64(), value);
}
}

#[test]
fn test_next_f32() {
let mut rand = LegacyRand::from_seed(0);

let values: [f32; 10] = [
0.73096776, 0.831441, 0.24053639, 0.6063452, 0.6374174, 0.30905056, 0.550437,
0.1170066, 0.59754527, 0.7815346,
];

for value in values {
assert_eq!(rand.next_f32(), value);
}
}

#[test]
fn test_next_i64() {
let mut rand = LegacyRand::from_seed(0);

let values: [i64; 10] = [
-4962768465676381896,
4437113781045784766,
-6688467811848818630,
-8292973307042192125,
-7423979211207825555,
6146794652083548235,
7105486291024734541,
-279624296851435688,
-2228689144322150137,
-1083761183081836303,
];

for value in values {
assert_eq!(rand.next_i64(), value);
}
}

#[test]
fn test_next_bool() {
let mut rand = LegacyRand::from_seed(0);

let values = [
true, true, false, true, true, false, true, false, true, true,
];

for value in values {
assert_eq!(rand.next_bool(), value);
}
}

#[test]
fn test_next_gaussian() {
let mut rand = LegacyRand::from_seed(0);

let values = [
0.8025330637390305,
-0.9015460884175122,
2.080920790428163,
0.7637707684364894,
0.9845745328825128,
-1.6834122587673428,
-0.027290262907887285,
0.11524570286202315,
-0.39016704137993774,
-0.643388813126449,
];

for value in values {
assert_eq!(rand.next_gaussian(), value);
}
}

#[test]
fn test_next_triangular() {
let mut rand = LegacyRand::from_seed(0);

let values = [
124.52156858525856,
104.34902101162372,
113.2163439160276,
70.01738222704547,
96.89666691951828,
107.30284075808541,
106.16817675813144,
79.11264482608078,
73.96721613927062,
81.72419521080646,
];

for value in values {
assert_eq!(rand.next_triangular(100f64, 50f64), value);
}
}

#[test]
fn test_split() {
let mut original_rand = LegacyRand::from_seed(0);
let mut new_rand = original_rand.split();

{
let splitter = new_rand.next_splitter();

let mut rand1 = splitter.split_string("TEST STRING");
assert_eq!(rand1.next_i32(), -1170413697);

let mut rand2 = splitter.split_u64(10);
assert_eq!(rand2.next_i32(), -1157793070);

let mut rand3 = splitter.split_pos(1, 11, -111);
assert_eq!(rand3.next_i32(), -1213890343);
}

assert_eq!(original_rand.next_i32(), 1033096058);
assert_eq!(new_rand.next_i32(), -888301832);
}
}
Loading

0 comments on commit 66b8644

Please sign in to comment.