Skip to content

Instantly share code, notes, and snippets.

@jaguilar
Created March 5, 2013 18:52
Show Gist options
  • Save jaguilar/5093046 to your computer and use it in GitHub Desktop.
Save jaguilar/5093046 to your computer and use it in GitHub Desktop.
Pathfinder tools
function CLAMP(min, max, n) {
if (n < min) return min;
if (n > max) return max;
return n;
}
function MEETPROB(n) {
return CLAMP(0.05, 0.95, 1-((n-1)/20.0));
}
function IN20(n) {
return MEETPROB(20 - n);
}
function EXPECTED(s) {
return DEXPR(s, DEXPECT);
}
function DEXPECT(number, sides) {
return number * ((sides + 1) / 2)
}
// Long story short, this function applies a function to a dice expression
// like 1d10 + 2. It also supports multiplication. The function gets to
// handle each dice listing, but does not see integers. Whitespace is ignored
// between numbers and operators, including between d and the dice numbers.
// A missing dice count results in 1. Parens are not permitted (what the crap
// game system are you playing in???).
//
// s: A string containing a dice expression. A dice expression is:
// expr := dice '+' expr |
// dice '*' expr |
// dice |
// number
// dice := number 'd' number
// Normal arithmetic binding rules apply (* binds tighter than +).
// dicefunction: A function that takes two params, a number of dice and a number of sides.
// It must return an integer. Each dice in the dice expression will be sent to this
// function, and the results will be tabulated by applying the requested
// arithmetic operators.
//
// DEXPECT: A provided dice function that returns the expected value.
//
// Other potential functions I haven't implemented yet:
// DEXEC: Run the dice function with an RNG.
// DMAX, DMIN: Return the max and min.
// DDIST: Generate a distribution for the dice expression.
function DEXPR(s, dicefunction) {
var sum = 0;
var parts = s.split(/\s*\+\s*/g);
for (var i = 0; i < parts.length; ++i) {
sum += DTIMES(parts[i], dicefunction);
}
return sum;
}
function DTIMES(s, dicefunction) {
var product = 1;
var parts = s.split(/\s*\*\s*/g);
for (var i = 0; i < parts.length; ++i) {
product *= DPARSE(parts[i], dicefunction);
}
return product;
}
function DPARSE(s, dicefunction) {
var parts = s.match(/(\d*)?\s*d\s*(\d+)/);
if (parts == null) {
return parseInt(s);
} else if (parts.length == 3) {
if (parts[1] == undefined) {
return dicefunction(1, parseInt(parts[2]));
} else {
return dicefunction(parseInt(parts[1]), parseInt(parts[2]));
}
} else {
alert("Weird input to DPARSE " + s);
}
}
function test_pathfinder() {
var f = function(n1, n2) {
Logger.log(n1 + ", " + n2);
return n1 * (n2 + 1) / 2;
}
Logger.log(DPARSE("1d10", f));
Logger.log(DPARSE("d5", f));
Logger.log(DPARSE("5d2", f));
Logger.log(DPARSE("2", f));
Logger.log(DEXPR("2d10 + 1d5 * 1d5 + 5", f));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment