package Games::Dice; use strict; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. @EXPORT_OK = qw( roll roll_array roll_whitewolf ); $VERSION = '0.02'; # Preloaded methods go here. sub roll ($) { my($line, $dice_string, $sign, $offset, $sum, @throws, @result); $line = shift; return undef unless $line =~ m{ ^ # beginning of line ( # dice string in $1 (?:\d+)? # optional count [dD] # 'd' for dice (?: # type of dice: \d+ # either one or more digits | # or % # a percent sign for d% = d100 ) ) (?: # grouping-only parens ([-+xX*/bB]) # a + - * / b(est) in $2 (\d+) # an offset in $3 )? # both of those last are optional }x; # whitespace allowed $dice_string = $1; $sign = $2 || ''; $offset = $3 || 0; $sign = lc $sign; @throws = roll_array( $dice_string ); return undef unless @throws; if( $sign eq 'b' ) { $offset = 0 if $offset < 0; $offset = @throws if $offset > @throws; @throws = sort { $b <=> $a } @throws; # sort numerically, descending @result = @throws[ 0 .. $offset-1 ]; # pick off the $offset first ones } else { @result = @throws; } $sum = 0; $sum += $_ foreach @result; $sum += $offset if $sign eq '+'; $sum -= $offset if $sign eq '-'; $sum *= $offset if ($sign eq '*' || $sign eq 'x'); do { $sum /= $offset; $sum = int $sum; } if $sign eq '/'; return $sum; } sub roll_array ($) { my($line, $num, $type, @throws); $line = shift; return undef unless $line =~ m{ ^ # beginning of line (\d+)? # optional count in $1 [dD] # 'd' for dice ( # type of dice in $2: \d+ # either one or more digits | # or % # a percent sign for d% = d100 ) }x; # whitespace allowed $num = $1 || 1; $type = $2; $type = 100 if $type eq '%'; @throws = (); for( 1 .. $num ) { push @throws, int (rand $type) + 1; } return @throws; } sub roll_whitewolf { my ($pool, $diff, $crits) = @_; my @rolls; my $successes = 0; my $tens = 0; return undef if (!$pool || !$diff); @rolls = roll_array($pool . 'd10'); foreach (@rolls){ if ($_ == 1){ $successes--; $tens-- if ($tens > 0); } elsif ($_ >= $diff){ $successes++; $tens++ if ($_ == 10); } } if ($crits && $tens != 0) { $successes += roll_whitewolf($tens, $diff, ''); } return $successes; } 1; #### #!/usr/bin/perl use strict; use warnings; use Games::Dice 'roll', 'roll_array', 'roll_whitewolf'; print roll_whitewolf(10, 8, 'yes'); #### "roll_whitewolf" is not exported by the Games::Dice module Can't continue after import errors at dice.test.pl line 4 BEGIN failed--compilation aborted at dice.test.pl line 4.