commit 9c8274d22759775a81cb97f784751542dc34eed5 Author: Bram van der Veen <96aa48@gmail.com> Date: Tue Jun 28 16:13:28 2016 +0200 First commit diff --git a/data.json b/data.json new file mode 100644 index 0000000..41545bd --- /dev/null +++ b/data.json @@ -0,0 +1,51 @@ +{ + "starTypes": { + "O": { + "luminosity": 50000, + "color": [192, 128, 255], + "planets": [0, 3] + }, + "B": { + "luminosity": 15000, + "color": [128, 192, 255], + "planets": [1, 5] + }, + "A": { + "luminosity": 25, + "color": [128, 192, 255], + "planets": [1, 7] + }, + "F": { + "luminosity": 2.5, + "color": [220, 255, 192], + "planets": [1, 11] + }, + "G": { + "luminosity": 1, + "color": [255, 192, 64], + "planets": [1, 19] + }, + "K": { + "luminosity": 0.25, + "color": [255, 128, 64], + "planets": [1, 9] + }, + "M": { + "luminosity": 0.05, + "color": [255, 100, 0], + "planets": [1, 5] + }, + "black hole": { + "luminosity": 100000, + "color": [128, 0, 64], + "planets": [0, 0] + } + }, + "nameParts": { + "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"] + }, + "badwords": ["4r5e", "5h1t", "5hit", "a55", "anal", "anus", "ar5e", "arrse", "arse", "ass", "ass-fucker", "asses", "assfucker", "assfukka", "asshole", "assholes", "asswhole", "a_s_s", "b!tch", "b00bs", "b17ch", "b1tch", "ballbag", "balls", "ballsack", "bastard", "beastial", "beastiality", "bellend", "bestial", "bestiality", "bi+ch", "biatch", "bitch", "bitcher", "bitchers", "bitches", "bitchin", "bitching", "bloody", "blowjob", "blowjob", "blowjobs", "boiolas", "bollock", "bollok", "boner", "boob", "boobs", "booobs", "boooobs", "booooobs", "booooooobs", "breasts", "buceta", "bugger", "bum", "bunnyfucker", "butt", "butthole", "buttmuch", "buttplug", "c0ck", "c0cksucker", "carpetmuncher", "cawk", "chink", "cipa", "cl1t", "clit", "clitoris", "clits", "cnut", "cock", "cock-sucker", "cockface", "cockhead", "cockmunch", "cockmuncher", "cocks", "cocksuck", "cocksucked", "cocksucker", "cocksucking", "cocksucks", "cocksuka", "cocksukka", "cok", "cokmuncher", "coksucka", "coon", "cox", "crap", "cum", "cummer", "cumming", "cums", "cumshot", "cunilingus", "cunillingus", "cunnilingus", "cunt", "cuntlick", "cuntlicker", "cuntlicking", "cunts", "cyalis", "cyberfuc", "cyberfuck", "cyberfucked", "cyberfucker", "cyberfuckers", "cyberfucking", "d1ck", "damn", "dick", "dickhead", "dildo", "dildos", "dink", "dinks", "dirsa", "dlck", "dog-fucker", "doggin", "dogging", "donkeyribber", "doosh", "duche", "dyke", "ejaculate", "ejaculated", "ejaculates", "ejaculating", "ejaculatings", "ejaculation", "ejakulate", "fuck", "fucker", "f4nny", "fag", "fagging", "faggitt", "faggot", "faggs", "fagot", "fagots", "fags", "fanny", "fannyflaps", "fannyfucker", "fanyy", "fatass", "fcuk", "fcuker", "fcuking", "feck", "fecker", "felching", "fellate", "fellatio", "fingerfuck", "fingerfucked", "fingerfucker", "fingerfuckers", "fingerfucking", "fingerfucks", "fistfuck", "fistfucked", "fistfucker", "fistfuckers", "fistfucking", "fistfuckings", "fistfucks", "flange", "fook", "fooker", "fuck", "fucka", "fucked", "fucker", "fuckers", "fuckhead", "fuckheads", "fuckin", "fucking", "fuckings", "fuckingshitmotherfucker", "fuckme", "fucks", "fuckwhit", "fuckwit", "fudgepacker", "fudgepacker", "fuk", "fuker", "fukker", "fukkin", "fuks", "fukwhit", "fukwit", "fux", "fux0r", "f_u_c_k", "gangbang", "gangbanged", "gangbangs", "gaylord", "gaysex", "goatse", "God", "god-dam", "god-damned", "goddamn", "goddamned", "hardcoresex", "hell", "heshe", "hoar", "hoare", "hoer", "homo", "hore", "horniest", "horny", "hotsex", "jack-off", "jackoff", "jap", "jerk-off", "jism", "jiz", "jizm", "jizz", "kawk", "knob", "knobead", "knobed", "knobend", "knobhead", "knobjocky", "knobjokey", "kock", "kondum", "kondums", "kum", "kummer", "kumming", "kums", "kunilingus", "l3i+ch", "l3itch", "labia", "lmfao", "lust", "lusting", "m0f0", "m0fo", "m45terbate", "ma5terb8", "ma5terbate", "masochist", "master-bate", "masterb8", "masterbat*", "masterbat3", "masterbate", "masterbation", "masterbations", "masturbate", "mo-fo", "mof0", "mofo", "mothafuck", "mothafucka", "mothafuckas", "mothafuckaz", "mothafucked", "mothafucker", "mothafuckers", "mothafuckin", "mothafucking", "mothafuckings", "mothafucks", "motherfucker", "motherfuck", "motherfucked", "motherfucker", "motherfuckers", "motherfuckin", "motherfucking", "motherfuckings", "motherfuckka", "motherfucks", "muff", "mutha", "muthafecker", "muthafuckker", "muther", "mutherfucker", "n1gga", "n1gger", "nazi", "nigg3r", "nigg4h", "nigga", "niggah", "niggas", "niggaz", "nigger", "niggers", "nob", "nobjokey", "nobhead", "nobjocky", "nobjokey", "numbnuts", "nutsack", "orgasim", "orgasims", "orgasm", "orgasms", "p0rn", "pawn", "pecker", "penis", "penisfucker", "phonesex", "phuck", "phuk", "phuked", "phuking", "phukked", "phukking", "phuks", "phuq", "pigfucker", "pimpis", "piss", "pissed", "pisser", "pissers", "pisses", "pissflaps", "pissin", "pissing", "pissoff", "poop", "porn", "porno", "pornography", "pornos", "prick", "pricks", "pron", "pube", "pusse", "pussi", "pussies", "pussy", "pussys", "rectum", "retard", "rimjaw", "rimming", "shit", "s.o.b.", "sadist", "schlong", "screwing", "scroat", "scrote", "scrotum", "semen", "sex", "sh!+", "sh!t", "sh1t", "shag", "shagger", "shaggin", "shagging", "shemale", "shi+", "shit", "shitdick", "shite", "shited", "shitey", "shitfuck", "shitfull", "shithead", "shiting", "shitings", "shits", "shitted", "shitter", "shitters", "shitting", "shittings", "shitty", "skank", "slut", "sluts", "smegma", "smut", "snatch", "son-of-a-bitch", "spac", "spunk", "s_h_i_t", "t1tt1e5", "t1tties", "teets", "teez", "testical", "testicle", "tit", "titfuck", "tits", "titt", "tittie5", "tittiefucker", "titties", "tittyfuck", "tittywank", "titwank", "tosser", "turd", "tw4t", "twat", "twathead", "twatty", "twunt", "twunter", "v14gra", "v1gra", "vagina", "viagra", "vulva", "w00se", "wang", "wank", "wanker", "wanky", "whoar", "whore", "willies", "willy", "xrated", "xxx"] +} diff --git a/index.js b/index.js new file mode 100644 index 0000000..f15952b --- /dev/null +++ b/index.js @@ -0,0 +1,91 @@ +const fs = require('fs'); +const Planet = require('./planet'); +const PRNG = require('./prng'); +const Star = require('./star'); +const MersenneTwister = require('./twister'); +const utils = require('./utils'); +const data = require('./data.json'); + +var names = []; +var stars = []; +var planets = []; + +function generate() { + 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 = { + badwords: 0, + duplicates: 0 + }, totalCount = 1000, i, position; + + pseudoRandom = new PRNG('96aa48'); + + for (i = 0; i < totalCount; i++) { + var number_of_syllables = Math.floor(pseudoRandom.value() * 2 + 2), new_name; + while (true) { + new_name = utils.random_name(pseudoRandom, number_of_syllables); + if (names.indexOf(new_name) >= 0) { + rejects.duplicates++; + } else if (data.badwords.indexOf(new_name) >= 0 || data.badwords.indexContains(new_name) >= 0) { + rejects.badwords++ + } else { + break; + } + } + names.push(new_name); + var r = pseudoRandom.realRange(min_radius, max_radius); + var theta = spiral_b * Math.log(r / max_radius) + pseudoRandom.gaussrandom(scatter_theta); + r += pseudoRandom.gaussrandom(scatter_radius); + // assign to a spiral arm + theta += pseudoRandom.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms; + position = { + x: Math.cos(theta) * r * 100, + y: Math.sin(theta) * r * 100, + z: pseudoRandom.gaussrandom(thickness * 0.5) + }; + stars.push(new Star(new_name,pseudoRandom.range(1, 100000),position)); + } + stars.sort(function(a, b) { + return a.name > b.name ? 1 : (a.name < b.name ? -1 : 0); + }); + + let temp = stars.pop() + + Object.assign(temp, temp.description()); + + for (star of stars) { + Object.assign(star, star.description()); + } + + fs.writeFileSync(__dirname + '/galaxy.json', JSON.stringify(stars, null, 2)) + + + console.log('names rejected', rejects); + console.log('generate elapsed', (((new Date()).getTime() - start) * 0.001).toFixed(3) + "s"); +} + +Array.prototype.indexContains = function(word) { + for (var idx = 0; idx < this.length; idx++) { + var test = this[idx]; + if (test.indexOf(word) >= 0 || word.indexOf(test) >= 0) { + return idx; + } + } + return -1; +} + +Math.clamp = function(a, min, max) { + return a < min ? min : (a > max ? max : a); +}; + +Array.prototype.insertAt = function(where, what) { + if (where < 0) { + this.splice(0, 0, what); + } else { + var tail = this.splice(where); + this.push(what) + for (var i = 0; i < tail.length; i++) { + this.push(tail[i]); + } + } +} + +generate(); diff --git a/planet.js b/planet.js new file mode 100644 index 0000000..1d1b916 --- /dev/null +++ b/planet.js @@ -0,0 +1,83 @@ +const PRNG = require('./prng'); +const utils = require('./utils'); + +function Planet(name, seed, orbitalRadius, insolation) { + this.name = name; + this.seed = seed; + this.orbitalRadius = orbitalRadius * 10; + this.insolation = insolation; + return this; +} + +Planet.prototype.detail = function() { + var pseudoRandom = new PRNG(this.seed), detail = {}, template; + detail.name = this.name; + detail.orbitalRadius = this.orbitalRadius; + detail.insolation = this.insolation; + detail.blackbodyK = utils.blackbody(detail.insolation); + template = pseudoRandom.pick(planetTypes, [detail.insolation * 100, 10, 1]); + detail.classification = template.classification; + detail.radius = pseudoRandom.range(template.radius[0], template.radius[1]) / 2200; + detail.density = pseudoRandom.realRange(template.density[0], template.density[1]); + detail.gravity = utils.gravity(detail.radius, detail.density); + detail.hydrographics = template.hydrographics(pseudoRandom, detail.insolation, detail.radius, detail.density); + detail.atmosphere = template.atmosphere(pseudoRandom, detail.insolation, detail.radius, detail.density, detail.hydrographics); + detail.HI = template.HI(detail.insolation, detail.radius, detail.density, detail.hydrographics, detail.atmosphere); + return detail; +}; + +Planet.prototype.description = function() { + return this.detail(); +}; + +var planetTypes = [ + { + classification: "rocky", + radius: [1000, 15000], + density: [2, 8], + hydrographics: function(pnrg, insolation, radius, density) { + var g = utils.gravity(radius, density), + tempK = utils.blackbody(insolation, 0); + return Math.clamp(pnrg.realRange(-50, 150 - Math.abs(tempK - 270)) * g - Math.abs(density - 5.5) * 10, 0, 100); + }, + atmosphere: function(pnrg, insolation, radius, density, hydrographics) { + var g = utils.gravity(radius, density); + if (hydrographics > 0 && insolation > 0.25 && insolation < 2) { + return pnrg.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 2, 1, 1, 1]); + } else { + return pnrg.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 3, 4, 5, 5]); + } + }, + HI: function(insolation, radius, density, hydrographics, atmosphere) { + var g = utils.gravity(radius, density), + tempK = utils.blackbody(insolation, 0); + if (atmosphere === "Breathable" && hydrographics > 0 && g < 1.25 && tempK > 230 && tempK < 280) { + return 1; + } else if ((atmosphere === "Breathable" || atmosphere === 'Filterable') && g < 2 && tempK > 200 && tempK < 310) { + return 2; + } else if (atmosphere === "Corrosive" || g > 2 || tempK > 400) { + return tempK > 1000 ? 5 : 4; + } else { + return 3; + } + } +}, +{ + classification: "gas giant", + radius: [15000, 120000], + density: [0.6, 2.0], + hydrographics: utils.fixed_value(0), + atmosphere: utils.fixed_value("Crushing"), + HI: utils.fixed_value(4) +}, +{ + classification: "brown dwarf", + radius: [120000, 250000], + density: [0.6, 2.0], + hydrographics: utils.fixed_value(0), + atmosphere: utils.fixed_value("Crushing"), + HI: utils.fixed_value(5) +}]; + + +module.exports = Planet; diff --git a/prng.js b/prng.js new file mode 100644 index 0000000..81de30a --- /dev/null +++ b/prng.js @@ -0,0 +1,69 @@ +const MersenneTwister = require('./twister'); + +function PRNG(seed) { + this.mt = new MersenneTwister(seed); + return this; +}; + +PRNG.prototype.value = function() { + return this.mt.random(); +}; + +PRNG.prototype.range = function(min, max) { + return Math.floor(this.value() * (max - min + 1) + min); +}; + +PRNG.prototype.realRange = function(min, max, skew_function) { + var v = this.value(); + if (typeof skew_function === 'function') { + v = skew_function(v); + } + return v * (max - min) + min; +}; + +PRNG.prototype.gaussrandom = function(dev) { + var X; + var context = this.gaussrandom.context; + if (context === undefined) { + 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; + if (dev === undefined) { + dev = 1.0; + } + return X * dev; +}; + +PRNG.prototype.pick = function(a, weights) { + var s = 0, + 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]; +}; + +module.exports = PRNG; diff --git a/star.js b/star.js new file mode 100644 index 0000000..2c910aa --- /dev/null +++ b/star.js @@ -0,0 +1,54 @@ +const PRNG = require('./prng'); +const Planet = require('./planet'); +const utils = require('./utils'); +const data = require('./data.json'); + +function Star(name, seed, position) { + this.name = name; + this.seed = seed; + this.position = position; + return this; +} +Star.prototype.detail = function() { + var pseudoRandom = new PRNG(this.seed) + , detail = {} + , spectralClass = pseudoRandom.pick(["O", "B", "A", "F", "G", "K", "M"], [0.0001, 0.2, 1, 3, 8, 12, 20]) + , spectralIndex = pseudoRandom.range(0, 9) + , stellarTemplate = data.starTypes[spectralClass]; + detail.spectralType = spectralClass + spectralIndex; + detail.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)) * 50; + detail.radius = Math.sqrt(detail.luminosity); + detail.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]); + detail.planetSeed = pseudoRandom.range(0, 1000000); + detail.template = stellarTemplate; + return detail; +} +Star.prototype.planets = function() { + var detail = this.detail() + , planets = [] + , pseudoRandom = new PRNG(detail.planetSeed) + , radius_min = 0.4 * pseudoRandom.realRange(0.5, 2) + , radius_max = 50 * pseudoRandom.realRange(0.5, 2) + , total_weight = (Math.pow(detail.numberOfPlanets, 2) + detail.numberOfPlanets) * 0.5 + , r = radius_min; + for (var i = 0; i < detail.numberOfPlanets; i++) { + r += i / total_weight * pseudoRandom.realRange(0.5, 1) * (radius_max - radius_min); + planets.push(new Planet(utils.kappatalize(this.name) + "-" + utils.romanNumeral(i + 1),pseudoRandom.range(0, 100000),r,detail.luminosity / Math.pow(r, 2))); + } + return planets; +} +Star.prototype.description = function() { + let planets = []; + + for (planet of this.planets()) { + planet.description = planet.description(); + planets.push(planet); + } + + return { + "detail": this.detail(), + "planets": planets + } +} + +module.exports = Star; diff --git a/twister.js b/twister.js new file mode 100644 index 0000000..a8231b3 --- /dev/null +++ b/twister.js @@ -0,0 +1,107 @@ +var MersenneTwister = function(seed) { + if (seed == undefined) { + seed = new Date().getTime(); + } + this.N = 624; + this.M = 397; + this.MATRIX_A = 0x9908b0df; + this.UPPER_MASK = 0x80000000; + this.LOWER_MASK = 0x7fffffff; + this.mt = new Array(this.N); + this.mti = this.N + 1; + this.init_genrand(seed); +} + +MersenneTwister.prototype.init_genrand = function(s) { + this.mt[0] = s >>> 0; + for (this.mti = 1; this.mti < this.N; this.mti++) { + var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30); + this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + + this.mti; + this.mt[this.mti] >>>= 0; + } +} + +MersenneTwister.prototype.init_by_array = function(init_key, key_length) { + var i, j, k; + this.init_genrand(19650218); + i = 1; + j = 0; + k = (this.N > key_length ? this.N : key_length); + for (; k; k--) { + var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30) + this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) + + init_key[j] + j; + this.mt[i] >>>= 0; + i++; + j++; + if (i >= this.N) { + this.mt[0] = this.mt[this.N - 1]; + i = 1; + } + if (j >= key_length) j = 0; + } + for (k = this.N - 1; k; k--) { + var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); + this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - + i; + this.mt[i] >>>= 0; + i++; + if (i >= this.N) { + this.mt[0] = this.mt[this.N - 1]; + i = 1; + } + } + this.mt[0] = 0x80000000; +} + +MersenneTwister.prototype.genrand_int32 = function() { + var y; + var mag01 = new Array(0x0, this.MATRIX_A); + if (this.mti >= this.N) { + var kk; + if (this.mti == this.N + 1) + this.init_genrand(5489); + for (kk = 0; kk < this.N - this.M; kk++) { + y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); + this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1]; + } + for (; kk < this.N - 1; kk++) { + y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); + this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1]; + } + y = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK); + this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1]; + this.mti = 0; + } + y = this.mt[this.mti++]; + y ^= (y >>> 11); + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= (y >>> 18); + return y >>> 0; +} + +MersenneTwister.prototype.genrand_int31 = function() { + return (this.genrand_int32() >>> 1); +} + +MersenneTwister.prototype.genrand_real1 = function() { + return this.genrand_int32() * (1.0 / 4294967295.0); +} + +MersenneTwister.prototype.random = function() { + return this.genrand_int32() * (1.0 / 4294967296.0); +} + +MersenneTwister.prototype.genrand_real3 = function() { + return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0); +} + +MersenneTwister.prototype.genrand_res53 = function() { + var a = this.genrand_int32() >>> 5, + b = this.genrand_int32() >>> 6; + return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); +} + +module.exports = MersenneTwister; diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..c303816 --- /dev/null +++ b/utils.js @@ -0,0 +1,77 @@ +const PRNG = require('./prng'); +const data = require('./data.json'); + +function random_name(PRNG, number_of_syllables, allow_second_name, allow_secondary) { + var syllables = [], name; + syllables.push(PRNG.pick(data.nameParts.prefix)); + for (var j = 2; j < number_of_syllables; j++) { + syllables.push(PRNG.pick(data.nameParts.middle)); + } + syllables.push(PRNG.pick(data.nameParts.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 = random_name(PRNG, PRNG.range(2, number_of_syllables), false, false) + " " + name; + name = kappatalize(name); + } + break; + case 'second-name': + if (allow_second_name !== false) { + name = name + " " + random_name(PRNG, PRNG.range(2, number_of_syllables), false); + name = kappatalize(name); + } + break; + case 'secondary': + if (allow_secondary !== false) { + name += " " + PRNG.pick(data.nameParts.secondary); + name = kappatalize(name); + } + break; + } + return kappatalize(name); +} + +function gravity(radius, density) { + return density / 5.56 * radius / 6557; +} + +function blackbody(insolation, albedo) { + if (albedo === undefined) { + albedo = 0; + } + return Math.pow((1367 * insolation * (1 - albedo)) / (4 * 0.0000000567), 0.25); +} + +function fixed_value(val) { + return function() { + return val; + } +} + +function romanNumeral(n) { + var units = ["I", "I", "I", "IV", "V", "VI", "VI", "VI", "IX"]; + if (n == 0) { + return ""; + } else if (n < 0 || n >= 20) { + return n; + } else if (n >= 10) { + return "X" + romanNumeral(n - 10); + } else { + return units[n - 1]; + } +} + +function kappatalize(str) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +module.exports = { + "random_name": random_name, + "gravity": gravity, + "blackbody": blackbody, + "fixed_value": fixed_value, + "romanNumeral": romanNumeral, + "kappatalize": kappatalize +}