File Coverage

blib/lib/Games/Bingo/Card.pm
Criterion Covered Total %
statement 132 132 100.0
branch 28 28 100.0
condition 2 3 66.6
subroutine 18 18 100.0
pod 4 4 100.0
total 184 185 99.4


line stmt bran cond sub pod time code
1             package Games::Bingo::Card;
2              
3 12     12   27144 use strict;
  12         74  
  12         555  
4 12     12   71 use warnings;
  12         24  
  12         425  
5 12     12   321 use 5.006; #perl 5.6.0
  12         39  
  12         471  
6 12     12   10889 use integer;
  12         123  
  12         76  
7 12     12   369 use vars qw($VERSION);
  12         27  
  12         607  
8 12     12   8360 use Games::Bingo::Column;
  12         35  
  12         340  
9 12     12   11177 use Games::Bingo::ColumnCollection;
  12         33  
  12         412  
10 12         15695 use Games::Bingo::Constants qw(
11             NUMBER_OF_NUMBERS_IN_CARD
12             NUMBER_OF_COLUMNS_IN_CARD
13             NUMBER_OF_ROWS_IN_CARD
14             NUMBER_OF_NUMBERS_IN_ROW
15             NUMBER_OF_NUMBERS
16 12     12   69 );
  12         20  
17              
18             $VERSION = '0.17';
19              
20             sub new {
21 13     13 1 7749 my ($class) = @_;
22            
23 13         53 my $self = bless [], $class;
24            
25 13         49 return $self;
26             }
27              
28             sub get_all_numbers {
29 181     181 1 212 my $self = shift;
30            
31 181         328 my @numbers = ();
32 181         215 foreach my $row (@{$self}) {
  181         316  
33 1620         1512 foreach my $number (@{$row}) {
  1620         2556  
34 3727 100       10322 push(@numbers, $number) if $number;
35             }
36             }
37 181         495 return @numbers;
38             }
39              
40             sub validate {
41 3     3 1 18 my ($self, $bingo) = @_;
42            
43 3         4 my $rv = 0;
44 3         5 my $trv = NUMBER_OF_NUMBERS_IN_CARD;
45            
46 3 100       9 if ($bingo->{game}) {
47 2         6 my @numbers = $self->get_all_numbers();
48            
49 2         6 foreach my $number (@numbers) {
50 30 100       93 ++$rv if $bingo->pulled($number);
51             }
52 2         7 $trv = NUMBER_OF_NUMBERS_IN_CARD;
53             } else {
54 1         61 warn "bingo game not defined?\n";
55             }
56            
57 3 100       10 if ($rv == $trv) {
58 1         4 $bingo->{game}--;
59 1         18 return 1;
60             } else {
61 2         15 return 0;
62             }
63             }
64              
65             sub _print_card {
66 1     1   7 my $self = shift;
67              
68 1         1 my $row = 0;
69 1         6 for (my $m = 0; $m < 7; $m++) {
70 7         11 my $column = 0;
71            
72 7 100       28 if ($m%2) {
73 3         13 for (my $n = 1; $n < 20; $n++) {
74 57 100       142 if ($n%2) {
75 30         854 print "|";
76             } else {
77 27 100       59 if ($self->[$column][$row]) {
78 15         428 printf("%2d",$self->[$column][$row]);
79             } else {
80 12         294 print " ";
81             }
82 27         92 ++$column;
83             }
84             }
85 3         6 $row++;
86             } else {
87 4         12 for (my $n = 1; $n < 20; $n++) {
88 76 100       130 if ($n%2) {
89 40         1131 print "+";
90             } else {
91 36         889 print "--";
92             }
93             }
94             }
95 7         1116 print "\n";
96             }
97 1         12 return 1;
98             }
99              
100             sub _insert {
101 2682     2682   11927 my ($self, $row, $number) = @_;
102            
103 2682         4437 my $column = $self->_resolve_column($number);
104 2682         18250 $self->[$column]->[$row] = $number;
105              
106 2682         8803 return 1;
107             }
108              
109             sub _integrity_check {
110 179     179   246 my ($self) = @_;
111            
112 179         244 my $rv = NUMBER_OF_NUMBERS_IN_CARD;
113 179         205 foreach my $row (@{$self}) {
  179         314  
114 1611         1590 foreach my $cell (@{$row}) {
  1611         2608  
115 3699 100 66     16118 if ($cell and $cell =~ m/^\d+$/o) {
116 2267         4704 $rv--;
117             }
118             }
119             }
120 179 100       437 if ($rv != 0) {
121 171         516 return 0;
122             } else {
123 8         38 return 1;
124             }
125             }
126              
127             sub _resolve_column {
128 2772     2772   46948 my ($self, $number) = @_;
129            
130 2772         3099 my $result = ($number / 10);
131 2772         8994 my ($column) = $result =~ m/^(\d{1})$/o;
132            
133 2772 100       6987 if ($result < 1) { #ones go in column 0
    100          
134 299         356 $column = 0;
135             } elsif ($result == NUMBER_OF_COLUMNS_IN_CARD) { #9 go in column 8
136 23         33 $column = 8;
137             }
138 2772         5662 return $column;
139             }
140              
141             sub _init {
142 178     178   317 my ($self) = @_;
143            
144 178         215 my @numbers;
145 178         704 my $bingo = Games::Bingo->new();
146 178         576 $bingo->init(\@numbers, NUMBER_OF_NUMBERS);
147              
148             #Creating the numeric set to pick from
149 178         642 my $temp_collection = Games::Bingo::ColumnCollection->new();
150 178         729 $temp_collection->divide(NUMBER_OF_COLUMNS_IN_CARD, @numbers);
151            
152 178         708 my $final_collection = Games::Bingo::ColumnCollection->new();
153            
154             #Getting the first 9 numbers
155 178         651 for (my $i = 0; $i < NUMBER_OF_COLUMNS_IN_CARD; $i++) {
156 1602         3792 my $c = $temp_collection->get_column($i);
157 1602         4910 my $n = $c->get_random_number(1);
158              
159 1602         4441 my $fc = Games::Bingo::Column->new($i);
160 1602         4007 $fc->populate($n);
161            
162 1602         4296 $final_collection->add_column($fc);
163             }
164              
165             #Getting the 3 extras so we have 12 numbers
166 178         447 for (my $i = NUMBER_OF_NUMBERS_IN_CARD
167             - NUMBER_OF_COLUMNS_IN_CARD; $i > 0; $i--) {
168 1068         2774 my $tc = $temp_collection->get_random_column(1);
169 1068         5628 my $n = $tc->get_random_number(1);
170 1068         1712 my $label = $tc->{label};
171            
172 1068         2478 my $fc = $final_collection->get_column($label);
173            
174 1068         2567 $fc->populate($n);
175             }
176 178         2039 return $final_collection;
177             }
178              
179             sub populate {
180 6     6 1 42 my ($self) = @_;
181              
182 176         437 HACK:
183            
184             my $fcc = $self->_init();
185            
186 176         557 for (my $row = NUMBER_OF_ROWS_IN_CARD-1; $row >= 0; $row--) {
187 528         1545 my $tcc = Games::Bingo::ColumnCollection->new();
188              
189 528         1440 for (my $i = NUMBER_OF_NUMBERS_IN_ROW; $i > 0; $i--) {
190              
191 2640         8331 my $c = $fcc->get_random_column(1);
192 2640         6528 my $number = $c->get_highest_number(1);
193            
194 2640 100       11593 if ($c->count_numbers() > 0) {
195 1056         2649 $fcc->add_column($c);
196             } else {
197             #implicitly discarding empty columns
198             }
199 2640         5471 $self->_insert($row, $number);
200             }
201 528         4527 foreach my $column (@${fcc}) {
202 1904         4670 $tcc->add_column($column);
203             }
204 528         1836 $fcc = $tcc;
205             }
206 176         427 my $amount = scalar $self->get_all_numbers();
207            
208 176 100       476 unless ($self->_integrity_check) {
209            
210 170         17442 warn "Incomplete trying again... ($amount)\n";
211            
212             #if the integrity check fails, meaning we don not have
213             #enough numbers to print a card we simply try again,
214             #please refer to the BUGS file or the B section below.
215            
216 170         648 $self = $self->_flush;
217            
218 170         658 goto HACK;
219             }
220 6         39 return $self;
221             }
222              
223             sub _flush {
224 171     171   254 my $self = shift;
225            
226 171         220 @{$self} = ();
  171         862  
227            
228 171         343 return $self;
229             }
230              
231             1;
232              
233             __END__