package Dice::Simple;
=head1 NAME
Dice::Simple - a simple module to throw dice
=head1 SYNOPSIS
use Dice::Simple qw(roll);
my $total=roll '3d6'; # simple die roll
print "You threw $total\n";
my @roll=roll '(2d4+d6)/2+20'; # more complicated dice expressio
+n
my ($total, $template, @dice)=@roll;
=head1 DESCRIPTION
There are a number of Dice throwing modules (L<Dice::Dice>, L<RPG::Dic
+e>).
Dice::Dice has an OO interface and allows some interesting possibiliti
+es but
I didn't feel I needed its complexity. This module, Dice::Simple does
+n't
really do anything that RPG::Dice does apart from more flexible dice t
+emplates.
However, if you are going to use the function a lot C<roll> is a lot q
+uicker to
type than C<computeDice> ;->
This was a surprisingly fun wheel to reinvent.
=cut
use strict; use warnings;
BEGIN {
use Exporter;
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
$VERSION = 0.02;
@ISA = qw(Exporter);
@EXPORT = qw();
%EXPORT_TAGS = ();
@EXPORT_OK = qw(roll);
}
=head1 FUNCTIONS
No functions are exported by default. The only function that can be i
+mported is
C<roll>. To do this insert C<use Dice::Simple qw(roll)> at the beginn
+ing of
your script.
If you don't want to import the function you can still call it using
C<Dice::Simple::roll()>.
=over 4
=item C<roll>
Roll takes a dice template corresponding to the standard Role Playing
+Game
dice conventions
d4 4-sided dice
d6 6-sided dice
d100 100-sided dice
Each dice may be optionally prefaced by a number indicating how many t
+imes
to roll the dice.
3d6 Roll 3 six-sided dice, (total between 3 and 18)
And may have a simple arithmetic modifier
2d4+2 Roll 2 four-sided dice, and add 2 to the total
Other arithmetic can be performed using the symbols
+ - * / ( )
for example: (3d6+2d4)/2
And we can optionally choose only the best dice using the notation C<t
+t>
tt3 6d6 Roll 6 six-sided dice and keep the best 3
I<NB:> we are not bound by those troublesome laws of reality we can cr
+eate C<d5>, C<d7> etc.
If called in a scalar context, C<roll> returns the total of the expres
+sion requested.
my $total=roll '2d4+4';
If called in a list context, C<roll> returns
=over 4
=item 1
the sum
=item 2
the template (e.g. the first value passed to C<roll>)
=item 3
the results of each die, in order they were thrown (e.g. as specified
+by the template).
=back
For example, C<2d4 + d6 + 3> might return
(13, "2d4 + d6 + 3", 3, 2, 5)
Total: 13
Template: "2d4 + d6 + 3"
Dice: 3, 2, 5
Note that the dice rolls do not retain any memory of which dice rolled
+ them.
=for undocumented
I<NB:> C<roll> may optionally be passed a list of dice rolls which wil
+l be used
B<in stead> of a randomly rolled integer. No error checking is curren
+tly
done to check that the value passed could have rolled by the dice spec
+ified.
This is not necessarily useful just yet..., however it means that the
+result of
a C<roll> call in list context can be passed back to C<roll> just by s
+hifting
off the result.
=back
=cut
use vars qw(@DICE);
sub roll {
my $template=shift || $_;
@DICE=@_;
my @scores;
(my $dice=$template)=~
s{(?:tt(\d+)\s+)?(\d+)?d(\d+)} # e.g. tt{n}? d4, 3d6, 2d8
{my($tot,@sc) # get total & dice for that role
=_roll($2||1,$3,$1);
push@scores,@sc; # add to overall dice.
$tot # replace #d# expression with tot
+al
}egx; # eg modifiers: apply this functi
+on to
# each occurrence of the #d# pa
+ttern
if ($dice=~/^[0-9+*()\/ -]*$/) { # eval should be safe because onl
+y
my $eval=eval($dice); # accept specified characters
return wantarray ? ($eval, $template, @scores) : $eval
}
undef; # return undef on failure
}
sub _roll {
my ($count, $die, $topn)=@_;
my $total=0;
my @scores=map {shift @DICE || int(rand $die)+1} 1..$count;
if ($topn) { # restrict to best dice only
@scores=(sort {$b<=>$a} @scores)[0..$topn-1]
# In v0.01 I made sure that the dice were returned
# in the order thrown. Don't think this is needed
# so just returning sorted values.
}
$total+=$_ for @scores;
return $total, @scores;
}
=head1 AUTHOR, BUGS, LICENSE
Version: 0.02 7th Dec 2001
Untested. No warranty implied.
May be distributed under the same terms as Perl itself.
(c) hakim@earthling.net
http://www.perlmonks.org /msg osfameron
=cut
int(rand 6)+1;
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
Outside of code tags, you may need to use entities for some characters:
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|