File Coverage

blib/lib/Games/Solitaire/Verify/Card.pm
Criterion Covered Total %
statement 78 78 100.0
branch 20 20 100.0
condition n/a
subroutine 21 21 100.0
pod 12 12 100.0
total 131 131 100.0


line stmt bran cond sub pod time code
1             package Games::Solitaire::Verify::Card;
2             $Games::Solitaire::Verify::Card::VERSION = '0.2601';
3 28     28   357647 use warnings;
  28         53  
  28         1976  
4 28     28   191 use strict;
  28         95  
  28         843  
5              
6              
7 28     28   474 use parent 'Games::Solitaire::Verify::Base';
  28         276  
  28         184  
8              
9 28     28   4640 use Games::Solitaire::Verify::Exception ();
  28         79  
  28         35145  
10              
11             __PACKAGE__->mk_acc_ref(
12             [
13             qw(
14             _flipped
15             _s
16             data
17             id
18             rank
19             suit
20             _game
21             )
22             ]
23             );
24              
25              
26             sub _recalc
27             {
28 23438     23438   38987 my ($self) = @_;
29              
30 23438         42461 $self->_s( $self->to_string() );
31              
32 23438         40351 return;
33             }
34              
35             sub _card_num_normalize
36             {
37 364     364   533 my $arg = shift;
38              
39 364 100       666 if ( ref($arg) eq "" )
40             {
41 336         512 return +{ map { $_ => $arg } (qw(t non_t)) };
  672         1627  
42             }
43             else
44             {
45 28         75 return $arg;
46             }
47             }
48              
49             my @card_nums = (
50             map { _card_num_normalize($_) } (
51             "A",
52             ( 2 .. 9 ),
53             {
54             't' => "T",
55             'non_t' => "10",
56             },
57              
58             "J", "Q",
59             "K"
60             )
61             );
62              
63             my %ranks_map =
64             ( map { $card_nums[$_]->{t} => ( $_ + 1 ) } ( 0 .. $#card_nums ) );
65              
66             my @suits_map_proto = (
67             [ "H" => { name => "hearts", color => "red", }, ],
68             [ "C" => { name => "clubs", color => "black", }, ],
69             [ "D" => { name => "diamonds", color => "red", }, ],
70             [ "S" => { name => "spades", color => "black", }, ],
71             );
72              
73             my %suits_map = ( map { @$_ } @suits_map_proto );
74              
75              
76             sub get_suits_seq
77             {
78 45     45 1 105 my $class = shift;
79              
80 45         142 return [ map { $_->[0] } @suits_map_proto ];
  180         557  
81             }
82              
83              
84             sub calc_rank
85             {
86 12263     12263 1 22813 my ( $self, $s ) = @_;
87              
88 12263         39652 return $ranks_map{$s};
89             }
90              
91              
92             sub calc_rank_with_0
93             {
94 1096     1096 1 2186 my ( $self, $str ) = @_;
95              
96 1096 100       2385 if ( $str eq "0" )
97             {
98 438         1356 return 0;
99             }
100             else
101             {
102 658         1488 return $self->calc_rank($str);
103             }
104             }
105              
106             sub _from_string
107             {
108 11606     11606   21355 my ( $self, $str ) = @_;
109              
110 11606         17627 my $is_flipped = 0;
111              
112 11606 100       27899 if ( $str =~ s{\A<(.*)>\z}{$1}ms )
113             {
114 1         2 $is_flipped = 1;
115             }
116              
117 11606 100       23860 if ( length($str) != 2 )
118             {
119 1         19 Games::Solitaire::Verify::Exception::Parse::Card->throw(
120             error => "string length is too long", );
121             }
122              
123 11605         32237 my ( $rank, $suit ) = split( //, $str );
124              
125 11605 100       26449 if ( !defined( $self->rank( $self->calc_rank($rank) ) ) )
126             {
127 1         10 Games::Solitaire::Verify::Exception::Parse::Card::UnknownRank->throw(
128             error => "unknown rank", );
129             }
130              
131 11604 100       24959 if ( exists( $suits_map{$suit} ) )
132             {
133 11603         27351 $self->suit($suit);
134             }
135             else
136             {
137 1         10 Games::Solitaire::Verify::Exception::Parse::Card::UnknownSuit->throw(
138             error => "unknown suit", );
139             }
140              
141 11603         26964 $self->set_flipped($is_flipped);
142              
143 11603         18991 return;
144             }
145              
146             sub _init
147             {
148 11837     11837   21096 my ( $self, $args ) = @_;
149              
150 11837 100       25619 if ( exists( $args->{string} ) )
151             {
152 11606         28272 $self->_from_string( $args->{string} );
153 11603         21482 $self->_recalc();
154             }
155              
156 11834 100       26925 if ( exists( $args->{id} ) )
157             {
158 8         26 $self->id( $args->{id} );
159             }
160              
161 11834 100       24318 if ( exists( $args->{data} ) )
162             {
163 7         19 $self->data( $args->{data} );
164             }
165              
166 11834         24337 return;
167             }
168              
169              
170             sub color
171             {
172 1965     1965 1 11062 my ($self) = @_;
173              
174 1965         4194 return $self->color_for_suit( $self->suit() );
175             }
176              
177              
178             sub color_for_suit
179             {
180 1969     1969 1 3364 my ( $self, $suit ) = @_;
181              
182 1969         5133 return $suits_map{$suit}->{'color'};
183             }
184              
185              
186             sub clone
187             {
188 231     231 1 2900 my $self = shift;
189              
190 231         639 my $new_card = Games::Solitaire::Verify::Card->new();
191              
192 231         681 $new_card->data( $self->data() );
193 231         558 $new_card->id( $self->id() );
194 231         639 $new_card->suit( $self->suit() );
195 231         529 $new_card->rank( $self->rank() );
196              
197 231         770 $new_card->_recalc();
198              
199 231         780 return $new_card;
200             }
201              
202              
203             sub _to_string_without_flipped
204             {
205 24379     24379   34839 my $self = shift;
206              
207 24379         48078 return $self->rank_to_string( $self->rank() ) . $self->suit();
208             }
209              
210             sub to_string
211             {
212 24379     24379 1 35266 my $self = shift;
213              
214 24379         45458 my $s = $self->_to_string_without_flipped();
215              
216 24379 100       44419 return ( $self->is_flipped ? "<$s>" : $s );
217             }
218              
219              
220             sub fast_s
221             {
222 27567     27567 1 74937 return shift->_s;
223             }
224              
225              
226             {
227             my @_t_nums = ( '0', ( map { $_->{t} } @card_nums ) );
228              
229             sub get_ranks_strings
230             {
231 19     19 1 126 return \@_t_nums;
232             }
233              
234             sub rank_to_string
235             {
236 24379     24379 1 40749 my ( $class, $rank ) = @_;
237              
238 24379         72405 return $_t_nums[$rank];
239             }
240              
241             }
242              
243              
244             sub is_flipped
245             {
246 24380     24380 1 74508 return shift->_flipped();
247             }
248              
249              
250             sub set_flipped
251             {
252 11604     11604 1 19387 my ( $self, $v ) = @_;
253              
254 11604         23401 $self->_flipped($v);
255              
256 11604         28208 $self->_recalc();
257              
258 11604         21421 return;
259             }
260              
261             1; # End of Games::Solitaire::Verify::Card
262              
263             __END__