#! /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";
}
}