File Coverage

blib/lib/Games/Solitaire/Verify/Freecells.pm
Criterion Covered Total %
statement 63 66 95.4
branch 15 18 83.3
condition n/a
subroutine 17 17 100.0
pod 8 8 100.0
total 103 109 94.5


line stmt bran cond sub pod time code
1             package Games::Solitaire::Verify::Freecells;
2             $Games::Solitaire::Verify::Freecells::VERSION = '0.2401';
3 9     9   62 use warnings;
  9         18  
  9         300  
4 9     9   49 use strict;
  9         22  
  9         240  
5              
6              
7 9     9   48 use parent 'Games::Solitaire::Verify::Base';
  9         21  
  9         42  
8              
9 9     9   558 use Games::Solitaire::Verify::Exception ();
  9         18  
  9         181  
10 9     9   46 use Games::Solitaire::Verify::Card ();
  9         31  
  9         225  
11              
12 9     9   50 use List::Util qw(first);
  9         17  
  9         8543  
13              
14             # _s is the string.
15             __PACKAGE__->mk_acc_ref(
16             [
17             qw(
18             _count
19             _cells
20             _s
21             )
22             ]
23             );
24              
25              
26             sub _input_from_string
27             {
28 272     272   502 my $self = shift;
29 272         474 my $str = shift;
30              
31 272 50       1053 if ( $str !~ m{\AFreecells:}gms )
32             {
33 0         0 Games::Solitaire::Verify::Exception::Parse::State::Freecells->throw(
34             error => "Wrong Freecell String", );
35             }
36              
37             POS:
38 272         604 for my $pos ( 0 .. ( $self->count() - 1 ) )
39             {
40 932 100       3816 if ( $str =~ m{\G\z}cg )
    50          
41             {
42 131         480 last POS;
43             }
44             elsif ( $str =~ m{\G (..)}gms )
45             {
46 801         1798 my $card_s = $1;
47 801         1615 $self->assign( $pos, $self->_parse_freecell_card($card_s) );
48             }
49             else
50             {
51 0         0 Games::Solitaire::Verify::Exception::Parse::State::Freecells
52             ->throw( error => "Wrong Freecell String", );
53             }
54             }
55             }
56              
57             sub _init
58             {
59 286     286   619 my ( $self, $args ) = @_;
60              
61 286 50       682 if ( !exists( $args->{count} ) )
62             {
63 0         0 die "The count was not specified for the freecells";
64             }
65              
66 286         711 $self->_count( $args->{count} );
67              
68 286         1042 $self->_s( 'Freecells:' . ( ' ' x $self->_count ) );
69              
70 286         917 $self->_cells( [ (undef) x $self->_count() ] );
71              
72 286 100       748 if ( exists( $args->{string} ) )
73             {
74 272         703 return $self->_input_from_string( $args->{string} );
75             }
76              
77 14         32 return;
78             }
79              
80             sub _parse_freecell_card
81             {
82 801     801   1545 my ( $self, $s ) = @_;
83              
84             return (
85 801 100       2816 ( $s eq q{ } )
86             ? undef()
87             : Games::Solitaire::Verify::Card->new(
88             {
89             string => $s,
90             }
91             )
92             );
93             }
94              
95              
96             sub count
97             {
98 775     775 1 1284 my $self = shift;
99              
100 775         2648 return $self->_count();
101             }
102              
103              
104             sub cell
105             {
106 3856     3856 1 6699 my ( $self, $idx ) = @_;
107              
108 3856         10678 return $self->_cells()->[$idx];
109             }
110              
111              
112             sub assign
113             {
114 2236     2236 1 4178 my ( $self, $idx, $card ) = @_;
115              
116 2236         5028 $self->_cells()->[$idx] = $card;
117             substr(
118 2236 100       6864 $self->{_s}, length('Freecells:') + ( $idx << 2 ) + 2,
119             2, ( defined($card) ? $card->fast_s : ' ' )
120             );
121              
122 2236         5103 return;
123             }
124              
125              
126             sub to_string
127             {
128 2226     2226 1 10114 ( my $r = $_[0]->{_s} ) =~ s# +\z##;
129 2226         5622 return $r;
130             }
131              
132              
133             sub cell_clone
134             {
135 26     26 1 43 my ( $self, $pos ) = @_;
136              
137 26         46 my $card = $self->cell($pos);
138              
139 26 100       74 return defined($card) ? $card->clone() : undef();
140             }
141              
142              
143             sub clear
144             {
145 578     578 1 1069 my ( $self, $pos ) = @_;
146              
147 578         1524 $self->assign( $pos, undef() );
148              
149 578         1139 return;
150             }
151              
152              
153             sub clone
154             {
155 7     7 1 10 my $self = shift;
156              
157 7         19 my $copy = __PACKAGE__->new(
158             {
159             count => $self->count(),
160             }
161             );
162              
163 7         21 foreach my $pos ( 0 .. ( $self->count() - 1 ) )
164             {
165 26         49 $copy->assign( $pos, $self->cell_clone($pos) );
166             }
167              
168 7         24 return $copy;
169             }
170              
171              
172             sub num_empty
173             {
174 489     489 1 801 my $self = shift;
175              
176 489         837 my $count = 0;
177              
178 489         1191 foreach my $fc_idx ( 0 .. ( $self->count() - 1 ) )
179             {
180 1692 100       2953 if ( !defined( $self->cell($fc_idx) ) )
181             {
182 251         470 ++$count;
183             }
184             }
185 489         1611 return $count;
186             }
187              
188             1; # End of Games::Solitaire::Verify::Freecells
189              
190             __END__