File Coverage

blib/lib/Acme/Dice.pm
Criterion Covered Total %
statement 65 71 91.5
branch 41 48 85.4
condition 17 23 73.9
subroutine 11 12 91.6
pod 2 2 100.0
total 136 156 87.1


line stmt bran cond sub pod time code
1             package Acme::Dice;
2              
3 3     3   80786 use 5.008008;
  3         12  
  3         137  
4 3     3   18 use strict;
  3         8  
  3         121  
5 3     3   16 use warnings;
  3         10  
  3         187  
6              
7 3     3   16 use Carp;
  3         6  
  3         327  
8 3     3   3725 use Data::Dumper;
  3         44112  
  3         253  
9              
10             BEGIN {
11 3     3   31 use Exporter ();
  3         6  
  3         72  
12 3     3   16 use vars qw(@ISA @EXPORT_OK);
  3         5  
  3         277  
13 3     3   62 @ISA = qw(Exporter);
14              
15 3         2911 @EXPORT_OK = qw( roll_dice roll_craps );
16             }
17              
18             $Acme::Dice::VERSION = '1.01';
19              
20             my $defaults = {
21             dice => 1,
22             sides => 6,
23             favor => 0,
24             bias => 20,
25             };
26              
27             sub roll_dice {
28 4326 50   4326 1 74340 my $raw_args = @_ == 1 ? shift : {@_};
29              
30             # no need to check params if coming from roll_craps
31 4326 100       16312 my $args =
32             delete( $raw_args->{skip_validate} )
33             ? $raw_args
34             : _validate_params($raw_args);
35              
36 4293         4534 my @rolls;
37 4293         5379 my $roll_total = 0;
38 4293         10471 for ( 1 .. $args->{dice} ) {
39 9305         15866 my $roll = ( int( rand( $args->{sides} ) ) + 1 );
40 9305 50 66     22503 _apply_bias( \$roll, $args ) if $args->{favor} && $args->{bias};
41 9305         11118 push( @rolls, $roll );
42 9305         18680 $roll_total += $roll;
43             }
44              
45 4293 100       21777 return wantarray ? @rolls : $roll_total;
46             }
47              
48             sub roll_craps {
49 368 50   368 1 22418 my $raw_args = @_ == 1 ? shift : {@_};
50              
51 368 100 100     1385 croak "param present but undefined: bias"
52             if exists( $raw_args->{bias} ) && !defined( $raw_args->{bias} );
53              
54 367   100     1104 my $bias = delete( $raw_args->{bias} ) || 0;
55              
56 367 100 100     1660 croak "Illegal value for 'bias': $bias" if $bias < 0 || $bias > 100;
57 4         1008 croak 'RTFM! Unknown params: ' . join( ', ', keys( %{$raw_args} ) )
  365         903  
58 365 100       328 if keys( %{$raw_args} );
59              
60             # hey, this is Acme, remember? you were TOLD not to look inside!
61 361 50       941 return ( wantarray ? ( 3, 4 ) : 7 ) if rand(100) < 5;
    100          
62              
63 337         312 my @rolls;
64 337         540 push(
65             @rolls,
66             roll_dice(
67             skip_validate => 1,
68             dice => 1,
69             sides => 6,
70             favor => 3,
71             bias => $bias
72             )
73             );
74 337         563 push(
75             @rolls,
76             roll_dice(
77             skip_validate => 1,
78             dice => 1,
79             sides => 6,
80             favor => 4,
81             bias => $bias
82             )
83             );
84              
85 337 100       1912 return wantarray ? @rolls : $rolls[0] + $rolls[1];
86             }
87              
88             sub _validate_params {
89 3652 50   3652   15212 my $raw_args = @_ == 1 ? shift : {@_};
90              
91 3652         4340 my $args = {};
92 3652         4089 my @errors;
93              
94             # put put defaults in place for missing params
95             # and detect incoming undefined params
96 3652         4151 for ( keys( %{$defaults} ) ) {
  3652         9874  
97 14608 100       60200 $raw_args->{$_} = $defaults->{$_} if !exists( $raw_args->{$_} );
98 14608 100       29062 push( @errors, "param present but undefined: $_" )
99             unless defined $raw_args->{$_};
100 14608         25572 $args->{$_} = delete( $raw_args->{$_} );
101 14608 100 100     120322 push( @errors, "$_ must be a non-negative integer: $args->{$_}" )
102             if defined( $args->{$_} ) && $args->{$_} !~ m/^\d+$/;
103             }
104 1         5 push( @errors,
105 3652         10725 'RTFM! Unknown params: ' . join( ', ', keys( %{$raw_args} ) ) )
106 3652 100       7198 if keys( %{$raw_args} );
107              
108 3652 100       11166 croak join( "\n", @errors ) if @errors;
109              
110             # validate individual params now
111 3635 100       10747 push( @errors, "Illegal value for 'dice': $args->{dice}" )
112             if $args->{dice} < 1;
113 3635 100       7277 push( @errors, "Really? Roll $args->{dice} dice?" ) if $args->{dice} > 100;
114              
115 3635 100       6797 push( @errors, "Illegal value for 'sides': $args->{sides}" )
116             if $args->{sides} < 1;
117              
118 3635 100 66     16904 push( @errors, "Illegal value for 'favor': $args->{favor}" )
119             if $args->{favor} < 0 || $args->{favor} > $args->{sides};
120 3635 100 66     14441 push( @errors, "Illegal value for 'bias': $args->{bias}" )
121             if $args->{bias} < 0 || $args->{bias} > 100;
122              
123 3635 100       9704 croak join( "\n", @errors ) if @errors;
124              
125 3619         8721 return $args;
126             }
127              
128             sub _apply_bias {
129 0     0     my $roll_src = shift;
130 0           my $args = shift;
131              
132 0           ${$roll_src} = $args->{favor}
  0            
133 0 0 0       if ${$roll_src} != $args->{favor} && rand(100) < $args->{bias};
134              
135 0           return;
136             }
137              
138             1;
139             __END__