mIRC Home    About    Download    Register    News    Help

Print Thread
#211249 09/04/09 10:04 AM
Joined: Jan 2005
Posts: 25
L
Ameglian cow
OP Offline
Ameglian cow
L
Joined: Jan 2005
Posts: 25
so I created a dice script for script which rolls a number of d10s, then sorts it based on 7 or above being a success, with double successes for 10s, and botches for 1s (this couldn't possibly be for white wolf, no sir, not possible).

all in all, its a decent script, even with my less than decent scripting knowledge.

it works perfectly fine, but while we were testing it (and trying to break it) we found a flaw.

It will roll any number of dice from 1 die to 445 dice. but 446 or more dice won't work.

that is way beyond the number of dice that will actually be used in any situation we are going to use the script, but it still bugs me that it stops at 445 for some reason I cannot see.

Code:
/exalt {
  ; $$1 is channel
  ; $$2 is number of rolls
  var %RAW.ROLL
  var %d = $$2
  while (%d > 0) {
    %RAW.ROLL = [ %RAW.ROLL ] $rand(1,10)
    dec %d
  }
  %NUM.SUCCESS = $count(%RAW.ROLL,7,8,9,10)
  %NUM.CRIT = $count(%RAW.ROLL,10)
  %NUM.FAILURE = $calc($$2 - %NUM.SUCCESS)
  %NUM.BOTCH = $findtok(%RAW.ROLL,1,0,32)
  %TOTAL.SUCCESS = $calc(%NUM.SUCCESS + %NUM.CRIT)
  %CUT1.ROLL = $deltok(%RAW.ROLL,11 - $$2,32)
  %CUT2.ROLL = $deltok(%RAW.ROLL,1 - $calc($$2 - 10),32)
  if $$2 <= 30 {
    msg $$1 Failure: %NUM.FAILURE $+ / $+ $$2 Botch: %NUM.BOTCH Success: %NUM.SUCCESS $+ / $+ $$2 Critcal: %NUM.CRIT TOTAL SUCCESS: %TOTAL.SUCCESS $+ / $+ $$2 Raw Roll ( $+ %RAW.ROLL $+ )
    halt
  }
  if $$2 > 30 {
    ; Displays the first ten and the last ten numbers
    msg $$1 Failure: %NUM.FAILURE $+ / $+ $$2 Botch: %NUM.BOTCH Success: %NUM.SUCCESS $+ / $+ $$2 Critcal: %NUM.CRIT TOTAL SUCCESS: %TOTAL.SUCCESS $+ / $+ $$2 Raw Roll ( $+ %CUT1.ROLL $+ ... $+ %CUT2.ROLL $+ )
    halt
  }
}


its an ugly bastard child of mine, but can someone see if its anything I did to make it stop at 446+? or is this just something inherent to mirc?

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
The problem is that you try to set a very long string in a single variable (%RAW.ROLL).

The limits for a variable (length of variable name + length of data):
- mIRC v6.31 and below: ~940 chars.
- mIRC v6.32 and above: ~4150 chars.

Do you need/use the results string (individual results of every roll) at all, except for calculating failure/botch/success etc?

If you don't:
The following doesn't store a list of rolls - it's processing the result for each roll right after that roll.
The examples may look a bit confisung at first glance. Don't worry! smile
Code:
/*
Syntax: $dice(R [,DN] [,SN] [,CN]) [.sum|success|failed|critical|botch]


--- Parameters ---
R = number of rolls (number of dices)
D = number of sides of the dices. 
S = lowest side for a successful roll. 
C = lowest side for a critical roll. 

You have to provide R, all other parameters are optional.
The D, S and C parameters don't have to be in order. N represents a positive integer.

If you don't provide D, S or C, the following defaults will be used:
if no D is given, a D10 is used
if no S (where N <=D) is given, a roll of (D/2 +1, rounded up to the next integer) is regarded a successful roll
	(for D3 = 2+, for a D3-D4 = 3+, for a D5-6 = 4+, and so on)
if no C (where N <= D) is given, a roll is critical only if he is = D

Examples: 
$dice(5) will return the sum of 5D10
$dice(2,D3) will return the sum of a 2D3


--- Properties ---
All properties are optional. Properties don't have to be in order.

sum = sum of the rolls (same as using no property at all)
success = number of successful rolls
failed = number of failed rolls (= total rolls - successfull rolls)
critical = number of critical rolls
botch = number of botch rolls

Examples:
$dice(8,D5).success = number of successful rolls of a 8D5 (using default success value where a roll of 5+ is regarded "success")
$dice(8,D5,S6).success = number of successful rolls of a 8D5, where a roll of 6+ is regarded "success"
$dice(4).failed = number of failed rolls of a 4D10 (using default values for D and success, where for a D10 a roll of 5- is regarded "failure")
$dice(3,D3).critical = number of critical rolls of a 3D3 (using default critical value = 3)
$dice(10,D9,C7).critical = number of critical rolls of a 10D9, where a roll of 7+ is regarded "critical"
$dice(5).botch = number of botches of a 5D10

You can combine all properties as you like, separate multiple properties by comma.
Examples:
"$dice(7).success,critical" > will for a 7D10 return: <successful rolls>,<critical rolls>
"$dice(8,S7,D8).sum,failed,botch" > will for a 8D8 return: <sum of rolls>,<failed rolls, where 6- is regarded "failure">,<botch rolls>
"$dice(3,D9,C8).critical,success" > will for a 3D9 return:
	<critical rolls, where 8+ is regarded "critical">,<successfull rolls, where for a D9  6+ is regarded "success")
*/


alias dice {
  if (($isid) && ($$1 isnum 1-)) {
    var %n = $int($1), %sum, %success = 0, %critical = 0, %botch = 0

    ; parse parameters
    var %d = $iif(($int($mid($wildtok($1-,D*,1,32),2-)) isnum 1-),$v1,10)
    var %s = $iif((($int($mid($wildtok($1-,S*,1,32),2-)) isnum 1-) && ($v1 <= %d)),$v1,$ceil($calc(%d / 2 $iif((%d > 1),+ 1))))
    var %c = $iif((($int($mid($wildtok($1-,C*,1,32),2-)) isnum 1-) && ($v1 < %d)),$v1,%d)

    ; roll the dices!
    var %r = 1
    while (%r <= %n) {
      var %x = $rand(1,%d)
      inc %sum %x
      if (%x = 1) { inc %botch }
      if (%x >= %s) { inc %success }
      if (%x >= %c) { inc %critical }
      inc %r
    }
    var %failed = $calc(%n - %success)

    ; parse properties
    var %return = $regsubex($prop,/(?<=^|\54)(sum|success|failed|critical|botch)(?=$|\54)/ig, $var(\1,1).value)

    ; return the requested result
    return $iif($regml(0),%return,%sum)
  }
}


If you want to create a channel message like yours with this custom identifier:
Code:
; /exalt #channel <number of D10 rolls>
alias exalt {

  var %chan = $1

  ; call the $dice identifier with $2 = the number of rolls, and request the output of failed/botch/success/critical
  ; instead of using a lot of $gettok, fill the $N identifiers with the returned result, so that $1 = failed, $2 = botch etc
  tokenize 44 $dice($$2,S7).failed,botch,success,critical

  msg %chan Failure: $1 Botch: $2 Success: $3 Critical: $4  Total success: $calc($3 + $4)
}


Both aliases are meant to be remotes.

Edit: fixed some typo

Last edited by Horstl; 09/04/09 01:57 PM.
Horstl #211269 10/04/09 03:52 AM
Joined: Jan 2005
Posts: 25
L
Ameglian cow
OP Offline
Ameglian cow
L
Joined: Jan 2005
Posts: 25
after some nice reading on my part, I managed to understand every part of that save for the very end, the regex parts. But thats more my failure to understand regex in general than any fault on your code ^^

Your examples were far from confusing, imo, they were clear cut and without them I would have needed much more time to figure out what you were doing.

As for the results string, I don't really need it no, its just there for cosmetic reasons, you know, kind of nice to see what you're rolled rather than just the pure numbers of it. sort of a talking point amongst friends, laughing at the numbers as it were.

We might know a 9 is just as likely as a 7, but we still think its better laugh

Originally, the way mine was set up it would only display 30 dice max, any more than that and it would cut it and only display the first ten rolls and the last ten rolls.

maybe add in something during the rolling process that saves the first 30, and if there are more than thirty, it would only show 30 dice then ... ?

I'm gonna screw around with what you've got, as its much prettier than mine, certainly better written, and see if I cant get something to work.

either way, thanks for your help

Joined: Jan 2005
Posts: 25
L
Ameglian cow
OP Offline
Ameglian cow
L
Joined: Jan 2005
Posts: 25
....ok, did some testing and got some intresting results

Quote:
/exalt #dicebot 10
<DiceBot> Failure: 50 Botch: Success: Critical: Total success: 0
/exalt #dicebot 20
<DiceBot> Failure: 109 Botch: Success: Critical: Total success: 0
//msg #dicebot Test: $dice(5).success
<DiceBot> Test: 17


50 failures with 10 dice, 109 failures with 20 dice, and 17 successes with 5 dice...

something is fishy oO

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Hm, though I'm not able to reproduce your problem with the alias, I modified some parts in this version:
- a property "string" has been added which will make the alias store and return the (max. 50 first) results
- properties r,d,s and c added (...just as the values are already there, and to compare the input to the values actually used)
- "R" is now optional too. If no valid R is provided, a single dice is used.
- some brackets in the while loop have been removed, to slightly improve the performance. Though it won't be noticeable for a "normal" R value, it compensates a bit for the "create a string" thing.
Code:
/*
$dice(R [,DN] [,SN] [,CN]) [.sum|success|failed|critical|botch|string|r|d|s|c]

--- Parameters ---
R = number of rolls (number of dice)
D = number of sides of the dice (type of dice)
S = lowest side of the dice to be regarded a "successful" roll
C = lowest side of the dice to be regarded a "critical" roll

All parameters are optional.
If used, R has to be a positive integer and the first parameter.
The D, S and C parameters consist of the indicating letter followed by a positive integer N. They don't have to be in order.

If you don't provide R, D, S, or C, the following defaults will be used:
- if no R is given, a single dice is used (R = 1)
- if no D is given, a 10-sided dice is used (D = 10)
- if no S (with N <= D) is given, a roll is regarded successful if it's equal to or biger than [D / 2 + 1, rounded up to the next integer]
- 	(the default S for D2 is 2, for D3-D4 it's 3, for D5-D6 it's 4 etc)
- if no C (with N <= D) is given, a roll is regarded critical if it has the highest possible result (that is: D)

Examples: 
$dice() will return the sum of a 1D10
$dice(5) will return the sum of a 5D10
$dice(2,D3) will return the sum of a 2D3


--- Properties ---
All properties are optional. Properties don't have to be in order.

sum = sum of the rolls (same as using no property at all)

success = number of successful rolls
failed = number of failed rolls (= total rolls - successful rolls)
critical = number of critical rolls
botch = number of botch rolls

string = space-delimited string of the individual dice results. If you use STRING (uppercase), results will be zeropadded to the length of D.
	The string will hold no more than the 50 first results.

r = number of rolls performed (e.g. if no valid R specified)
d = number of sides of the dice used (e.g. if no valid D specified)
s = value used as success threshold (e.g. if no valid S specified)
c = value used as success threshold (e.g. if no valid C specified)

	The r,d,s and c properties are most of all for convenience

Examples:
$dice() = sum of a default roll with a default dice (a 1D10)
$dice(8,D5).success = number of successful rolls of a 8D5 (using default success value where a roll of 5+ is regarded "success")
$dice(8,D5,S6).success = number of successful rolls of a 8D5, where a roll of 6+ is regarded "success"
$dice(4).failed = number of failed rolls of a 4D10 (using default values for D and success, where for a D10 a roll of 5- is regarded "failure")
$dice(3,D3).critical = number of critical rolls of a 3D3 (using default critical value = 3)
$dice(10,D9,C7).critical = number of critical rolls of a 10D9, where a roll of 7+ is regarded "critical"
$dice(5).botch = number of botches of a 5D10
$dice(10,D6).string = a string of the individual results of a 10D6
$dice().d = default D value (10)
$dice().s = default S value for a default D roll (= 6 for a default D10)

You can use multiple properties, separated by comma. The results will be separated by comma. Examples:
"$dice(7).success,critical" will for a 7D10 return: <successful rolls>,<critical rolls>
"$dice(8,S7,D8).sum,failed,botch" will for a 8D8 return: <sum of rolls>,<failed rolls, where 6- is regarded "failure">,<botch rolls>
"$dice(3,D9,C8).critical,success" will for a 3D9 return:
	<critical rolls, where 8+ is regarded "critical">,<successfull rolls, where for a D9  6+ is regarded "success")
"$dice(D4,C6).c,critical" will for a 1D4 return:
	<default critical threshold of a D4 (the invalid "C6" is ignored as it's bigger than D)>,
	<critical rolls of the 1D4, using the default 3 as threshold>
*/


alias dice {
  if ($isid) {
    var %sum = 0, %success = 0, %critical = 0, %botch = 0, %string, %n = 1

    ; parse parameters
    var %r = $iif(($int($1) isnum 1-),$v1,1)
    var %d = $iif(($int($mid($wildtok($1-,D*,1,32),2-)) isnum 1-),$v1,10)
    var %s = $iif((($int($mid($wildtok($1-,S*,1,32),2-)) isnum 1-) && ($v1 <= %d)),$v1,$ceil($calc(%d / 2 $iif((%d > 1),+ 1))))
    var %c = $iif((($int($mid($wildtok($1-,C*,1,32),2-)) isnum 1-) && ($v1 < %d)),$v1,%d)

    ; parse properties (1) - create a (zeropadded) string of results?
    var %mkstring = $iif(($wildtok($prop,string,1,44)),$iif(($v1 isupper),$len(%d),1))

    ; roll the dice: count sum and events, make string if desired
    while (%n <= %r) {
      var %x = $rand(1,%d)
      inc %sum %x
      if (%x == 1) inc %botch
      if (%x >= %s) inc %success
      if (%x >= %c) inc %critical
      if (%mkstring) && ($numtok(%string,32) < 50) var %string = %string $iif((%mkstring < 2),%x,$base(%x,10,10,$v1))
      inc %n
    }
    var %failed = %r - %success

    /*
    parse properties (2) - every valid property is substituted with the value of the variable that has the name of this property
    (?<=^|\54) means "the match following is at the start of the string, or preceded by a octal 54 = comma"
    (?=$|\54) means "the match preceding is at the end of the string, or followed by a octal 54 = comma"
    x|y|z is a "or-list" of possible matches, the rounded brackets capture the match. "\1" in the substitution part is the match just captured
    */
    var %return = $regsubex($prop,/(?<=^|\54)(sum|success|failed|critical|botch|string|r|d|s|c)(?=$|\54)/ig, $var(\1,1).value)

    ; return the result acc. to properties, or the sum if no property was substituted (used)
    return $iif($regml(0),%return,%sum)
  }
}


I used this alias for testing and never had strange/contradictionary results. If you have weird results again, run some tests with it:
Code:
; /dicetest [No. of dice] [No. of sides per dice] [success threshold] [critical threshold]
alias dicetest {
  ; values passed to the alias
  ECHO -ag Input: $iif($1,Dice: $1) $iif($2,Sides per dice: $2) $iif($3,Success at: $3) $iif($4,Critical at: $4)

  ; calling the alias
  tokenize 44 $dice($1,D $+ $2,S $+ $3,C $+ $4).r,d,s,c,success,failed,critical,botch,string

  ; values returned by the alias
  ECHO -ag $1 Dice used, $2 Sides per dice. Conditions: Success at $3 Critical at $4
  ECHO -ag Result: Successful $5 Failed $6 Critical $7 Botch $8
  ECHO -ag Raw roll: $replace($9,$chr(32),...)
  ECHO -ag $str(-,50)
}


Link Copied to Clipboard