#!/usr/bin/perl
$Getopt::Std::STANDARD_HELP_VERSION
= 1;
my
(
@DECK
,
@PLAYERS_HAND
,
@COMPUTERS_HAND
,
%BOOKS
,
%opt
);
my
(
@HIS_PAST_GUESSES
,
@MY_PAST_GUESSES
);
my
(
$asker
,
$opponent
,
$professional
,
$whoseturn
,
$status
,
$myb
,
$yourb
);
my
%so
=(
'A'
=>1,
'J'
=>11,
'Q'
=>12,
'K'
=>13 );
my
%iscard
=
map
{
$_
=> 1 }
qw(A J Q K 2 3 4 5 6 7 8 9 10)
;
sub
pickone {
my
(
$myarr
)=
@_
;
my
%h
=
map
{
$_
=> 1 }
@$myarr
;
return
( (
keys
%h
)[
rand
scalar
keys
%h
] )
if
(!
$professional
);
my
(
@saveguess
,
$guess
)=();
while
(
@HIS_PAST_GUESSES
) {
$guess
=
shift
@HIS_PAST_GUESSES
;
next
if
(
grep
(
$guess
eq
$_
,
keys
%{
$BOOKS
{
'You'
}}));
next
if
(
grep
(
$guess
eq
$_
,
@MY_PAST_GUESSES
));
if
( !
grep
(
$guess
eq
$_
,
@COMPUTERS_HAND
) ) {
push
(
@saveguess
,
$guess
);
next
;
}
push
(
@MY_PAST_GUESSES
,
$guess
);
return
(
$guess
);
}
@HIS_PAST_GUESSES
=
@saveguess
;
$guess
=(
keys
%h
)[
rand
scalar
keys
%h
];
push
(
@MY_PAST_GUESSES
,
$guess
);
return
(
$guess
);
}
sub
compguess {
my
(
$guess
,
$stat
);
do
{
print
"\nI ask you for: "
;
$guess
=pickone(\
@COMPUTERS_HAND
);
print
$guess
,
"\n"
;
}
while
(!
defined
(
$stat
=askfor(\
@COMPUTERS_HAND
, \
@PLAYERS_HAND
,
$guess
)));
havebook(\
@COMPUTERS_HAND
);
return
(
$stat
?0:
$guess
);
}
sub
playguess {
my
(
$guess
,
$stat
);
do
{
print
"\nYou ask me for: "
;
$guess
=<STDIN>;
chomp
(
$guess
);
}
while
(!
defined
(
$stat
=askfor(\
@PLAYERS_HAND
, \
@COMPUTERS_HAND
,
$guess
)));
push
(
@HIS_PAST_GUESSES
,
$guess
);
havebook(\
@PLAYERS_HAND
);
return
(
$stat
?0:
$guess
);
}
sub
draw {
my
(
$drawarr
,
$guess
)=
@_
;
my
$foo
=
pop
@DECK
;
die
(
"No more cards: S.N.H."
)
if
(!
$foo
);
if
(
$foo
eq
$guess
) {
print
"$asker drew the guess\n"
;
print
"$asker get to go again\n"
;
}
else
{
print
"$asker drew a $foo\n"
if
(
$asker
eq
'You'
);
@MY_PAST_GUESSES
=();
}
push
@$drawarr
,
$foo
;
return
(
$foo
);
}
sub
askfor {
my
(
$askarr
,
$vicarr
,
$card
)=
@_
;
$card
=
uc
$card
;
if
(
$card
eq
""
) {
print
"I have "
,
scalar
(
@COMPUTERS_HAND
),
" cards in my hand "
;
printhand(\
@COMPUTERS_HAND
,
'I'
, 1);
print
"There are "
,
scalar
(
@DECK
),
" cards remaining in the stock\n"
;
return
;
}
exit
if
(
$card
eq
'QUIT'
);
if
(
$card
eq
'P'
) {
$professional
=!
$professional
;
print
$professional
?
"Entering"
:
"Leaving"
,
" professional mode\n"
;
return
;
}
unless
(
exists
$iscard
{
$card
}) {
print
"I don't understand!\n"
;
return
;
}
if
(!
grep
(
$card
eq
$_
,
@$askarr
)) {
print
"$asker dont have any $card"
.
"s!\n"
;
return
;
}
if
(!
grep
(
$card
eq
$_
,
@$vicarr
)) {
print
"$opponent say \"GO FISH!\"\n"
;
return
0;
}
my
@GOOD
=
grep
(
$card
eq
$_
,
@$vicarr
);
@$vicarr
=(
grep
(
$card
ne
$_
,
@$vicarr
));
print
"$opponent have "
,
scalar
(
@GOOD
),
" $card"
, (
scalar
(
@GOOD
)>1)?
"s"
:
""
,
"\n"
;
print
"$asker get another guess!\n"
;
push
(
@$askarr
,
@GOOD
);
}
sub
havebook {
my
$array
=
shift
;
my
(
%hash
,
$flag
);
$flag
=0;
foreach
(
@$array
){
$hash
{
$_
}++;}
foreach
my
$value
(
keys
%hash
) {
if
(
$hash
{
$value
}==4) {
@$array
=
grep
( (
$_
ne
$value
),
@$array
);
print
"$asker made a book of "
,
$value
,
"s\n"
;
$BOOKS
{
$asker
}{
$value
}=1;
$flag
=1;
}
}
return
(
$flag
);
}
sub
printhand {
unless
(
$_
[2]) {
print
"$_[1] hand is: "
,
join
(
' '
,
sort
{ ((
$a
=~/^\d+$/)?
$a
:
$so
{
$a
}) <=> ((
$b
=~/^\d+$/)?
$b
:
$so
{
$b
}); }
@{
$_
[0]});
}
my
@bl
=
keys
%{
$BOOKS
{
$_
[1]}};
if
(
@bl
) {
print
" + Book"
,
scalar
(
@bl
)>1?
"s "
:
" "
,
join
(
' '
,
@bl
);
}
print
"\n"
;
}
getopts(
'p'
, \
%opt
) or
die
"Usage: $0 [-p]\n"
;
$professional
=
$opt
{
'p'
};
print
"Do you want to see instructions (y/n)?"
;
$status
=<STDIN>;
if
(
$status
=~/^y/i) {
print
<DATA>;
print
"Press <return>"
;
$status
=<STDIN>;
}
@DECK
= (
keys
%iscard
) x 4;
@DECK
= shuffle(
@DECK
);
foreach
(1..7) {
push
(
@PLAYERS_HAND
,
pop
@DECK
);
push
(
@COMPUTERS_HAND
,
pop
@DECK
);
}
$whoseturn
=
int
(
rand
(2));
print
$whoseturn
?
"You"
:
"I"
,
" get to start\n"
;
while
(1) {
print
"\n"
;
last
if
( (!
@PLAYERS_HAND
) or (!
@COMPUTERS_HAND
) );
printhand(\
@PLAYERS_HAND
,
"You"
);
$asker
=
$whoseturn
?
"You"
:
"I"
;
$opponent
=(!
$whoseturn
)?
"You"
:
"I"
;
my
$hand
;
if
(
$whoseturn
) {
$status
=playguess();
$hand
= \
@PLAYERS_HAND
;
}
else
{
$status
=compguess();
$hand
= \
@COMPUTERS_HAND
;
}
if
(
$status
) {
if
(draw(
$hand
,
$status
) eq
$status
) {
havebook(
$hand
);
redo
;
}
else
{
redo
if
(havebook(
$hand
));
$whoseturn
=!
$whoseturn
;
}
}
}
print
@COMPUTERS_HAND
?
"You"
:
"I"
,
" ran out of cards\n"
;
$myb
=
scalar
(
keys
%{
$BOOKS
{
'I'
}});
$yourb
=
scalar
(
keys
%{
$BOOKS
{
'You'
}});
print
"I had $myb Books and you had $yourb\n"
;
if
(
$myb
==
$yourb
) {
print
"It's a tie!\n"
;
}
else
{
print
$myb
>
$yourb
?
"I"
:
"You"
,
" win!\n"
;
}