File Coverage

blib/lib/Games/Blackjack.pm
Criterion Covered Total %
statement 53 77 68.8
branch 14 32 43.7
condition 2 9 22.2
subroutine 12 18 66.6
pod n/a
total 81 136 59.5


line stmt bran cond sub pod time code
1             ######################################################################
2             # Games::Blackjack -- 2003, Mike Schilli
3             ######################################################################
4 1     1   37739 use warnings; use strict;
  1     1   2  
  1         36  
  1         5  
  1         2  
  1         73  
5              
6             package Games::Blackjack;
7              
8             our $VERSION = "0.04";
9              
10             #==========================================
11             package Games::Blackjack::Shoe;
12             #==========================================
13              
14 1     1   2529 use Algorithm::GenerateSequence;
  1         754  
  1         33  
15             use Algorithm::Numerical::Shuffle
16 1     1   1143 qw(shuffle);
  1         663  
  1         305  
17              
18             ###########################################
19             sub new {
20             ###########################################
21 2     2   550 my($class, @options) = @_;
22              
23 2         9 my $self = {nof_decks => 1, @options};
24              
25 2         6 bless $self, $class;
26 2         10 $self->reshuffle();
27 2         912 return $self;
28             }
29              
30             ###########################################
31             sub reshuffle {
32             ###########################################
33 2     2   3 my($self) = @_;
34              
35 2         27 my @cards =
36             (Algorithm::GenerateSequence->new(
37             [qw( Heart Diamond Spade Club )],
38             [qw( A 2 3 4 5 6 7 8 9 10 J Q K )])
39             ->as_list()) x $self->{nof_decks};
40              
41 2         1726 $self->{cards} = shuffle \@cards;
42             }
43              
44             ###########################################
45             sub remaining {
46             ###########################################
47 0     0   0 my($self) = @_;
48              
49 0         0 return scalar @{$self->{cards}};
  0         0  
50             }
51              
52             ###########################################
53             sub draw_card {
54             ###########################################
55 0     0   0 my($self) = @_;
56              
57 0         0 return shift @{$self->{cards}};
  0         0  
58             }
59              
60             #==========================================
61             package Games::Blackjack::Hand;
62             #==========================================
63 1     1   1386 use Quantum::Superpositions;
  1         48158  
  1         8  
64 1     1   1960 use Log::Log4perl qw(:easy);
  1         80204  
  1         10  
65              
66             ###########################################
67             sub new {
68             ###########################################
69 3     3   28 my($class, @options) = @_;
70              
71 3         10 my $self = { cards => [], @options };
72              
73 3 50       12 die "No shoe" if !exists $self->{shoe};
74 3         14 bless $self, $class;
75             }
76              
77             ###########################################
78             sub draw {
79             ###########################################
80 0     0   0 my($self) = @_;
81              
82 0         0 push @{$self->{cards}},
  0         0  
83             $self->{shoe}->draw_card();
84             }
85              
86             ###########################################
87             sub count {
88             ###########################################
89 18     18   15120 my($self, $how) = @_;
90              
91 18         52 my $counts = any(0);
92              
93 18         101 for(@{$self->{cards}}) {
  18         54  
94 50 100       8488 if($_->[1] =~ /\d/) {
    50          
95 26         180 $counts += $_->[1];
96             } elsif($_->[1] eq 'A') {
97 48         25400 $counts = any(
98 24         84 map { eigenstates $_ } $counts+1, $counts+11);
99             } else {
100 0         0 $counts += 10;
101             }
102             }
103              
104 18         10803 DEBUG "counts(before)=$counts";
105              
106             # Delete busted hands
107 18         4094 $counts = ($counts <= 21);
108            
109 18         9531 DEBUG "counts(after)=$counts";
110              
111             # Busted!!
112 18 100       2705 return undef if ! eigenstates($counts);
113              
114 14 100       14681 return $counts unless defined $how;
115              
116 12 100       92 if($how eq "hard") {
    50          
117             # Return minimum
118 1         5 return int($counts <=
119             all(eigenstates($counts)));
120             } elsif($how eq "soft") {
121             # Return maxium
122 11         37 return int($counts >=
123             all(eigenstates($counts)));
124             }
125             }
126              
127             ###########################################
128             sub blackjack {
129             ###########################################
130 2     2   16 my($self) = @_;
131              
132 2         9 my $c = $self->count();
133              
134 2 100       65 return 0 unless defined $c;
135              
136 1         1110 return 1 if $c == 21 and $c == 11 and
137 1 50 33     5 @{$self->{cards}} == 2;
      33        
138 0         0 return 0;
139             }
140              
141             ###########################################
142             sub as_string {
143             ###########################################
144 0     0   0 my($self) = @_;
145              
146 0         0 return "[" . join(',', map({ "@$_" }
  0         0  
147 0         0 @{$self->{cards}})) . "]";
148             }
149              
150             ###########################################
151             sub count_as_string {
152             ###########################################
153 0     0   0 my($self) = @_;
154              
155 0 0       0 return $self->busted() ?
    0          
156             "Busted" : $self->blackjack() ?
157             "Blackjack" : $self->count("soft");
158             }
159              
160             ###########################################
161             sub busted {
162             ###########################################
163 2     2   666 my($self) = @_;
164              
165 2         7 return ! defined $self->count();
166             }
167              
168             ###########################################
169             sub score {
170             ###########################################
171 0     0     my($self, $dealer) = @_;
172              
173 0 0         return -1 if $self->busted();
174              
175 0 0         return 1 if $dealer->busted();
176              
177 0 0 0       return 0 if $self->blackjack() and
178             $dealer->blackjack();
179              
180 0 0         return 1.5 if $self->blackjack();
181              
182 0 0         return -1 if $dealer->blackjack();
183              
184 0           return $self->count("soft") <=>
185             $dealer->count("soft");
186             }
187              
188             1;
189              
190             __END__