File Coverage

blib/lib/Games/Euchre/AI/Human.pm
Criterion Covered Total %
statement 9 126 7.1
branch 0 30 0.0
condition 0 15 0.0
subroutine 3 11 27.2
pod 7 8 87.5
total 19 190 10.0


line stmt bran cond sub pod time code
1             # Human computer player.
2              
3             # This module is licensed under the same terms as the other modules in
4             # this package: GPLv2
5              
6             package Games::Euchre::AI::Human;
7              
8 1     1   874 use strict;
  1         2  
  1         27  
9 1     1   5 use warnings;
  1         2  
  1         21  
10 1     1   6 use Games::Euchre::AI;
  1         1  
  1         1764  
11              
12             our @ISA = qw(Games::Euchre::AI);
13              
14             # Words for the players
15             our %who = (
16             0 => "you",
17             1 => "your left opponent",
18             2 => "your partner",
19             3 => "your right opponent",
20             );
21              
22             # Helper function
23             sub who {
24 0     0 0   my $state = shift;
25 0           my $theirNum = shift;
26 0           my $index = $theirNum - $state->{number} % 4;
27 0           return $state->{names}->{$theirNum} . " ($who{$index})";
28             }
29              
30             sub bid {
31 0     0 1   my $self = shift;
32 0           my $state = shift;
33              
34 0 0         my $round = ($state->{passes} < 4 ? 1 : 2);
35 0           my $options;
36 0 0         if ($round == 1) {
37 0           my $dealer = ($state->{number} - $state->{passes} - 2) % 4 + 1;
38 0           $self->{turnedUp} = $state->{turnedUp};
39 0           $self->{turnedUp} =~ /(.)$/;
40 0           my $suit = $1;
41             # bid can only be turned-up suit of pass
42 0           $options = "$suit,${suit}A,P";
43 0           print "Dealer: " . &who($state, $dealer) .
44             " turned up: $$state{turnedUp}\n";
45             # Show other players' passes
46 0           for (my $i=0; $i < $state->{passes} % 4; $i++) {
47 0           my $player = ($state->{number} - $state->{passes} + $i - 1) % 4 + 1;
48 0           print &who($state, $player) . " passed\n";
49             }
50             } else {
51 0           $self->{turnedUp} =~ /(.)$/;
52 0           my $suit = $1;
53 0           $options = "H,D,S,C,N,HA,DA,SA,CA,NA,P";
54             # disallow the round 1 suit
55 0           $options =~ s/$suit A?,//gx;
56             # maybe disallow notrump
57 0 0         $options =~ s/NA?,//g if (!$state->{notrump});
58             # disallow pass in hand-dealer situation
59 0 0 0       $options =~ s/,P// if ($state->{hangdealer} && $state->{passes} == 7);
60             # Show other players' passes
61 0           for (my $i=1; $i <= 3; $i++) {
62 0           my $player = ($state->{number} + $i - 1) % 4 + 1;
63 0           print &who($state, $player) . " passed\n";
64             }
65             }
66 0           print "Your hand: " . join(" ", @{$state->{hand}}) . "\n";
  0            
67              
68             # Loop until we get a legal bid
69 0           my $bid = "XXX";
70 0           my $legal = 0;
71 0           do {
72 0           print "\nYour bid ($options): ";
73 0           $bid = uc();
74 0           print "\n";
75             # Clean up: no whitespace, pass is undef
76 0           $bid =~ s/\s//gs;
77 0 0         $bid = undef if ($bid eq "P");
78 0           $legal = $self->isLegalBid($state, $bid);
79 0 0         if (!$legal) {
80 0           print " *** Illegal bid ***\n";
81             }
82             } while (!$legal);
83              
84 0           return $bid;
85             }
86              
87             sub pickItUp {
88 0     0 1   my $self = shift;
89 0           my $state = shift;
90              
91 0           print "Turned up: $$state{turnedUp}\n";
92 0           print "Your hand: " . join(" ", @{$state->{hand}}) . "\n";
  0            
93              
94             # Loop until we get a legal card
95 0           my $index = -1;
96 0           my $legal = 0;
97 0           do {
98 0           print "\nWhich card do you want to discard (1-5): ";
99 0           $index = ;
100 0           print "\n";
101 0           chomp $index;
102 0   0       $legal = $index =~ /^\d$/ && $index >= 1 && $index <= 5;
103 0 0         if (!$legal) {
104 0           print " *** Not a valid card number ***\n";
105             }
106             } while (!$legal);
107              
108 0           return $index-1;
109             }
110              
111             sub playCard {
112 0     0 1   my $self = shift;
113 0           my $state = shift;
114              
115 0 0         if (@{$state->{played}}) {
  0            
116 0           for (my $i=0; $i < @{$state->{played}}; $i++) {
  0            
117 0           print &who($state, $state->{playedBy}->[$i]) . " played " . $state->{played}->[$i] . "\n";
118             }
119             #print "\n";
120             } else {
121 0           print "Your lead\n";
122             }
123 0           print "Your hand: " . join(" ", @{$state->{hand}}) . ", trump: $$state{trump}, tricks: $$state{ourTricks} for us, $$state{theirTricks} for them\n";
  0            
124              
125             # Loop until we get a legal card
126 0           my $index = -1;
127 0           my $legal = 0;
128 0           do {
129 0           print "\nWhich card do you want to play (1-" . @{$state->{hand}} . "): ";
  0            
130 0           $index = ;
131 0           print "\n";
132 0           chomp $index;
133 0   0       $legal = $index =~ /^\d$/ && $index >= 1 && $index <= @{$state->{hand}};
134 0 0         if (!$legal) {
135 0           print " *** Not a valid card number ***\n";
136             } else {
137 0           $legal = $self->isLegalPlay($state, $index-1);
138 0 0         if (!$legal) {
139 0           print " *** Not a legal choice ***\n";
140             }
141             }
142             } while (!$legal);
143              
144 0           return $index-1;
145             }
146              
147              
148             sub endOfBidding {
149 0     0 1   my $self = shift;
150 0           my $state = shift;
151              
152 0           my %results = (
153             C => "CLUBS are trump",
154             H => "HEARTS are trump",
155             S => "SPADES are trump",
156             D => "DIAMONDS are trump",
157             N => "NO-TRUMP was called",
158             );
159              
160             # Say who passed before the bid
161 0           my $bidder = $state->{bidder};
162             # If all passed, pretend player after dealer was bidder
163 0   0       $bidder ||= ($state->{dealer} % 4) + 1;
164 0           my $passesPlusOne = ($bidder - $state->{number}) %4;
165 0           for (my $i=1; $i < $passesPlusOne; $i++) {
166 0           my $player = ($state->{number} + $i - 1) % 4 + 1;
167 0           print &who($state, $player) . " passed\n";
168             }
169              
170 0 0         if ($state->{trump}) {
171 0           my $trumpMsg = $results{$state->{trump}};
172 0 0 0       my $alone = $state->{usAlone} || $state->{themAlone} ? " alone" : "";
173 0           print &who($state, $state->{bidder}) . " bid$alone, $trumpMsg\n";
174             } else {
175 0           $self->{allPassed} = 1;
176 0           print "Bidding is over, everyone passed\n\n";
177             }
178             }
179              
180             sub endOfTrick {
181 0     0 1   my $self = shift;
182 0           my $state = shift;
183              
184 0           for (my $i=$state->{myCard}; $i<@{$state->{played}}; $i++) {
  0            
185 0           print &who($state, $state->{playedBy}->[$i]) . " played " . $state->{played}->[$i] . "\n";
186             }
187              
188 0           print &who($state, $state->{winner}) . " won the trick\n\n";
189             }
190              
191             sub endOfHand {
192 0     0 1   my $self = shift;
193 0           my $state = shift;
194              
195              
196 0 0         if (!$self->{allPassed}) {
197 0 0         my $who = $state->{ourTricks} > $state->{theirTricks} ? "You" : "They";
198 0           my @tricks = sort ($state->{ourTricks}, $state->{theirTricks});
199 0           my %score = (
200             'win' => "1",
201             'all' => "2 (all of them)",
202             'alone' => "4 (alone!)",
203             'euchre' => "2 (Euchre!)",
204             );
205 0           print "$who won the hand $tricks[1] to $tricks[0] for a score of $score{$state->{winType}}\n";
206             }
207 0           delete $self->{turnedUp};
208 0           delete $self->{allPassed};
209             }
210              
211             sub endOfGame {
212 0     0 1   my $self = shift;
213 0           my $state = shift;
214              
215 0 0         my $who = $state->{ourScore} > $state->{theirScore} ? "You" : "They";
216 0           my @score = sort ($state->{ourScore}, $state->{theirScore});
217 0           print "$who won the game $score[1] to $score[0]\n";
218             }
219              
220             1;