roguelike-pumpkin-patch
Version:
A roguelike development library in JavaScript.
72 lines • 2.89 kB
JavaScript
/** Random generator */
var Random = /** @class */ (function () {
function Random(seed, base) {
if (!seed) {
// Get seed from milliseconds since Jan 1st, 1970
seed = Date.now();
}
this.seed = Math.floor(seed);
this.weyl = 0;
this.x = 0;
this.base = (base) ? base : 100000;
// Run it a couple of times, in case the seed isn't that good.
for (var i = 0; i < 10; i++) {
this.getRandom();
}
}
;
/** Generate a random number from 0 <= number < 1 */
// An attempt to reproduce something resembling the Middle Square Weyl Sequence PRNG
// See Widynski (2017) https://arxiv.org/abs/1704.00358v5
// The above algorithm uses unsigned ints. JS uses signed floats. Further testing required to see whether or not this is actually a problem.
Random.prototype.getRandom = function () {
this.x *= this.x;
this.x += (this.weyl += this.seed);
// Note, >>> makes the shift be unsigned. The >>> 0 at the end flips the "sign" bit to be positive, ensuring a non-negative result.
this.x = ((this.x >>> 32) | (this.x << 32)) >>> 0;
return (this.x % this.base) / this.base;
};
/** Get a random number in a range */
Random.prototype.getNumber = function (min, max, integer) {
if (typeof integer === "undefined") {
if (Number.isInteger(min) && Number.isInteger(max)) {
integer = true;
}
}
if (integer) {
return Math.floor(this.getRandom() * (max + 1 - min)) + Math.ceil(min);
}
else {
return (this.getRandom() * (max - min)) + min;
}
};
/** Get a random element from an array */
Random.prototype.getRandomElement = function (array) {
var randomIndex = this.getNumber(0, array.length - 1, true);
return array[randomIndex];
};
/** Get a random element, with weights */
Random.prototype.getWeightedElement = function (array) {
var totalWeight = 0;
var integer = true;
array.forEach(function (element) {
totalWeight += element.weight;
integer = integer && Number.isInteger(element.weight);
});
var randomNumber = this.getNumber((integer) ? 1 : 0, totalWeight, integer);
// Go through the array until we have a winner
for (var i = 0; i < array.length; i++) {
randomNumber -= array[i].weight;
if (randomNumber <= 0) {
// Found it!
return array[i].option;
}
}
// Not found; seems like a problem
throw new Error("No match found.");
};
return Random;
}());
export { Random };
export default Random;
//# sourceMappingURL=Random.js.map