Fixed issues with inconsistent PRNG mechanics

This commit is contained in:
Bram van der Veen 2016-09-18 15:44:47 +02:00
parent 290a6ee2c6
commit 9a666ee4da
4 changed files with 53 additions and 25 deletions

View file

@ -12,17 +12,34 @@ function generate(seed, amount) {
if (!amount) amount = 1000; if (!amount) amount = 1000;
if (!seed) seed = 1234; if (!seed) seed = 1234;
var spiral_arms = 2, spiral_angle_degrees = 360, min_radius = 0.05, max_radius = 0.9, thickness = 0.1, scatter_theta = Math.PI / spiral_arms * 0.2, scatter_radius = min_radius * 0.4, spiral_b = spiral_angle_degrees / Math.PI * min_radius / max_radius, start = (new Date()).getTime(), names = [], rejects = { var spiral_arms = 2,
badwords: 0, spiral_angle_degrees = 360,
duplicates: 0 min_radius = 0.05,
}, totalCount = amount, i, position; max_radius = 0.9,
thickness = 0.1,
scatter_theta = Math.PI / spiral_arms * 0.2,
scatter_radius = min_radius * 0.4,
spiral_b = spiral_angle_degrees / Math.PI * min_radius / max_radius,
pseudoRandom = new PRNG(seed); start = (new Date()).getTime(),
names = [],
rejects = {
badwords: 0,
duplicates: 0
},
totalCount = amount,
i,
position,
lastSeed;
prng = new PRNG(seed);
for (i = 0; i < totalCount; i++) { for (i = 0; i < totalCount; i++) {
var number_of_syllables = Math.floor(pseudoRandom.value() * 2 + 2), new_name; var number_of_syllables = Math.floor(prng.value() * 2 + 2), new_name;
while (true) { while (true) {
new_name = utils.random_name(pseudoRandom, number_of_syllables); new_name = utils.random_name(prng, number_of_syllables);
if (names.indexOf(new_name) >= 0) { if (names.indexOf(new_name) >= 0) {
rejects.duplicates++; rejects.duplicates++;
} else if (data.badwords.indexOf(new_name) >= 0 || data.badwords.indexContains(new_name) >= 0) { } else if (data.badwords.indexOf(new_name) >= 0 || data.badwords.indexContains(new_name) >= 0) {
@ -32,17 +49,21 @@ function generate(seed, amount) {
} }
} }
names.push(new_name); names.push(new_name);
var r = pseudoRandom.realRange(min_radius, max_radius); var r = prng.realRange(min_radius, max_radius);
var theta = spiral_b * Math.log(r / max_radius) + pseudoRandom.gaussrandom(scatter_theta); var theta = spiral_b * Math.log(r / max_radius) + prng.gaussrandom(scatter_theta);
r += pseudoRandom.gaussrandom(scatter_radius); r += prng.gaussrandom(scatter_radius);
// assign to a spiral arm // assign to a spiral arm
theta += pseudoRandom.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms; theta += prng.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms;
position = { position = {
x: (Math.cos(theta) * r) * 100, x: (Math.cos(theta) * r) * 100,
y: (Math.sin(theta) * r) * 100, y: (Math.sin(theta) * r) * 100,
z: pseudoRandom.gaussrandom(thickness * 0.5) * 100 z: prng.gaussrandom(thickness * 0.5) * 100
}; };
stars.push(new Star(new_name,pseudoRandom.range(1, 100000),position));
//FIXME: For some fucking reason the code only works if I call a prng value right here.
prng.value()
stars.push(new Star(new_name, Math.floor(prng.value() * 100000), position));
} }
return stars; return stars;

View file

@ -2,7 +2,7 @@ const PRNG = require('./prng');
const utils = require('./utils'); const utils = require('./utils');
function Planet(name, seed, orbitalRadius, insolation, hasStation) { function Planet(name, seed, orbitalRadius, insolation, hasStation) {
var pseudoRandom = new PRNG(this.seed), var pseudoRandom = new PRNG(seed),
template = pseudoRandom.pick(planetTypes, [insolation * 100, 10, 1]); template = pseudoRandom.pick(planetTypes, [insolation * 100, 10, 1]);
this.name = name; this.name = name;
@ -31,8 +31,8 @@ function Planet(name, seed, orbitalRadius, insolation, hasStation) {
Planet.prototype.generateStation = function (prng) { Planet.prototype.generateStation = function (prng) {
return { return {
size: prng.pick(['mini', 'small', 'medium', 'big'], [30, 40, 20, 10]), size: prng.pick(['small', 'big', 'epic'], [498, 499, 8]),
economy: prng.pick(['mining', 'agricultural', 'military', 'tech', 'industrial', 'residential'], [15, 30, 10, 15, 10, 30]) economy: prng.pick(['mining', 'agricultural', 'tech', 'industrial', 'residential'], [15, 30, 15, 10, 30])
} }
} }

View file

@ -2,11 +2,14 @@ const MersenneTwister = require('./twister');
function PRNG(seed) { function PRNG(seed) {
this.mt = new MersenneTwister(seed); this.mt = new MersenneTwister(seed);
this.seed = seed;
return this; return this;
}; };
PRNG.prototype.seed = 0;
PRNG.prototype.value = function() { PRNG.prototype.value = function() {
return this.mt.random(); return this.mt.random()
}; };
PRNG.prototype.range = function(min, max) { PRNG.prototype.range = function(min, max) {
@ -61,8 +64,9 @@ PRNG.prototype.pick = function(a, weights) {
} }
} }
} else { } else {
idx = this.range(0, a.length - 1); idx = this.range(0, a.length - 1);
} }
return a[idx]; return a[idx];
}; };

17
star.js
View file

@ -4,19 +4,22 @@ const utils = require('./utils');
const data = require('./data.json'); const data = require('./data.json');
function Star(name, seed, position) { function Star(name, seed, position) {
var pseudoRandom = new PRNG(this.seed), var pseudoRandom = new PRNG(seed),
spectralClass = pseudoRandom.pick(["O", "B", "A", "F", "G", "K", "M"], [0.0001, 0.2, 1, 3, 8, 12, 20]), spectralClass = pseudoRandom.pick(["black hole", "O", "B", "A", "F", "G", "K", "M"], [.5, 0.0001, 0.2, 1, 3, 8, 12, 20]),
spectralIndex = pseudoRandom.range(0, 9), spectralIndex = pseudoRandom.range(0, 9),
stellarTemplate = data.starTypes[spectralClass]; stellarTemplate = data.starTypes[spectralClass];
this.name = name; this.name = name;
this.seed = seed; this.seed = seed;
this.position = position; this.position = position;
this.spectralType = spectralClass + spectralIndex; if (spectralClass != 'black hole')
this.spectralType = spectralClass + spectralIndex;
else
this.spectralType = spectralClass;
this.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)) * 50; this.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)) * 50;
this.radius = Math.sqrt(this.luminosity); this.radius = Math.sqrt(this.luminosity);
this.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]); this.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]);
this.numberOfStations = pseudoRandom.range(0, this.numberOfPlanets / 8); this.numberOfStations = pseudoRandom.range(0, this.numberOfPlanets / 20);
this.planetSeed = pseudoRandom.range(0, 1000000); this.planetSeed = pseudoRandom.range(0, 1000000);
this.color = stellarTemplate.color; this.color = stellarTemplate.color;
this.planets = this.generatePlanets(); this.planets = this.generatePlanets();
@ -37,15 +40,15 @@ Star.prototype.generatePlanets = function () {
planets.push(new Planet(utils.kappatalize(this.name) + "-" + utils.romanNumeral(i + 1), pseudoRandom.range(0, 1000000), r, this.luminosity / Math.pow(r, 2))); planets.push(new Planet(utils.kappatalize(this.name) + "-" + utils.romanNumeral(i + 1), pseudoRandom.range(0, 1000000), r, this.luminosity / Math.pow(r, 2)));
} }
this.divideStations(planets); this.divideStations(planets, this.seed);
return planets; return planets;
} }
Star.prototype.divideStations = function (planets) { Star.prototype.divideStations = function (planets, seed) {
var stations = this.numberOfStations || 0; var stations = this.numberOfStations || 0;
var i = planets.length - 1; var i = planets.length - 1;
var pseudoRandom = new PRNG(this.seed); var pseudoRandom = new PRNG(seed);
for (i = 0; i < stations; i++) { for (i = 0; i < stations; i++) {
var arr = [] var arr = []