diff --git a/Astrophysics.js b/Astrophysics.js new file mode 100644 index 0000000..c0869cd --- /dev/null +++ b/Astrophysics.js @@ -0,0 +1,139 @@ +class Astrophysics { + static gravity(radius, density) { + return density / 5.56 * radius / 6557; + } + + static blackbody(insolation, albedo = 0) { + return Math.pow((1367 * insolation * (1 - albedo)) / (4 * 0.0000000567), 0.25); + } + + static HI(insolation, radius, density, hydrographics, atmosphere) { + const g = Astrophysics.gravity(radius, density).toFixed(2); + const { albedo } = atmosphere ? Astrophysics.atmosphereData[atmosphere] : 0; + const tempK = Astrophysics.blackbody(insolation, albedo + hydrographics * 0.002).toFixed(1); + const tempC = (tempK- 275.15).toFixed(1); + + let temperature; + + if (tempC < -150) { + temperature = 'frigid'; + } + else if (tempC < -70) { + temperature = 'very cold'; + } + else if (tempC < -10) { + temperature = 'cold'; + } + else if (tempC < 30) { + temperature = 'temperate'; + } + else if (tempC < 60) { + temperature = 'hot'; + } + else if (tempC < 120) { + temperature = 'very hot'; + } + else { + temperature = 'inferno'; + } + + let data; + + if (atmosphere === 'Breathable' && hydrographics > 0 && g < 1.25 && ['cold', 'hot', 'temperate'].indexOf(temperature) > -1) { + data = { HI: 1, description: 'earthlike' }; + } + else if (['Breathable', 'Filterable'].indexOf(atmosphere) > -1 && g < 2 && ['inferno', 'frigid'].indexOf(temperature) === -1) { + data = { HI: 2, description: 'survivable' }; + } + else if (atmosphere === 'Corrosive' || g > 3 || ['inferno', 'frigid'].indexOf(temperature) > -1) { + data = tempC > 800 ? { HI: 5, description: 'inimical' } : { HI: 1, description: 'robot accessible' }; + } + else { + data = { HI: 3, description: 'EVA possible' }; + } + + return Object.assign(data, { g, albedo, tempC, temperature }); + }; +}; + +Astrophysics.starTypeData = { + 'O': { + luminosity: 50000, color: 0xFFC0FF, planets: [0, 3] + }, + 'B': { + luminosity: 15000, color: 0xC0A0FF, planets: [1, 5] + }, + 'A': { + luminosity: 25, color: 0x80C0FF, planets: [1, 7] + }, + 'F': { + luminosity: 2.5, color: 0xA0FF80, planets: [1, 11] + }, + 'G': { + luminosity: 1, color: 0xFFFF40, planets: [1, 19] + }, + 'K': { + luminosity: 0.25, color: 0xFFC040, planets: [1, 9] + }, + 'M': { + luminosity: 0.05, color: 0xFF4000, planets: [1, 5] + }, + 'black hole': { + luminosity: 100000, color: 0x800040, planets: [0, 0] + } +}; + +Astrophysics.atmosphereData = { + Breathable: { + albedo: 0.2, density: 1 + }, + Filterable: { + albedo: 0.3, density: 1 + }, + Inert: { + albedo: 0.1, density: 0.5 + }, + Corrosive: { + albedo: 0.5, density: 2 + }, + Toxic: { + albedo: 0.4, density: 1.5 + }, + Trace: { + albedo: 0.05, density: 0.1 + }, + Crushing: { + albedo: 0.8, density: 100 + } +}; + +Astrophysics.planetTypeData = [ + { + classification:'rocky', + radius: [1000,15000], + density: [2,8], + hydrographics: function(pnrg, insolation, radius, density) { + let g = Astrophysics.gravity(radius, density), + tempK = Astrophysics.blackbody(insolation, 0); + return Math.clamp(pnrg.realRange(-50, 150 - Math.abs(tempK - 270)) * g - Math.abs(density - 5.5) * 10, 0, 100).toFixed(0); + }, + atmosphere: function(pnrg, insolation, radius, density, hydrographics) { + let g = Astrophysics.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: Astrophysics.HI + }, + { + classification: 'gas giant', radius: [15000, 120000], density: [0.6, 2.0], hydrographics: 0, atmosphere: 'Crushing', HI: Astrophysics.HI + }, + { + classification: 'brown dwarf', radius: [120000, 250000], density: [0.6, 2.0], hydrographics: 0, atmosphere: 'Crushing', HI: Astrophysics.HI + } +]; + +module.exports = Astrophysics; diff --git a/Galaxy.js b/Galaxy.js new file mode 100644 index 0000000..7ed8c6e --- /dev/null +++ b/Galaxy.js @@ -0,0 +1,64 @@ +const PRNG = require('./PRNG'); +const badwords = require('./badwords'); +const utils = require('./utils'); +const Star = require('./Star'); + +const spiral_arms = 2; +const spiral_angle_degrees = 360; +const min_radius = 0.05; +const max_radius = 0.9; +const thickness = 0.1; +const scatter_theta = Math.PI / spiral_arms * 0.2; +const scatter_radius = min_radius * 0.4; +const spiral_b = spiral_angle_degrees / Math.PI * min_radius / max_radius; +const names = []; +const rejects = { badwords: 0, duplicates: 0 }; + +class Galaxy { + constructor(seed, number_of_stars) { + this.stars = []; + + let i; + let position; + + let pseudoRandom = new PRNG(seed); + + for (i = 0; i < number_of_stars; i++) { + let number_of_syllables = Math.floor(pseudoRandom.value() * 2 + 2); + let new_name; + + while (true) { + new_name = PRNG.random_name(pseudoRandom, number_of_syllables); + + if (names.indexOf(new_name) >= 0) { + rejects.duplicates++; + } + else if (badwords.indexOf(new_name) >= 0 || badwords.indexContains(new_name) >= 0) { + rejects.badwords++ + } + else { + break; + } + } + + names.push(new_name); + + let r = pseudoRandom.realRange(min_radius, max_radius); + let theta = spiral_b * Math.log(r / max_radius) + pseudoRandom.gaussrandom(scatter_theta); + + r += pseudoRandom.gaussrandom(scatter_radius); + + theta += pseudoRandom.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms; + + position = { + x: Math.cos(theta) * r, + y: Math.sin(theta) * r, + z: pseudoRandom.gaussrandom(thickness * 0.5) + }; + + this.stars.push(new Star(new_name, pseudoRandom.range(1, 100000), position)); + } + } +} + +module.exports = Galaxy; diff --git a/MersenneTwister.js b/MersenneTwister.js new file mode 100644 index 0000000..83e1fca --- /dev/null +++ b/MersenneTwister.js @@ -0,0 +1,123 @@ +class MersenneTwister { + constructor(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); + }; + + init_genrand(s) { + this.mt[0] = s >>> 0; + + for (this.mti = 1; this.mti < this.N; this.mti++) { + let 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; + } + } + + init_by_array(init_key, key_length) { + let i, j, k; + + this.init_genrand(19650218); + + i = 1; + j = 0; + k = (this.N > key_length ? this.N : key_length); + + for (; k; k--) { + let 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--) { + let 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; + } + + genrand_int32() { + let y; + let mag01 = new Array(0x0, this.MATRIX_A); + + if (this.mti >= this.N) { + let 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; + } + + genrand_int31() { + return (this.genrand_int32() >>> 1); + } + + genrand_real1() { + return this.genrand_int32() * (1.0 / 4294967295.0); + } + + random() { + return this.genrand_int32() * (1.0 / 4294967296.0); + } + + genrand_real3() { + return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0); + } + + genrand_res53() { + let 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/PRNG.js b/PRNG.js new file mode 100644 index 0000000..6724ce3 --- /dev/null +++ b/PRNG.js @@ -0,0 +1,122 @@ +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 diff --git a/Planet.js b/Planet.js new file mode 100644 index 0000000..4e006f2 --- /dev/null +++ b/Planet.js @@ -0,0 +1,37 @@ +const { gravity, blackbody, planetTypeData } = require('./Astrophysics'); +const PRNG = require('./PRNG'); + +class Planet { + constructor(name, seed, orbitalRadius, insolation) { + this.name = name; + this.seed = seed; + this.orbitalRadius = orbitalRadius; + this.insolation = insolation; + + this.details = this.get_details(); + }; + + get_details() { + let pseudoRandom = new PRNG(this.seed); + let detail = {}; + let template; + + template = pseudoRandom.pick(planetTypeData, [this.insolation.toFixed(2) * 100, 10, 1]); + detail.name = this.name; + detail.orbitalRadius = this.orbitalRadius.toFixed(2); + detail.insolation = this.insolation.toFixed(2); + detail.blackbodyK = blackbody(detail.insolation); + detail.classification = template.classification; + detail.radius = pseudoRandom.range(template.radius[0], template.radius[1]); + detail.density = pseudoRandom.realRange(template.density[0], template.density[1]); + detail.gravity = gravity(detail.radius, detail.density); + detail.hydrographics = typeof template.hydrographics === 'function' && template.hydrographics(pseudoRandom, detail.insolation, detail.radius, detail.density); + detail.atmosphere = typeof template.atmosphere === 'function' && template.atmosphere(pseudoRandom, detail.insolation, detail.radius, detail.density, detail.hydrographics); + + Object.assign(detail, template.HI(detail.insolation, detail.radius, detail.density, detail.hydrographics, detail.atmosphere)); + + return detail; + }; +}; + +module.exports = Planet; diff --git a/Star.js b/Star.js new file mode 100644 index 0000000..0fb44f5 --- /dev/null +++ b/Star.js @@ -0,0 +1,75 @@ +const Planet = require('./Planet'); +const PRNG = require('./PRNG'); +const { starTypeData } = require('./Astrophysics'); + +class Star { + constructor(name, seed, position) { + this.name = name; + this.seed = seed; + this.position = position; + + this.position.far_x = (this.position.x * 50000).toFixed(2); + this.position.far_y = (this.position.y * 50000).toFixed(2); + this.position.far_z = (this.position.z * 50000).toFixed(2); + + let details = this.get_details(); + this.radius = Math.max(Math.min(Math.log(details.luminosity) + 8, 20), 2); + this.color = details.template.color; + + this.details = details; + this.planets = this.get_planets(); + }; + + romanNumeral(n) { + const units = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']; + + if (n == 0) { + return ''; + } else if (n < 0 || n >= 20) { + return n; + } else if (n >= 10) { + return 'X' + this.romanNumeral(n - 10); + } else { + return units[n - 1]; + } + }; + + get_details() { + let detail = {}; + + let pseudoRandom = new PRNG(this.seed); + let spectralClass = pseudoRandom.pick(['O', 'B', 'A', 'F', 'G', 'K', 'M'], [0.0001, 0.2, 1, 3, 8, 12, 20]); + let spectralIndex = pseudoRandom.range(0, 9); + let stellarTemplate = starTypeData[spectralClass]; + + detail.spectralType = spectralClass + spectralIndex; + detail.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)); + detail.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]); + detail.planetSeed = pseudoRandom.range(0, 1000000); + detail.template = stellarTemplate; + + return detail; + }; + + get_planets() { + let details = this.details; + let planets = []; + let pseudoRandom = new PRNG(details.planetSeed); + let radius_min = 0.4 * pseudoRandom.realRange(0.5, 2); + let radius_max = 50 * pseudoRandom.realRange(0.5, 2); + let total_weight = (Math.pow(details.numberOfPlanets, 2) + details.numberOfPlanets) * 0.5; + let r = radius_min; + + for (let i = 0; i < details.numberOfPlanets; i++) { + r += i / total_weight * pseudoRandom.realRange(0.5, 1) * (radius_max - radius_min); + + planets.push( + new Planet(this.name.capitalize() + '-' + this.romanNumeral(i + 1), pseudoRandom.range(0, 100000), r, details.luminosity / Math.pow(r, 2)) + ); + } + + return planets; + }; +} + +module.exports = Star; diff --git a/badwords.json b/badwords.json new file mode 100644 index 0000000..6d3e720 --- /dev/null +++ b/badwords.json @@ -0,0 +1,453 @@ +[ + "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/data.json b/data.json deleted file mode 100644 index 41545bd..0000000 --- a/data.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "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/galaxygen b/galaxygen index aa64ddd..7c24251 100755 --- a/galaxygen +++ b/galaxygen @@ -1,27 +1,26 @@ #!/usr/bin/env node -const fs = require('fs'); -const cli = require('cli'); -const galaxy = require('./index'); +const fs = require('fs'); +const cli = require('cli'); +const Galaxy = require('./Galaxy'); cli.parse({ - seed: ['s', 'The seed you want to generate with. (defaults to \'1234\')', 'string'], - amount: ['a', 'The amount of stars you want to generate. (defaults to 1000)', 'int'], - output: ['o', 'The output file (if enabled). (defaults to printing JSON to stdout)', 'string'], + seed: ['s', 'The seed you want to generate with. (defaults to \'1234\')', 'string'], + amount: ['a', 'The amount of stars you want to generate. (defaults to 1000)', 'int'], + output: ['o', 'The output file (if enabled). (defaults to printing JSON to stdout)', 'string'], }); cli.main((args, options) => { - var gen = galaxy.generate(options.seed, options.amount); - - if (options.output) { - fs.access(options.output, fs.R_OK | fs.W_OK, (err) => { - if (err) console.log('No write access to the specified output file!'); - else { - fs.writeFileSync(options.output, JSON.stringify(gen, null, 2)); - } - }); - } - else { - console.log(JSON.stringify(gen, null, 2)); - } + let galaxy = new Galaxy(options.seed || ~~(Math.random() * 10000), options.amount || 1000); + if (options.output) { + fs.access(options.output, fs.R_OK | fs.W_OK, (err) => { + if (err) console.log('No write access to the specified output file!'); + else { + fs.writeFileSync(options.output, JSON.stringify(galaxy, null, 2)); + } + }); + } + else { + console.log(JSON.stringify(galaxy, null, 2)); + } }); diff --git a/index.js b/index.js deleted file mode 100644 index 95205a6..0000000 --- a/index.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs'); -const PRNG = require('./prng'); -const Star = require('./star'); -const utils = require('./utils'); -const data = require('./data.json'); - -var names = []; -var stars = []; -var planets = []; - -function generate(seed, amount) { - if (!amount) amount = 1000; - 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 = { - badwords: 0, - duplicates: 0 - }, - - totalCount = amount, - i, - position, - lastSeed; - - prng = new PRNG(seed); - - for (i = 0; i < totalCount; i++) { - var number_of_syllables = Math.floor(prng.value() * 2 + 2), new_name; - while (true) { - new_name = utils.random_name(prng, 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 = prng.realRange(min_radius, max_radius); - var theta = spiral_b * Math.log(r / max_radius) + prng.gaussrandom(scatter_theta); - r += prng.gaussrandom(scatter_radius); - // assign to a spiral arm - theta += prng.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms; - position = { - x: (Math.cos(theta) * r) * 100, - y: (Math.sin(theta) * r) * 100, - z: prng.gaussrandom(thickness * 0.5) * 100 - }; - - //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; -} - -module.exports = { - "generate": generate -} diff --git a/map.js b/map.js deleted file mode 100644 index 8c4ff08..0000000 --- a/map.js +++ /dev/null @@ -1,3 +0,0 @@ -const PRNG = require('./prng'); - -var seed = 411234; diff --git a/planet.js b/planet.js deleted file mode 100644 index 1ebea19..0000000 --- a/planet.js +++ /dev/null @@ -1,107 +0,0 @@ -const PRNG = require('./prng'); -const utils = require('./utils'); - -function Planet(name, seed, orbitalRadius, insolation, hasStation) { - var pseudoRandom = new PRNG(seed), - template = pseudoRandom.pick(planetTypes, [insolation * 100, 10, 1]); - - this.name = name; - this.seed = seed; - this.orbitalRadius = orbitalRadius * 10; - this.insolation = insolation; - this.blackbodyK = utils.blackbody(this.insolation); - this.temperature = this.blackbodyK - 273.15; - this.classification = template.classification; - this.radius = pseudoRandom.range(template.radius[0], template.radius[1]) / 2200; - this.density = pseudoRandom.realRange(template.density[0], template.density[1]); - this.gravity = utils.gravity(this.radius, this.density); - this.hydrographics = template.hydrographics(pseudoRandom, this.insolation, this.radius, this.density); - this.atmosphere = template.atmosphere(pseudoRandom, this.insolation, this.radius, this.density, this.hydrographics); - this.HI = template.HI(this.insolation, this.radius, this.density, this.hydrographics, this.atmosphere); - this.habitable = this.HI == 2 && this.temperature > -60 && this.temperature < 60; - if (pseudoRandom.value() > .9) this.water = { - color: this.generateWaterColor(this.temperature, pseudoRandom) - } - - this.color = this.generateColor(this.temperature, this.water, pseudoRandom); - - - return this; -} - -Planet.prototype.generateStation = function (prng) { - return { - size: prng.pick(['small', 'big', 'epic'], [498, 499, 8]), - economy: prng.pick(['mining', 'agricultural', 'tech', 'industrial', 'residential'], [15, 30, 15, 10, 30]) - - } -} - -Planet.prototype.generateColor = function (temperature, water, prng) { - if (temperature < 0 && water) { - var color = Math.floor(prng.value() * 100) + 155; - return [color, color, color]; - } - else { - return [Math.floor(prng.value() * 100) + 125, Math.floor(prng.value() * 100) + 125, Math.floor(prng.value() * 100) + 125]; - } -} - -Planet.prototype.generateWaterColor = function (temperature, prng) { - if (temperature > 100) return false; - else { - return [Math.floor(prng.value() * 60) + 50, Math.floor(prng.value() * 60) + 50, Math.floor(prng.value() * 200) + 55] - } -} - -var planetTypes = [ - { - classification: "rocky", - radius: [1000, 15000], - density: [2, 8], - hydrographics: function(prng, insolation, radius, density) { - var g = utils.gravity(radius, density), - tempK = utils.blackbody(insolation, 0); - return Math.clamp(prng.realRange(-50, 150 - Math.abs(tempK - 270)) * g - Math.abs(density - 5.5) * 10, 0, 100); - }, - atmosphere: function(prng, insolation, radius, density, hydrographics) { - var g = utils.gravity(radius, density); - if (hydrographics > 0 && insolation > 0.25 && insolation < 2) { - return prng.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 2, 1, 1, 1]); - } else { - return prng.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 deleted file mode 100644 index d668e03..0000000 --- a/prng.js +++ /dev/null @@ -1,73 +0,0 @@ -const MersenneTwister = require('./twister'); - -function PRNG(seed) { - this.mt = new MersenneTwister(seed); - this.seed = seed; - return this; -}; - -PRNG.prototype.seed = 0; - -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 deleted file mode 100644 index 52dc598..0000000 --- a/star.js +++ /dev/null @@ -1,65 +0,0 @@ -const PRNG = require('./prng'); -const Planet = require('./planet'); -const utils = require('./utils'); -const data = require('./data.json'); - -function Star(name, seed, position) { - var pseudoRandom = new PRNG(seed), - 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), - stellarTemplate = data.starTypes[spectralClass]; - - this.name = name; - this.seed = seed; - this.position = position; - if (spectralClass != 'black hole') - this.spectralType = spectralClass + spectralIndex; - else - this.spectralType = spectralClass; - this.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)) * 50; - this.radius = Math.sqrt(this.luminosity); - this.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]); - this.numberOfStations = pseudoRandom.range(0, this.numberOfPlanets / 20); - this.planetSeed = pseudoRandom.range(0, 1000000); - this.color = stellarTemplate.color; - this.planets = this.generatePlanets(); - - return this; -} - -Star.prototype.generatePlanets = function () { - var planets = [], - pseudoRandom = new PRNG(this.planetSeed), - radius_min = 0.4 * pseudoRandom.realRange(0.5, 2), - radius_max = 50 * pseudoRandom.realRange(0.5, 2), - total_weight = (Math.pow(this.numberOfPlanets, 2) + this.numberOfPlanets) * 0.5, - r = radius_min - - for (var i = 0; i < this.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, 1000000), r, this.luminosity / Math.pow(r, 2))); - } - - this.divideStations(planets, this.seed); - - return planets; -} - -Star.prototype.divideStations = function (planets, seed) { - var stations = this.numberOfStations || 0; - var i = planets.length - 1; - var pseudoRandom = new PRNG(seed); - - for (i = 0; i < stations; i++) { - var arr = [] - for (planet of planets) { - arr.push(100 / planets.length); - } - var planet = pseudoRandom.pick(planets, arr); - planet.station = planet.generateStation(pseudoRandom); - planet.station.seed = planet.seed; - } - -} - -module.exports = Star; diff --git a/twister.js b/twister.js deleted file mode 100644 index a8231b3..0000000 --- a/twister.js +++ /dev/null @@ -1,107 +0,0 @@ -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 index e9c0c50..8e6c40e 100644 --- a/utils.js +++ b/utils.js @@ -1,71 +1,6 @@ -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); -} +Math.clamp = function(a, min, max) { + return a < min ? min : (a > max ? max : a); +}; Array.prototype.indexContains = function(word) { for (var idx = 0; idx < this.length; idx++) { @@ -75,29 +10,12 @@ Array.prototype.indexContains = function(word) { } } 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); +String.prototype.capitalize = function() { + if (this) { + return this.substr(0, 1).toUpperCase() + this.substr(1); } else { - var tail = this.splice(where); - this.push(what) - for (var i = 0; i < tail.length; i++) { - this.push(tail[i]); - } + return ''; } -} - -module.exports = { - "random_name": random_name, - "gravity": gravity, - "blackbody": blackbody, - "fixed_value": fixed_value, - "romanNumeral": romanNumeral, - "kappatalize": kappatalize -} +};