File Coverage

blib/lib/Games/Bowling/Scorecard.pm
Criterion Covered Total %
statement 53 53 100.0
branch 12 12 100.0
condition 12 12 100.0
subroutine 12 12 100.0
pod 8 8 100.0
total 97 97 100.0


line stmt bran cond sub pod time code
1 2     2   2025 use strict;
  2         5  
  2         97  
2 2     2   12 use warnings;
  2         4  
  2         135  
3             package Games::Bowling::Scorecard;
4             {
5             $Games::Bowling::Scorecard::VERSION = '0.105';
6             }
7             # ABSTRACT: score your bowling game easily
8              
9              
10 2     2   1190 use Games::Bowling::Scorecard::Frame;
  2         5  
  2         1178  
11              
12              
13             sub new {
14 8     8 1 4284 my ($class) = @_;
15              
16 8         87 my $self = bless { frames => [ ] } => $class;
17              
18 8         31 return $self;
19             }
20              
21              
22             sub frames {
23 687     687 1 803 my ($self) = @_;
24              
25 687         679 return @{ $self->{frames} };
  687         2219  
26             }
27              
28              
29             sub current_frame {
30 139     139 1 1152 my ($self) = @_;
31              
32 139 100       224 return if $self->is_done;
33              
34 138         381 my @frames = $self->frames;
35              
36 138         213 my $frame = pop @frames;
37              
38 138 100 100     543 return $self->_next_frame if !$frame || $frame->is_done;
39              
40 64         230 return $frame;
41             }
42              
43             sub _next_frame {
44 74     74   89 my ($self) = @_;
45              
46             my $frame = $self->frames == 9
47 74 100       184 ? do {
48 7         3096 require Games::Bowling::Scorecard::Frame::TenPinTenth;
49 7         48 Games::Bowling::Scorecard::Frame::TenPinTenth->new;
50             }
51             : Games::Bowling::Scorecard::Frame->new;
52              
53 74         107 push @{ $self->{frames} }, $frame;
  74         167  
54              
55 74         307 return $frame;
56             }
57              
58              
59             sub pending_frames {
60 136     136 1 164 my ($self) = @_;
61              
62 136         224 my @pending_frames = grep { $_->is_pending } $self->frames;
  673         1531  
63             }
64              
65              
66             sub record { ## no critic Ambiguous
67 81     81 1 1918 my ($self, @balls) = @_;
68              
69 81         185 for my $ball (@balls) {
70 140 100       250 Carp::croak "can't record more balls on a completed scorecard"
71             if $self->is_done;
72              
73 136         289 for my $pending ($self->pending_frames) {
74 38         100 $pending->record($ball);
75             }
76              
77 136         333 $self->current_frame->record($ball);
78             }
79             }
80              
81              
82             sub score {
83 6     6 1 26 my ($self) = @_;
84              
85 6         9 my $score = 0;
86 6         14 $score += $_->score for $self->frames;
87              
88 6         42 return $score;
89             }
90              
91              
92             sub score_through {
93 44     44 1 4175 my ($card, $n) = @_;
94              
95 44 100 100     462 Carp::croak "frame out of range" unless $n >= 1 and $n <= 10;
96              
97 42         79 my @frames = $card->frames;
98 42         64 my $score = 0;
99              
100 42         87 INDEX: for my $idx (0 .. $n - 1) {
101 210         276 my $frame = $frames[ $idx ];
102 210 100 100     560 return undef if $frame->is_pending or not $frame->is_done;
103              
104 207         535 $score += $frame->score;
105             }
106              
107 39         151 return $score;
108             }
109              
110              
111             sub is_done {
112 285     285 1 1004 my ($self) = @_;
113              
114 285         478 my @frames = $self->frames;
115              
116 285   100     1267 return (@frames == 10 and $frames[9]->is_done);
117             }
118              
119              
120             300;
121              
122             __END__