Wednesday, August 17, 2005

Dice Rolling Fun in Javascript

Well I finally managed to complete my javascript die rolling script. I created it so I could have "interactive" character and monster sheets, since I keep a lot of my DMing info in computers. Eventually I may use XML and XSL but until then this little script adds clickable die rolls to HTML documents. All you have to do is put
<span class="dieroll">1d8</span>
in your HTML and $EmerilSoundEffect you've got a clickable die roll, in this case one eight-sided die.

<html>
<head>
<script language="javascript" type="text/javascript">
function addDiceProperties( ) {
var dieElements = getDieElements( );
var x = 0;
for( x = 0; x < dieElements.length; x++) {
dieElements[x].onclick = dieElements[x].onkeypress =
dieRoller(dieElements[x].innerHTML);
}
}

function getDieElements( ) {
var spans = document.getElementsByTagName("span");
var dieElems = [];
var isaDieRoll = /\bdieroll\b/;
for(j = 0; j < spans.length; j++) {
if ( isaDieRoll.test(spans[j].className ) ) {
dieElems[dieElems.length] = spans[j];
}
}
return dieElems;
}

function dieRoller(txt) {
var count;
var sides;
var count_sides = getDieArgs(txt);
count = count_sides[0];
sides = count_sides[1];
return function( ) {
return rollDie(count, sides);
};
}

function rollDie(count, sides) {
var results = 0;
var i = 0;
for(i = 0; i < count; i++) {
results += intRand(1, sides);
}
document.getElementById("resultsbox").value = results;
}


function intRand(mini, maxi) {
var range = maxi - mini + 1;
return Math.floor(Math.random() * range + mini);
}

function getDieArgs(txt) {
var pat = /([0-9]+)d([0-9]+)/;
var res = [];
var match = pat.exec(txt);
res[0] = parseInt(match[1]);
res[1] = parseInt(match[2]);
return res;
}

</script>
<style type="text/css">
.dieroll {
color: blue;
text-decoration: underline;
}

#resultsdiv {
position: fixed;
right: 0;
top: 0;
border-style: dashed;
border-width: 1px;
background-color: white;
padding: 1px 1px 1px 1px;
margin: 1px 1px 1px 1px;
}
#resultsbox {
width: 3em;
}
</style>

</head>
<body onload="addDiceProperties( )">
<div id="resultsdiv">Die Results: <input type="text" id="resultsbox"></div>
<div><!-- This is where the rest of your stuff goes -->
<p>
<ul>
<li><span class="dieroll">1d4</span></li>
<li><span class="dieroll">3d6</span></li>
<li><span class="dieroll">1d8</span></li>
<li><span class="dieroll">1d10</span></li>
<li><span class="dieroll">1d12</span></li>
<li><span class="dieroll">1d20</span></li>
<li><span class="dieroll">1d100</span></li>
</ul>
</p>
</div>
</body>
</html>


EDIT: 5:45PM

Well it seems there are some bugs in the randomness code part. Doesn't look like we ever get natural 20s for instance. I get the feeling it has something to do with the chance of getting a 1 from Math.random( ). So I am going to fiddle with this code, and welcome any suggestions.



EDIT: 8:30 PM

Fixed it. Knew there was something fishy. Thanks to http://www.werelight.com/docs/JavaScript_Quick_Reference.htm

2 comments:

Young Dave said...

dude, your intRand function never returns the maxi cuz i think the logics a little messed up. try this:
function intRand(mini, maxi) {
var range = maxi - mini;
return Math.round(Math.random() * range + mini);
}

Young Dave said...

haha, oops, didn't see you already fixed it