File Coverage

blib/lib/Games/Bowling/Scorecard/AsText.pm
Criterion Covered Total %
statement 47 47 100.0
branch 38 38 100.0
condition 8 8 100.0
subroutine 7 7 100.0
pod 1 1 100.0
total 101 101 100.0


line stmt bran cond sub pod time code
1 1     1   1488 use v5.24.0;
  1         3  
2 1     1   5 use warnings;
  1         2  
  1         37  
3             package Games::Bowling::Scorecard::AsText 0.106;
4             # ABSTRACT: format a bowling scorecard as text
5              
6 1     1   6 use utf8;
  1         2  
  1         5  
7              
8             #pod =encoding utf8
9             #pod
10             #pod =head1 SYNOPSIS
11             #pod
12             #pod use Games::Bowling::Scorecard;
13             #pod
14             #pod my $card = Games::Bowling::Scorecard->new;
15             #pod
16             #pod $card->record(6,1); # slow start
17             #pod $card->record(7,2); # getting better
18             #pod $card->record(10); # strike!
19             #pod $card->record(9,1); # picked up a spare
20             #pod $card->record(10) for 1 .. 3; # turkey!
21             #pod $card->record(0,0); # clearly distracted by something
22             #pod $card->record(8,2); # amazingly picked up 7-10 split
23             #pod $card->record(10, 9, 1); # pick up a bonus spare
24             #pod
25             #pod print Games::Bowling::Scorecard::AsText->card_as_text($card);
26             #pod
27             #pod The above outputs:
28             #pod
29             #pod ┏━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━━━┓
30             #pod ┃ 6 1 ┃ 7 2 ┃ ╳ ┃ 9 ◢ ┃ ╳ ┃ ╳ ┃ ╳ ┃ - - ┃ 8 ◢ ┃ ╳ 9 ◢ ┃
31             #pod ┃ 7 ┃ 16 ┃ 36 ┃ 56 ┃ 86 ┃ 106 ┃ 116 ┃ 116 ┃ 136 ┃ 156 ┃
32             #pod ┗━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━━━┛
33             #pod
34             #pod =head1 WARNING
35             #pod
36             #pod This module's interface is almost certain to change, whenever the author gets
37             #pod around to it.
38             #pod
39             #pod =head1 DESCRIPTION
40             #pod
41             #pod So, you've written a bowling record-keeper and now you want to print out
42             #pod scorecards to your dynamic Gopher site. Games::Bowling::Scorecard has taken
43             #pod care of the scoring, but now you need to worry about all those slashes and
44             #pod dashes and X's
45             #pod
46             #pod =method card_as_text
47             #pod
48             #pod my $text = Games::Bowling::Scorecard::AsText->card_as_text($card);
49             #pod
50             #pod Given a scorecard, this method returns a three-line text version of the card,
51             #pod using standard notation. A total is kept only through the last non-pending
52             #pod frame.
53             #pod
54             #pod =cut
55              
56 1     1   34 use Carp ();
  1         2  
  1         654  
57              
58             sub card_as_text {
59 4     4 1 37 my ($self, $card) = @_;
60              
61 4         6 my $hdr = '┏━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━━━━━━┓';
62 4         7 my $ftr = '┗━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━━━━━━┛';
63 4         23 my $balls = '';
64 4         8 my $scores = '';
65              
66 4         10 my @frames = $card->frames;
67 4         11 INDEX: for my $i (0 .. 8) {
68 36         63 my $frame = $frames[ $i ];
69 36 100       82 unless ($frame) {
70 5         12 $_ .= '┃ ' for $balls, $scores;
71 5         12 next INDEX;
72             }
73              
74 31         76 $balls .= sprintf '┃ %s ',
75             $self->_two_balls($frame->was_split, $frame->balls);
76              
77 31         84 my $score = $card->score_through($i + 1);
78 31 100       121 $scores .= defined $score
79             ? sprintf '┃ %3u ', $score
80             : '┃ ';
81             }
82              
83 4         8 TENTH: for (1) {
84 4         8 my $frame = $frames[ 9 ];
85              
86 4 100       9 unless ($frame) {
87 1         2 $_ .= '┃ ┃' for $balls, $scores;
88 1         2 last TENTH;
89             }
90              
91 3         11 $balls .= sprintf '┃ %s ┃',
92             $self->_three_balls($frame->was_split, $frame->balls);
93              
94 3         8 my $score = $card->score_through(10);
95              
96 3 100       15 $scores .= defined $score
97             ? sprintf '┃ %3u ┃', $score
98             : '┃ ┃';
99             }
100              
101 4         51 return "$hdr\n"
102             . "$balls\n"
103             . "$scores\n"
104             . "$ftr\n";
105             }
106              
107             my @NUM = qw(
108             - 1 2 3 4 5 6 7 8 9
109             ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨
110             );
111              
112             sub _two_balls {
113 54     54   5567 my ($self, $split, $b1, $b2) = @_;
114              
115 54 100       114 return ' ' unless defined $b1;
116              
117 53         110 my $c = $NUM[ (9 * $split) + $b1 ];
118              
119 53 100 100     410 sprintf '%s %s',
    100          
    100          
    100          
120             $b1 == 10 ? '╳' : $c,
121             $b1 == 10 ? ' ' : defined $b2 ? $b1 + $b2 == 10 ? '◢' : $b2 || '-' : ' ';
122             }
123              
124             sub _three_balls {
125 22     22   10177 my ($self, $split, $b1, $b2, $b3) = @_;
126              
127 22 100       63 return ' ' unless defined $b1;
128              
129 21 100       57 if ($b1 == 10) {
    100          
    100          
130 12 100       31 return '╳ ' unless defined $b2;
131              
132 10 100 100     56 return sprintf '╳ ╳ %s', defined $b3 ? $b3 == 10 ? '╳' : $b3 || '-' : ' '
    100          
    100          
133             if $b2 == 10;
134              
135 6         15 return sprintf '╳ %s', $self->_two_balls($split, $b2, $b3);
136             } elsif (not defined $b2) {
137 2   100     17 return sprintf '%s ', $b1 || '-';
138             } elsif ($b1 + $b2 == 10) {
139 4 100 100     9 return sprintf '%s %s',
    100          
140             $self->_two_balls($split, $b1, $b2),
141             defined $b3 ? $b3 == 10 ? '╳' : $b3 || '-' : ' ';
142             } else {
143 3         10 return sprintf '%s ', $self->_two_balls($split, $b1, $b2);
144             }
145             }
146              
147             300;
148              
149             __END__