# Human computer player.
# This module is licensed under the same terms as the other modules in
# this package: GPLv2
package Games::Euchre::AI::Human;
use strict;
use warnings;
use Games::Euchre::AI;
our @ISA = qw(Games::Euchre::AI);
# Words for the players
our %who = (
0 => "you",
1 => "your left opponent",
2 => "your partner",
3 => "your right opponent",
);
# Helper function
sub who {
my $state = shift;
my $theirNum = shift;
my $index = $theirNum - $state->{number} % 4;
return $state->{names}->{$theirNum} . " ($who{$index})";
}
sub bid {
my $self = shift;
my $state = shift;
my $round = ($state->{passes} < 4 ? 1 : 2);
my $options;
if ($round == 1) {
my $dealer = ($state->{number} - $state->{passes} - 2) % 4 + 1;
$self->{turnedUp} = $state->{turnedUp};
$self->{turnedUp} =~ /(.)$/;
my $suit = $1;
# bid can only be turned-up suit of pass
$options = "$suit,${suit}A,P";
print "Dealer: " . &who($state, $dealer) .
" turned up: $$state{turnedUp}\n";
# Show other players' passes
for (my $i=0; $i < $state->{passes} % 4; $i++) {
my $player = ($state->{number} - $state->{passes} + $i - 1) % 4 + 1;
print &who($state, $player) . " passed\n";
}
} else {
$self->{turnedUp} =~ /(.)$/;
my $suit = $1;
$options = "H,D,S,C,N,HA,DA,SA,CA,NA,P";
# disallow the round 1 suit
$options =~ s/$suit A?,//gx;
# maybe disallow notrump
$options =~ s/NA?,//g if (!$state->{notrump});
# disallow pass in hand-dealer situation
$options =~ s/,P// if ($state->{hangdealer} && $state->{passes} == 7);
# Show other players' passes
for (my $i=1; $i <= 3; $i++) {
my $player = ($state->{number} + $i - 1) % 4 + 1;
print &who($state, $player) . " passed\n";
}
}
print "Your hand: " . join(" ", @{$state->{hand}}) . "\n";
# Loop until we get a legal bid
my $bid = "XXX";
my $legal = 0;
do {
print "\nYour bid ($options): ";
$bid = uc(<STDIN>);
print "\n";
# Clean up: no whitespace, pass is undef
$bid =~ s/\s//gs;
$bid = undef if ($bid eq "P");
$legal = $self->isLegalBid($state, $bid);
if (!$legal) {
print " *** Illegal bid ***\n";
}
} while (!$legal);
return $bid;
}
sub pickItUp {
my $self = shift;
my $state = shift;
print "Turned up: $$state{turnedUp}\n";
print "Your hand: " . join(" ", @{$state->{hand}}) . "\n";
# Loop until we get a legal card
my $index = -1;
my $legal = 0;
do {
print "\nWhich card do you want to discard (1-5): ";
$index = <STDIN>;
print "\n";
chomp $index;
$legal = $index =~ /^\d$/ && $index >= 1 && $index <= 5;
if (!$legal) {
print " *** Not a valid card number ***\n";
}
} while (!$legal);
return $index-1;
}
sub playCard {
my $self = shift;
my $state = shift;
if (@{$state->{played}}) {
for (my $i=0; $i < @{$state->{played}}; $i++) {
print &who($state, $state->{playedBy}->[$i]) . " played " . $state->{played}->[$i] . "\n";
}
#print "\n";
} else {
print "Your lead\n";
}
print "Your hand: " . join(" ", @{$state->{hand}}) . ", trump: $$state{trump}, tricks: $$state{ourTricks} for us, $$state{theirTricks} for them\n";
# Loop until we get a legal card
my $index = -1;
my $legal = 0;
do {
print "\nWhich card do you want to play (1-" . @{$state->{hand}} . "): ";
$index = <STDIN>;
print "\n";
chomp $index;
$legal = $index =~ /^\d$/ && $index >= 1 && $index <= @{$state->{hand}};
if (!$legal) {
print " *** Not a valid card number ***\n";
} else {
$legal = $self->isLegalPlay($state, $index-1);
if (!$legal) {
print " *** Not a legal choice ***\n";
}
}
} while (!$legal);
return $index-1;
}
sub endOfBidding {
my $self = shift;
my $state = shift;
my %results = (
C => "CLUBS are trump",
H => "HEARTS are trump",
S => "SPADES are trump",
D => "DIAMONDS are trump",
N => "NO-TRUMP was called",
);
# Say who passed before the bid
my $bidder = $state->{bidder};
# If all passed, pretend player after dealer was bidder
$bidder ||= ($state->{dealer} % 4) + 1;
my $passesPlusOne = ($bidder - $state->{number}) %4;
for (my $i=1; $i < $passesPlusOne; $i++) {
my $player = ($state->{number} + $i - 1) % 4 + 1;
print &who($state, $player) . " passed\n";
}
if ($state->{trump}) {
my $trumpMsg = $results{$state->{trump}};
my $alone = $state->{usAlone} || $state->{themAlone} ? " alone" : "";
print &who($state, $state->{bidder}) . " bid$alone, $trumpMsg\n";
} else {
$self->{allPassed} = 1;
print "Bidding is over, everyone passed\n\n";
}
}
sub endOfTrick {
my $self = shift;
my $state = shift;
for (my $i=$state->{myCard}; $i<@{$state->{played}}; $i++) {
print &who($state, $state->{playedBy}->[$i]) . " played " . $state->{played}->[$i] . "\n";
}
print &who($state, $state->{winner}) . " won the trick\n\n";
}
sub endOfHand {
my $self = shift;
my $state = shift;
if (!$self->{allPassed}) {
my $who = $state->{ourTricks} > $state->{theirTricks} ? "You" : "They";
my @tricks = sort ($state->{ourTricks}, $state->{theirTricks});
my %score = (
'win' => "1",
'all' => "2 (all of them)",
'alone' => "4 (alone!)",
'euchre' => "2 (Euchre!)",
);
print "$who won the hand $tricks[1] to $tricks[0] for a score of $score{$state->{winType}}\n";
}
delete $self->{turnedUp};
delete $self->{allPassed};
}
sub endOfGame {
my $self = shift;
my $state = shift;
my $who = $state->{ourScore} > $state->{theirScore} ? "You" : "They";
my @score = sort ($state->{ourScore}, $state->{theirScore});
print "$who won the game $score[1] to $score[0]\n";
}
1;