File Coverage

blib/lib/Games/Cards/Bridge/Rubber.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Games::Cards::Bridge::Rubber;
2              
3 1     1   22433 use strict;
  1         2  
  1         41  
4 1     1   5 use warnings;
  1         1  
  1         29  
5              
6 1     1   4 use base qw(Class::Accessor);
  1         3  
  1         2036  
7             use Games::Cards::Bridge::Contract;
8             use Carp;
9              
10             our $VERSION = '0.01';
11              
12             __PACKAGE__->mk_accessors(
13             'contracts', # array ref
14             # these are all auto-calculated
15             # scores:
16             'we_above',
17             'we_below',
18             'we_leg',
19             'they_leg',
20             'they_above',
21             'they_below',
22             'we_vul', # bool
23             'they_vul', # bool
24             'complete', # bool
25             );
26              
27             sub we_score {
28             my $self = shift;
29             return $self->we_above + $self->we_below;
30             }
31             sub they_score {
32             my $self = shift;
33             return $self->they_above + $self->they_below;
34             }
35             sub both_vul {
36             my $self = shift;
37             return $self->we_vul && $self->they_vul;
38             }
39              
40             sub new {
41             my $self = shift;
42             my $class = ref($self) || $self;
43             $self = bless {}, $class;
44             $self->set($_, 0) for qw/we_above we_below they_above they_below we_vul they_vul complete we_leg they_leg/;
45             $self->set('contracts', []);
46             return $self;
47             }
48              
49             sub contract {
50             my $self = shift;
51             my $p = {@_};
52             my $dir = lc $p->{direction};
53             my $we = $dir eq 'we';
54             my $they = !$we;
55             croak "'direction' must be 'we' or 'they'" unless $dir =~ /^(we|they)$/;
56             my $contract = Games::Cards::Bridge::Contract->new(
57             declarer=> 'N',
58             trump => $p->{trump},
59             bid => $p->{bid},
60             made => $p->{made},
61             down => $p->{down},
62             vul => ($we ? $self->we_vul : $self->they_vul),
63             penalty => $p->{dbl},
64             );
65             my @score = $contract->rubber_score; # (declarer_above, declarer_below, opps_above)
66             push @{$self->contracts}, $contract;
67             my ( $decAbove, $decBelow, $decLeg, $decVul, $oppAbove, $oppLeg, $oppVul ) = $we
68             ? qw/ we_above we_below we_leg we_vul they_above they_leg they_vul /
69             : qw/ they_above they_below they_leg they_vul we_above we_leg we_vul / ;
70             $self->set($decAbove, $self->$decAbove + $score[0]);
71             $self->set($decBelow, $self->$decBelow + $score[1]);
72             $self->set($oppAbove, $self->$oppAbove + $score[2]);
73             $self->set($decLeg, $self->$decLeg + $score[1]);
74             if( $self->$decLeg >= 100 ){ # game was reached
75             $self->set($decLeg, 0); # clear the legs
76             $self->set($oppLeg, 0);
77             if( $self->$decVul ){ # if already vul
78             $self->set('complete', 1); # .. then this was second game, so rubber is done
79             $self->set($decAbove, $self->$decAbove + ($self->$oppVul ? 500 : 700) ); # rubber bonus
80             }else{
81             $self->set($decVul, 1); # now vul
82             }
83             }
84             return $contract;
85             }
86              
87             1;
88              
89              
90             =pod
91              
92             =head1 NAME
93              
94             Games::Cards::Bridge::Rubber - Object for Bridge (card game) Rubber scoring
95              
96             =head1 VERSION
97              
98             Version 0.01
99              
100             =head1 SYNOPSIS
101              
102             This module provides a class for creating Bridge rubber objects, including the results and scoring and current state of the rubber.
103              
104             use Games::Cards::Bridge::Rubber;
105             sub show_score {
106             my $rubber = shift;
107             printf "Totals (above/below): We = %d/%d \t They = %d/%d\n", $rubber->we_above, $rubber->we_below, $rubber->they_above, $rubber->they_below;
108             printf " Legs: We = %d \t They = %d\n", $rubber->we_leg, $rubber->they_leg;
109             printf " Vul: We = %d \t They = %d\n", $rubber->we_vul, $rubber->they_vul;
110             printf "==COMPLETE==\n\tWe: %d\tThey: %d\n", $rubber->we_score, $rubber->they_score if $rubber->complete;
111             }
112             my $rubber = Games::Cards::Bridge::Rubber->new;
113              
114             show_score($rubber);
115             foreach my $opts (
116             { direction => 'we', trump => 'H', bid => '2', made => '4' },
117             { direction => 'they', trump => 'S', bid => '4', down => '2', dbl => 1 },
118             { direction => 'they', trump => 'N', bid => '3', made => '4' },
119             { direction => 'they', trump => 'S', bid => '3', made => '3' },
120             { direction => 'they', trump => 'D', bid => '2', down => '2' },
121             { direction => 'we', trump => 'H', bid => '6', made => '7', dbl => 1 },
122             { direction => 'they', trump => 'N', bid => '1', made => '2' },
123             { direction => 'we', trump => 'C', bid => '3', made => '3' },
124             { direction => 'they', trump => 'H', bid => '3', made => '3' },
125             ){
126             $rubber->contract( %$opts );
127             show_score($rubber);
128             }
129              
130              
131             =head1 METHODS
132              
133             =head2 new
134              
135             No parameters needed.
136              
137             =head2 contract
138              
139             Add a contract to the rubber.
140             This needs the same arguments as L's constructor, as well as a I parameter of 'we' or 'they' (and the I parameter is not used).
141             This method is also responsible for internally updating the attributes.
142             See also L
143              
144             =head2 we_score
145              
146             Gives the current total 'We' score.
147              
148             =head2 they_score
149              
150             Gives the current total 'They' score.
151              
152             =head2 both_vul
153              
154             Alias to returns true iff ->we_vul() and ->they_vul().
155              
156             =head1 ATTRIBUTES
157              
158             These are all auto-calculated/maintained; their current values are available from the accessor method provided by L.
159              
160             =head2 contracts
161              
162             Array ref holding all the contracts added by the contract() method.
163              
164             =head2 we_above
165              
166             Current above-the-line score for 'We'.
167              
168             =head2 we_below
169              
170             Current below-the-line score for 'We'.
171              
172             =head2 we_leg
173              
174             The current "leg" for 'We'.
175              
176             =head2 they_leg
177              
178             The current "leg" for 'They'.
179              
180             =head2 they_above
181              
182             Current above-the-line score for 'They'.
183              
184             =head2 they_below
185              
186             Current below-the-line score for 'They'.
187              
188             =head2 we_vul
189              
190             Returns true if the 'We' side is vulnerable (has one "game").
191              
192             =head2 they_vul
193              
194             Returns true if the 'They' side is vulnerable (has one "game").
195              
196             =head2 complete
197              
198             Returns true if the rubber has concluded (one side got two "games").
199              
200             =head1 PREREQUISITES
201              
202             =over 4
203              
204             =item *
205              
206             L
207              
208             =item *
209              
210             L
211              
212             =item *
213              
214             L
215              
216             =back
217              
218             =head1 TODO
219              
220             =over 4
221              
222             =item *
223              
224             Handle honors bonuses
225              
226             =back
227              
228             =head1 AUTHOR
229              
230             David Westbrook, C<< >>
231              
232             =head1 BUGS & SUPPORT
233              
234             See L
235              
236             =head1 COPYRIGHT & LICENSE
237              
238             Copyright 2006 David Westbrook, all rights reserved.
239              
240             This program is free software; you can redistribute it and/or modify it
241             under the same terms as Perl itself.
242              
243             =cut
244              
245