From dc8e3b6766b84deb2c609ad9488a7ea67180aa1b Mon Sep 17 00:00:00 2001 From: kopareigns <kopareigns@gmail.com> Date: Sun, 7 Oct 2018 00:16:49 -0400 Subject: [PATCH] Normal distribution for intelligence --- src/js/utilJS.tw | 97 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/src/js/utilJS.tw b/src/js/utilJS.tw index 18549d4aa77..7fe7ed1251c 100644 --- a/src/js/utilJS.tw +++ b/src/js/utilJS.tw @@ -144,13 +144,6 @@ window.Height = (function(){ return table[nationality + "." + race] || table[nationality] || table["." + race] || table[""] || def; }; - // Helper method - generate two independent Gaussian numbers using Box-Muller transform - const gaussianPair = function() { - let r = Math.sqrt(-2.0 * Math.log(1 - Math.random())); - let sigma = 2.0 * Math.PI * (1 - Math.random()); - return [r * Math.cos(sigma), r * Math.sin(sigma)]; - }; - // Helper method: Generate a skewed normal random variable with the skew s // Reference: http://azzalini.stat.unipd.it/SN/faq-r.html const skewedGaussian = function(s) { @@ -290,6 +283,96 @@ window.Height = (function(){ }; })(); +window.Intelligence = (function(){ + 'use strict'; + + // Global configuration (for different game modes/options/types) + var mean = 0; + var minMult = -3.0; + var maxMult = 3.0; + var skew = 0.0; + var spread = 45; + var minIntelligence = -101; + var maxIntelligence = 100; + + // Configuration method for the above values + const _config = function(conf) { + if(_.isUndefined(conf)) { + return {mean: mean, limitMult: [minMult, maxMult], limitIntelligence: [minIntelligence, maxIntelligence], skew: skew, spread: spread}; + } + if(_.isFinite(conf.mean)) { mean = Math.clamp(conf.mean, -100, 100); } + if(_.isFinite(conf.skew)) { skew = Math.clamp(conf.skew, -1000, 1000); } + if(_.isFinite(conf.spread)) { spread = Math.clamp(conf.spread, 0.1, 100); } + if(_.isArray(conf.limitMult) && conf.limitMult.length === 2 && conf.limitMult[0] !== conf.limitMult[1] && + _.isFinite(conf.limitMult[0]) && _.isFinite(conf.limitMult[1])) { + minMult = Math.min(conf.limitMult[0], conf.limitMult[1]); + maxMult = Math.max(conf.limitMult[0], conf.limitMult[1]); + } + if(_.isArray(conf.limitIntelligence) && conf.limitIntelligence.length === 2 && conf.limitIntelligence[0] !== conf.limitIntelligence[1] && + _.isFinite(conf.limitIntelligence[0]) && _.isFinite(conf.limitIntelligence[1])) { + minIntelligence = Math.min(conf.limitIntelligence[0], conf.limitIntelligence[1]); + maxIntelligence = Math.max(conf.limitIntelligence[0], conf.limitIntelligence[1]); + } + return {limitMult: [minMult, maxMult], limitIntelligence: [minIntelligence, maxIntelligence], skew: skew, spread: spread}; + }; + + // Helper method: Generate a skewed normal random variable with the skew s + // Reference: http://azzalini.stat.unipd.it/SN/faq-r.html + const skewedGaussian = function(s) { + let randoms = gaussianPair(); + if(s === 0) { + // Don't bother, return an unskewed normal distribution + return randoms[0]; + } + let delta = s / Math.sqrt(1 + s * s); + let result = delta * randoms[0] + Math.sqrt(1 - delta * delta) * randoms[1]; + return randoms[0] >= 0 ? result : -result; + }; + + // Height multiplier generator; skewed gaussian according to global parameters + const multGenerator = function() { + let result = skewedGaussian(skew); + while(result < minMult || result > maxMult) { + result = skewedGaussian(skew); + } + return result; + }; + + // Helper method: Generate an intelligence based on the mean one and limited according to config. + const intelligenceGenerator = function() { + let result = multGenerator() * spread + mean; + + while(result < minIntelligence || result > maxIntelligence) { + result = multGenerator() * spread + mean; + } + + return Math.ceil(result); + }; + + const _randomIntelligence = function(settings) { + if (settings) { + const currentConfig = _config(); + _config(settings); + const result = intelligenceGenerator(); + _config(currentConfig); + return result; + } + return intelligenceGenerator(); + }; + + return { + random: _randomIntelligence, + config: _config, + }; +})(); + +// Helper method - generate two independent Gaussian numbers using Box-Muller transform +window.gaussianPair = function() { + let r = Math.sqrt(-2.0 * Math.log(1 - Math.random())); + let sigma = 2.0 * Math.PI * (1 - Math.random()); + return [r * Math.cos(sigma), r * Math.sin(sigma)]; +}; + if(!Array.prototype.findIndex) { Array.prototype.findIndex = function(predicate) { if (this == null) { -- GitLab