Created
September 10, 2018 02:03
-
-
Save canemacchina/7abef3d9555a638106402510490847e9 to your computer and use it in GitHub Desktop.
Dice is a tiny JS object that makes it possible to roll RPG dice using the window.crypto library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Dice is a tiny JS object that makes it possible to roll | |
* cryptographically safe RPG style dice. | |
* | |
* Examples: | |
* Dice.d6(); | |
* Dice.d8.times(3); | |
* Dice.roll("2d6 + 2d10 + 2"); | |
* | |
* Make a coin toss: | |
* Dice.d2 = make_die(2); | |
* Dice.d2(); | |
*/ | |
function make_die(sides) { | |
var die = function(){ | |
var r = 1; | |
// Can use a cryptographically safe random generator? | |
if(typeof window.crypto == 'object'){ | |
var request_bytes = Math.ceil(Math.log2(sides) / 8); | |
if(request_bytes){ // No randomness required | |
var maxNum = Math.pow(256, request_bytes); | |
var ar = new Uint8Array(request_bytes); | |
while(true){ | |
window.crypto.getRandomValues(ar); | |
var val = 0; | |
for(var i = 0;i < request_bytes;i++){ | |
val = (val << 8) + ar[i]; | |
} | |
if(val + sides - (val % sides) < maxNum){ | |
r = 1 + (val % sides); | |
break; | |
} | |
} | |
} | |
}else{ // Not as random, but good enough | |
r = (Math.random() * sides | 0) + 1; | |
} | |
return r; | |
}; | |
die.times = function(count){ | |
var rolls = []; | |
for(var i = 0 ; i < count ; i++){ | |
rolls.push(this()); | |
} | |
return rolls; | |
}; | |
return die; | |
} | |
var Dice = { | |
d4: make_die(4), | |
d6: make_die(6), | |
d8: make_die(8), | |
d10: make_die(10), | |
d12: make_die(12), | |
d20: make_die(20), | |
d100: make_die(100), | |
roll: function(expression){ | |
var self = this, rolls = []; | |
expression.toLowerCase().replace(/(\d+)(d\d+)?/g, function(_, count, die){ | |
if(die){ | |
rolls = rolls.concat(self[die].times(+count)); | |
}else{ | |
rolls.push(+count); | |
} | |
}); | |
return rolls.reduce(function(sum, roll){ | |
return sum + roll; | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment