I'll get this out of the way quick: Yes, I know, everyone's done a !roll script. I also know that mine probably could be optimized.
This is just like any other roll script, with a twist. It allows for DnD dice notation (e.g. 2d20).
For example, if you input !roll 2d20 + 2, it will "roll" 2 20-sided dice, then add 2 to the sum of the rolls. It has support for parantheses and all basic mathematical functions ( +-*/^ ). It also comes with an on INPUT command for you to roll for yourself. If you do not want this functionality, just remove it, I don't mind.
NOTE: This is a simple version, I do not have any built-in functionality to select which channels or nicknames it works with, nor does it have flood protection (yet), you'll have to add that yourself.
on *:text:!roll*:#: msg $chan $nick $+ 's roll: $uroll($2-)
on *:input:#: {
if ($1 == !roll) {
msg $active $me $+ 's roll: $uroll($2-)
halt
}
}
alias uroll {
var %formula $1-
var %y $numtok($1-,32)
var %x 0
while (%x < %y) {
inc %x
var %t $gettok($1-,%x,32)
if ($chr(100) isin %t) {
if ($chr(40) isin %t) {
var %t40 $count(%t,$chr(40))
var %t $remove(%t,$chr(40))
}
if ($chr(41) isin %t) {
var %t41 $count(%t,$chr(41))
var %t $remove(%t,$chr(41))
}
var %z1 $gettok(%t,1,100)
var %z2 $gettok(%t,2,100)
var %g 0
var %tot 0
while (%g < %z1) {
inc %g
inc %tot $rand(1,%z2)
}
var %t30 0
while (%t30 < %t40) {
inc %t30
var %tot $+($chr(40),%tot)
}
unset %t40
var %t30 0
while (%t30 < %t41) {
inc %t30
var %tot $+(%tot,$chr(41))
}
unset %t41
var %formula $puttok(%formula,%tot,%x,32)
}
}
var %fin $calc(%formula)
if (%fin > 0) return %fin
else return Check your formula for any errors. All d's must be lowercase, and you cannot be missing parantheses.
}
It does indeed! Of course, Jaytea is a dictator and won't allow any fun in #mSL anyway!
As a side note to Mr. Jaytea: Some of us still recall the original intent of #mSL and I do like to read over the things you type for all of us 'lesser' (used lightly) people regarding the internal functionality and behaviour of scripting with MSL. So, thanks a lot for explaining yourself here and elsewhere ... always a nice treat! :D
The boring part is that the so called reasons are left unexplained.
haha alright. as much as i love 'the sound of my own voice', i just tend to feel a bit silly typing long and technical explanations that people often overlook let alone try to understand. but for you Jethro, i'd be happy to elaborate :P
the space before $1 is actually insignificant, it's the space before $2 that makes the difference. look what $str() produces here:
//tokenize 32 3 3 | echo -a $str(+$r(1, $2), $1)
as you can see, a string of +$r(1, <value of $2>) is generated. in the overall construction $calc( [ $str( ... ) ] ), the evaluation brackets force $str() to evaluate early, and the result is passed to $calc(). it is as if we used the following:
//echo -a $calc( +$r(1, 3)+$r(1, 3)+$r(1, 3) )
which, of course, works properly. but since we're interested in the general case, in which $2 could presumably take on any value, consider what happens if $2 is a larger number, say 1000. +$r(1, 1000) is 12 characters; the length limit imposed on the return value of any identifier is 4,150; thus the maximum value for $1 if we're rolling a 1000 sided dice is floor(4150 / 12) = 345.
in the alternative form, where the space before $2 is eliminated, look what $str() produces instead:
//tokenize 32 3 3 | echo -a $str(+$r(1,$2), $1)
$2 is left unevaluated. +$r(1,$2) is 9 characters, and so $1 can now be up to floor(4150 / 9) = 461 for $1 = 1000.
the increase in the permissible value of $1 is really a side issue (how often do you expect to roll over 300 dice?) - the main disadvantage that including the space has is that it allows code in $2 to be evaluated. for example:
//tokenize 32 3 $!finDfile(.,*,1,$+(echo,$chr(32),oops!)) | echo -a $!1- is $1- | echo -a $calc( [ $str(+$r(1, $2), $1) ] )
this happens because now, as before, it is as if this were used:
//echo -a $calc( +$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!)))+$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!)))+$r(1, $finDfile(.,*,1,$+(echo,$chr(32),oops!))) )
which makes it easier to see what actually happened. that's why i suggested removing the space - i'm quite conscious about providing code that i know to be exploitable :P
no no, the /tokenize was just an example of declaring X and Y :P the meat of it is this:
$calc( [ $str(+$r(1, $2), $1) ] )
which, in general, returns the sum for any (reasonable) X ($1) and Y ($2). i wasn't suggesting you update your code; whenever i point out alternatives it's purely for informative purposes rather than telling scripters they should modify their submission in one way or another :P if you do want to incorporate that little bit, i would suggest the following modification be made:
$calc( [ $str(+$r(1,$2),$1) ] )
(removed the spaces before $2 and $1)
which is better for a couple of reasons that i don't want to bore you with
I've changed the $active for the ON TEXT: to $chan, forgot to do that after testing (I was only in one channel at the time).
As for the tokenizing, I'm not really sure how to implement that since it replaces $1- (in this case, the original input formula) with $1 = number of dice and $2 = sides of the polygon, and since it keeps going back to check in on the original input $1-.... Unless I made another %var of course :P I'm just feeling lethargic at the moment.
If it just went with only one XdY, it could fit it in with minimal problems, but this thing allows you to go like (4d6 + (8d12 - 4d4)) + 2 , etc. lol. I'll get around to it.
ah yes, the ol' "sum of N identically distributed uniform random variables" :P i've wrestled with this in the past, tried to find a generalized closed form approximation for the probability distribution function of XdY for any X and Y. needless to say, i concluded that resorting to summing $r(1, Y) over X iterations was by far the most sane approach to the problem! (see the Irwin-Hall Distribution)
and it's great to see you've avoided the use of regular expressions to locate XdY, it certainly exposes one to clever and more realistic coding techniques ;P realism aside, an example of an alternative to a while loop that can be used once you've identified X and Y is the following:
//tokenize 100 2d20 | echo -a $calc( [ $str(+$r(1, $2), $1) ] )
Champagne, you're well aware that enjoyment of any description is strictly forbidden in #mSL!