#! /usr/bin/perl -w srand; # Usage: roll [specifier] . . . # [specifier] is MxXdY/Z{+,-}N, where M, X, Y, Z, and N are nonnegative # integers, and Z <= X. Computes M random numbers between (X-Z)±N and # (X-Z)Y±N, inclusive. Rolls X Y-sided dice, drops the lowest Z, then # adds N. Useful for RPGs or other games that involve dice. # # Mx, X, /Z, ±N, or any combination thereof may be omitted. for (@ARGV) { if(! /^(?:([0-9]+)x)?([0-9]+)?d([0-9]+)(?:\/([0-9]+))?(?:([+-])([0-9]+))?$/) { print <<"EOF"; Bad specifier: $_ Specifiers are of the form XdY, optionally followed by /Z, +N, or -N, and optionally proceeded by Mx. X, Y, Z, M, and N are nonnegative integers; if given, Z must be less than or equal to X. Only one of +N or -N may be given; if /Z is given along with +N or -N, /Z most come first. Z and N default to zero if not specified. M and X default to 1 if not specified Rolls X Y-sided dice, drops the Z lowest, and finally adds or subtracts the constant N. Do this M times, showing the result from each such roll. EOF exit 1; } $times = defined($1) ? $1 : 1; $rolls = defined($2) ? $2 : 1; $drop = defined($4) ? $4 : 0; $bonus = defined($6) ? $5 eq "-" ? -$6 : $6 : 0; $type = $3; die "cannot drop $drop dice of $rolls in $_" if($drop > $rolls); for (1..$times) { @rolled = (); $val = 0; for (1..$rolls) { push @rolled,(int rand($type)) + 1; } @rolled = sort {$a <=> $b} @rolled; for(1..$drop){shift @rolled}; for(@rolled){$val += $_}; $val += $bonus; print "$_: $val\n"; } }