rendered paste body#!/usr/bin/perl -w
use strict;
sub roll { return int(1+rand($_[0])); }
# Interprets expressions like "6x3of4d6+2"
sub dice {
my $spec = shift;
die "bad dice expression" if
$spec !~
m/(?:(\d+)x)? # repeat N times
(?:(\d+)of)? # select top N dice
(?:(\d+))? # count of dice to roll
d(\d+) # die type, only field required
(?:([\-+]\d+))?/x; # add/subtract offset
my ($repeat, $select, $count, $type, $off) = ($1, $2, $3, $4, $5);
if(!defined $repeat or $repeat eq "") { $repeat = 1; }
if(!defined $count or $count eq "") { $count = 1; }
if(!defined $select or $select eq "") { $select = $count; }
if(!defined $off or $off eq "") { $off = 0; }
my @raw_rolls = ();
my @results = ();
for(my $rep=0; $rep<$repeat; $rep++) {
my @rolls = ();
for(my $roll=0; $roll<$count; $roll++) {
my $val = roll($type);
push @raw_rolls, $val;
push @rolls, $val;
}
@rolls = sort {$a<=>$b} @rolls;
for(my $i=$select; $i<$count; $i++) { pop @rolls; }
my $total = $off;
foreach my $r (@rolls) { $total += $r; }
push @results, $total;
}
print "Results:";
foreach my $r (@results) { print " $r"; }
print " (raw rolls:";
foreach my $r (@raw_rolls) { print " $r"; }
print ")\n";
}
foreach my $s (@ARGV) { dice($s); }