File Coverage

blib/lib/Game/PseudoRand.pm
Criterion Covered Total %
statement 88 92 95.6
branch 36 36 100.0
condition 64 74 86.4
subroutine 18 20 90.0
pod 4 4 100.0
total 210 226 92.9


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # returns Pseudo Random Distribution random functions
4              
5             package Game::PseudoRand;
6              
7 3     3   67318 use 5.10.0;
  3         24  
8 3     3   20 use strict;
  3         6  
  3         71  
9 3     3   17 use warnings;
  3         7  
  3         88  
10 3     3   16 use Carp qw(croak);
  3         5  
  3         3283  
11              
12             require Exporter;
13             our @ISA = qw(Exporter);
14             our @EXPORT_OK = qw(prd_bistep prd_step prd_bitable prd_table);
15              
16             our $VERSION = '0.03';
17              
18             sub HIT () { 1 }
19             sub MISS () { 0 }
20              
21             sub prd_bistep {
22 7     7 1 4001 my %param = @_;
23             croak "need start step_hit step_miss values"
24             unless exists $param{start}
25             and exists $param{step_hit}
26 7 100 100     84 and exists $param{step_miss};
      66        
27             croak "rand must be a code ref"
28 3 100 100     28 if defined $param{rand} and ref $param{rand} ne 'CODE';
29 2         3 my $odds = $param{start};
30 2   100 3   13 my $rand = $param{rand} // sub { CORE::rand };
  3         64  
31             ( sub {
32 5 100   5   27 if ( &$rand <= $odds ) { $odds += $param{step_hit}; HIT }
  1         3  
  1         4  
33 4         13 else { $odds += $param{step_miss}; MISS }
  4         23  
34             },
35 0     0   0 sub { $odds = $param{start} }
36 2         37 );
37             }
38              
39             sub prd_step {
40 12     12 1 4614 my %param = @_;
41             croak "requires start and step values"
42             unless exists $param{start}
43 12 100 100     103 and exists $param{step};
44             croak "rand must be a code ref"
45 7 100 100     35 if defined $param{rand} and ref $param{rand} ne 'CODE';
46 6         11 my $odds = $param{start};
47 6   66     18 my $reset = $param{reset} // $odds;
48 6   100 10   31 my $rand = $param{rand} // sub { CORE::rand };
  10         78  
49             ( sub {
50 12 100   12   61 if ( &$rand <= $odds ) { $odds = $reset; HIT }
  4         6  
  4         16  
51 8         21 else { $odds += $param{step}; MISS }
  8         36  
52             },
53 1     1   3 sub { $odds = $param{start} }
54 6         33 );
55             }
56              
57             sub prd_bitable {
58 16     16 1 8725 my %param = @_;
59             croak "need start table_hit table_miss values"
60             unless exists $param{start}
61             and exists $param{table_hit}
62 16 100 100     125 and exists $param{table_miss};
      66        
63             croak "table_hit must be a not-empty array ref"
64             if ref $param{table_hit} ne 'ARRAY'
65 12 100 100     46 or !@{ $param{table_hit} };
  11         40  
66             croak "table_miss must be a not-empty array ref"
67             if ref $param{table_miss} ne 'ARRAY'
68 10 100 100     42 or !@{ $param{table_miss} };
  9         33  
69             croak "rand must be a code ref"
70 8 100 100     39 if defined $param{rand} and ref $param{rand} ne 'CODE';
71 7   100     23 my $idxhit = $param{index_hit} // 0;
72 7   100     23 my $idxmiss = $param{index_miss} // 0;
73 7         9 my $table_hit = [ @{ $param{table_hit} } ];
  7         16  
74 7         13 my $table_miss = [ @{ $param{table_miss} } ];
  7         12  
75 7 100 100     45 croak "index_hit outside of table bounds"
76             if $idxhit < 0 or $idxhit >= @$table_hit;
77 5 100 100     33 croak "index_miss outside of table bounds"
78             if $idxmiss < 0 or $idxmiss >= @$table_miss;
79 3         5 my $odds = $param{start};
80 3   100 13   15 my $rand = $param{rand} // sub { CORE::rand };
  13         52  
81             ( sub {
82 15 100   15   93 if ( &$rand <= $odds ) {
83 7         14 $idxmiss = 0;
84 7         14 $odds += $table_hit->[ $idxhit++ ];
85 7         13 $idxhit %= @$table_hit;
86 7         34 return HIT;
87             } else {
88 8         19 $idxhit = 0;
89 8         16 $odds += $table_miss->[ $idxmiss++ ];
90 8         13 $idxmiss %= @$table_miss;
91 8         42 return MISS;
92             }
93             },
94             sub {
95 0     0   0 $odds = $param{start};
96 0   0     0 $idxhit = $param{idxhit} // 0;
97 0   0     0 $idxmiss = $param{idxmiss} // 0;
98             }
99 3         23 );
100             }
101              
102             sub prd_table {
103 13     13 1 3978 my %param = @_;
104             croak "need start and table values"
105             unless exists $param{start}
106 13 100 66     71 and exists $param{table};
107             croak "table must be a not-empty array ref"
108             if ref $param{table} ne 'ARRAY'
109 12 100 100     49 or !@{ $param{table} };
  11         45  
110             croak "rand must be a code ref"
111 10 100 100     35 if defined $param{rand} and ref $param{rand} ne 'CODE';
112 9   100     27 my $index = $param{index} // 0;
113 9         13 my $table = [ @{ $param{table} } ];
  9         19  
114 9 100 100     50 croak "index outside of table bounds" if $index < 0 or $index >= @$table;
115 7         13 my $odds = $param{start};
116 7   66     18 my $reset = $param{reset} // $odds;
117 7   100 18   36 my $rand = $param{rand} // sub { CORE::rand };
  18         59  
118             ( sub {
119 20 100   20   89 if ( &$rand <= $odds ) { $odds = $reset; $index = 0; HIT }
  8         17  
  8         11  
  8         36  
120 12         25 else { $odds += $table->[ $index++ ]; $index %= @$table; MISS }
  12         23  
  12         47  
121             },
122 2   50 2   5 sub { $odds = $param{start}; $index = $param{index} // 0 }
  2         10  
123 7         41 );
124             }
125              
126             1;
127             __END__