This repository has been archived on 2024-02-25. You can view files and clone it, but cannot push or open issues or pull requests.
galaxygen/PRNG.js

123 lines
4.6 KiB
JavaScript
Raw Normal View History

const MersenneTwister = require('./MersenneTwister');
const name_parts = {
prefix: ['a', 'aeg', 'ai', 'alf', 'alph', 'amn', 'an', 'and', 'apt', 'arct', 'ard', 'ath', 'aur', 'b', 'bell', 'bet', 'bor', 'c', 'call', 'can', 'canc', 'cap', 'ceph', 'ch', 'chl', 'cr', 'cz', 'delt', 'drac', 'e', 'eps', 'f', 'fom', 'g', 'gamm', 'gall', 'gat', 'gemi', 'gn', 'gr', 'h', 'heph', 'her', 'holl', 'i', 'in', 'ind', 'ir', 'j', 'k', 'kn', 'l', 'lep', 'lin', 'lov', 'm', 'malth', 'mar', 'med', 'mir', 'mirc', 'n', 'nept', 'o', 'or', 'pers', 'p', 'ph', 'plei', 'plut', 'pn', 'poll', 'pr', 'ps', 'pt', 'pyr', 'q', 'qu', 'r', 'rig', 's', 'sag', 'sc', 'sir', 'str', 't', 'taur', 'tell', 'th', 'tn', 'trop', 'ts', 'u', 'ull', 'ult', 'ur', 'v', 'veg', 'vesp', 'vr', 'w', 'wh', 'wr', 'x', 'xz', 'y', 'z', 'z'],
middle: ['acl', 'ac', 'ad', 'aedr', 'agg', 'al', 'alh', 'alr', 'alt', 'am', 'an', 'apr', 'aqu', 'ar', 'ath', 'cul', 'e', 'ec', 'ed', 'ef', 'egg', 'elg', 'em', 'en', 'eph', 'er', 'et', 'i', 'iat', 'ib', 'ic', 'id', 'ig', 'il', 'ir', 'isc', 'ist', 'itt', 'od', 'of', 'om', 'on', 'oph', 'opt', 'orp', 'om', 'oth', 'ue', 'ulp', 'ulph', 'ur', 'und', 'us', 'ut', 'uu'],
suffix: ['a', 'ae', 'ai', 'anae', 'ao', 'ar', 'arn', 'aur', 'aut', 'ea', 'ei', 'el', 'eo', 'eon', 'eos', 'es', 'ga', 'ho', 'holm', 'hus', 'i', 'ia', 'iea', 'ii', 'io', 'ion', 'is', 'las', 'o', 'oe', 'oea', 'oi', 'oia', 'on', 'one', 'or', 'orn', 'os', 'ov', 'ova', 'u', 'ua', 'ue', 'ula', 'uo', 'um', 'un', 'us', 'ux', 'z'],
secondary: ['Major', 'Minor', 'Secundus', 'Tertius', 'Quartus', 'Quintus', 'Septimus', 'Octavus', 'Nonus', 'Decimus']
};
class PRNG {
constructor(seed) {
this.mt = new MersenneTwister(seed);
};
value() {
return this.mt.random();
};
range(min, max) {
return Math.floor(this.value() * (max - min + 1) + min);
};
realRange(min, max, skew_function) {
let v = this.value();
if (typeof skew_function === 'function') {
v = skew_function(v);
}
return v * (max - min) + min;
};
gaussrandom(dev = 1.0) {
let X;
let context = this.gaussrandom.context;
if (!context) {
context = this.gaussrandom.context = {
phase: 0
};
};
if (context.phase === 0) {
do {
context.V1 = this.realRange(-1, 1);
context.V2 = this.realRange(-1, 1);
context.S = context.V1 * context.V1 + context.V2 * context.V2;
}
while (context.S >= 1 || context.S == 0);
X = context.V1 * Math.sqrt(-2 * Math.log(context.S) / context.S);
} else {
X = context.V2 * Math.sqrt(-2 * Math.log(context.S) / context.S);
}
context.phase = 1 - context.phase;
return X * dev;
};
pick(a, weights) {
let s = 0;
let idx;
if (weights !== undefined) {
for (idx = 0; idx < weights.length; idx++) {
s += weights[idx];
}
s = this.value() * s;
for (idx = 0; idx < weights.length; idx++) {
s -= weights[idx];
if (s < 0) {
break;
}
}
} else {
idx = this.range(0, a.length - 1);
}
return a[idx];
};
static random_name(PRNG, number_of_syllables, allow_second_name, allow_secondary) {
let syllables = [];
let name;
let suffix;
syllables.push(PRNG.pick(name_parts.prefix));
for (var j = 2; j < number_of_syllables; j++) {
syllables.push(PRNG.pick(name_parts.middle));
}
syllables.push(PRNG.pick(name_parts.suffix));
name = syllables.join('');
suffix = PRNG.pick(['', 'first-name', 'second-name', 'secondary'], [8, 1, 1, 4]);
switch (suffix) {
case 'first-name':
if (allow_second_name !== false) {
name = this.random_name(PRNG, PRNG.range(2, number_of_syllables), false, false).capitalize() + ' ' + name;
}
break;
case 'second-name':
if (allow_second_name !== false) {
name = name + ' ' + this.random_name(PRNG, PRNG.range(2, number_of_syllables), false).capitalize();
}
break;
case 'secondary':
if (allow_secondary !== false) {
name += ' ' + PRNG.pick(name_parts.secondary);
}
break;
}
return name.capitalize();
};
}
module.exports = PRNG