Skip to content

Instantly share code, notes, and snippets.

@sma
Last active August 29, 2015 14:05
Show Gist options
  • Save sma/898b3ecad7d6bea87ebf to your computer and use it in GitHub Desktop.
Save sma/898b3ecad7d6bea87ebf to your computer and use it in GitHub Desktop.
// roll a single n-sided die
function d(n) {
return Math.floor(Math.random() * n) + 1;
}
// roll an exploding n-sided die
function dx(n) {
var v = d(n); return v === n ? v + dx(n) : v;
}
// roll an exploding n-sided die along with an exploding D6
function ddx(n) {
return Math.max(dx(n), dx(6));
}
function attack(attacker, defender) {
var wild = 0, fullDefense = 0;
// roll to remove shaken
if (ddx(defender.spirit) - defender.wounds >= 4) defender.shaken = false;
// roll to attack
var a = ddx(attacker.fighting) + wild - fullDefense;
if (a >= defender.parry) {
// deal damage and compute wounds
var damage = dx(attacker.strength) + dx(8) + wild;
if (a >= defender.parry + 4) damage += dx(6);
var wounds = Math.floor((damage - defender.toughness) / 4);
if (defender.shaken && wounds === 0) wounds = 1;
if (wounds > 0) defender.shaken = true;
// soak damage if possible
if (wounds > 0 && defender.bennies > 0) {
defender.bennies--;
var soak = Math.floor((ddx(defender.constitution) - defender.wounds) / 4);
if (soak > 0) wounds -= soak;
if (wounds == 0) defender.shaken = false;
}
if (wounds > 0) {
defender.wounds -= wounds;
}
return defender.wounds <= -4;
}
return false;
}
function killAlrik() {
var alrik = {
agility: 8,
strength: 8,
constitution: 6,
spirit: 6,
fighting: 8,
parry: 6,
toughness: 8,
wounds: 0,
shaken: false,
bennies: 2
};
for (var turn = 1; ; turn++) {
if (attack(alrik, alrik)) {
return turn;
}
}
}
function sample(fn, count) {
var samples = [], i;
for (i = 0; i < 200; i++) {
samples.push(0);
}
for (i = 0; i < count; i++) {
samples[fn()]++;
}
return samples;
}
function variance(samples, count) {
var m = 0, v = 0, i;
for (i = 0; i < samples.length; i++) {
m += i * samples[i];
}
m /= count;
for (i = 0; i < samples.length; i++) {
v += Math.pow(i - m, 2) * samples[i];
}
v /= count;
return [m, Math.sqrt(v)];
}
function graph(samples, count) {
var i, s, x, p, f = 400;
for (i = 0; i < samples.length; i++) {
if (samples[i] > 0) {
p = Math.round(samples[i] / count * 1000);
if (p > .1) {
s = "" + i;
while (s.length < 2) {
s = " " + s;
}
s += ": ";
x = Math.round(samples[i] / count * f);
do {
s += "-";
} while (--x > 0);
console.log(s + " " + p / 10 + "%");
}
}
}
}
var count = 10000;
var samples = sample(killAlrik, count);
console.log(variance(samples, count));
graph(samples, count);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment