Files
GameStarter/src/js/net/minecraft/util/Random.js
T
2022-05-12 05:23:03 +02:00

83 lines
2.2 KiB
JavaScript

import Long from "../../../../../libraries/long.js";
export default class Random {
static instances = 0;
constructor(seed = Date.now() % 1000000000 ^ Random.instances++ * 1000) {
this.multiplier = Long.fromString("25214903917");
this.mask = Long.fromInt(1).shiftLeft(48).subtract(1);
this.addend = Long.fromInt(0xB);
this.doubleUnit = 1.1102230246251565E-16;
this.maxInt = Long.fromInt(0x7fffffff);
this.intMask = Long.fromInt(0x80000000);
this.setSeed(seed);
}
nextFloat() {
return this.next(24).toNumber() / (1 << 24);
}
nextDouble() {
return this.next(26).shiftLeft(27).add(this.next(27)).toNumber() * this.doubleUnit;
}
nextInt(max = -1) {
if (max === -1) {
return this.next(32).toNumber();
}
let r = this.next(31);
let m = max - 1;
if ((max & m) === 0) // i.e., bound is a power of 2
r = Long.fromInt(max).multiply(r).shiftRightUnsigned(31).toNumber();
else {
r = r.toNumber();
for (let u = r;
u - (r = u % max) + m < 0;
u = this.next(31).toNumber())
;
}
return r;
}
nextLong() {
return this.next(32).shiftLeft(32).add(this.next(32));
}
next(bits) {
let oldSeed;
let nextSeed;
do {
oldSeed = this.seed;
nextSeed = oldSeed.multiply(this.multiplier).add(this.addend).and(this.mask);
} while (!this._compareAndSet(oldSeed, nextSeed));
let num = nextSeed.shiftRight(48 - bits);
return num.greaterThan(this.maxInt) ? num.or(this.intMask) : num; // Cast to integer
}
_compareAndSet(expect, update) {
if (!this.seed.equals(expect)) {
return false;
}
this.seed = update;
return true;
}
setSeed(n) {
let long;
if (typeof n === "number") {
long = Long.fromInt(n);
} else if (n instanceof Long) {
long = n;
} else {
long = Long.fromString(n);
}
this.seed = long.xor(this.multiplier).and(this.mask);
}
}