Go Fish: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 246: Line 246:
=={{header|FutureBasic}}==
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
<syntaxhighlight lang="futurebasic">





Line 262: Line 263:
_window = 1
_window = 1
begin enum 1
begin enum 1
_scrollView
_scrollView
_textView
_textView
end enum
end enum


Line 283: Line 284:


local fn CheckForFaceCard(TheCard as short) as str255
local fn CheckForFaceCard(TheCard as short) as str255
str255 WantsCard
str255 WantsCard
WantsCard = str$(TheCard)
WantsCard = str$(TheCard)
WantsCard = Mid$(cards,k,1)
WantsCard = Mid$(cards,k,1)
if TheCard = 0 then WantsCard = "10"
if TheCard = 0 then WantsCard = "10"
if TheCard = 11 then WantsCard = "jack"
if TheCard = 11 then WantsCard = "jack"
if TheCard = 12 then WantsCard = "Queen"
if TheCard = 12 then WantsCard = "Queen"
if TheCard = 13 then WantsCard = "King"
if TheCard = 13 then WantsCard = "King"
if TheCard = 1 then WantsCard = "Ace"
if TheCard = 1 then WantsCard = "Ace"
end fn = WantsCard
end fn = WantsCard




void local fn PrintViewScrollToBottom( printView as ViewRef )
void local fn PrintViewScrollToBottom( printView as ViewRef )
'~'1
BeginCCode
BeginCCode
NSScrollView *scrollView = [printView enclosingScrollView];
NSScrollView *scrollView = [printView enclosingScrollView];
NSClipView *clipView = [scrollView contentView];
NSClipView *clipView = [scrollView contentView];
[clipView scrollToPoint:NSMakePoint(0,printView.frame.size.height-scrollView.contentSize.height + 20)];
[clipView scrollToPoint:NSMakePoint(0,printView.frame.size.height-scrollView.contentSize.height + 20)];
[scrollView reflectScrolledClipView:clipView];
[scrollView reflectScrolledClipView:clipView];
EndC
EndC
end fn
end fn




void local fn DealCards
void local fn DealCards

RemainingCards -= 1
RemainingCards -= 1
short sc
short sc
sc = rnd(RemainingCards)
sc = rnd(RemainingCards)

For k = 1 To 13
For k = 1 To 13
sc -= deck(k)
sc -= deck(k)
If sc <= 0 Then exit fn
If sc <= 0 Then exit fn
Next k
Next k

End fn
End fn


void local fn youGoFishing
void local fn youGoFishing

fn DealCards
fn DealCards

str255 WantsCard
str255 WantsCard
WantsCard = fn CheckForFaceCard(k)
WantsCard = fn CheckForFaceCard(k)

if WantsCard = "0" then WantsCard = "10"
if WantsCard = "0" then WantsCard = "10"

Print " " + WantsCard + "."
Print " " + WantsCard + "."
deck(k) -= 1
deck(k) -= 1
play(k) += 1
play(k) += 1

End fn
End fn


void local fn cpuGoFishing
void local fn cpuGoFishing

fn DealCards
fn DealCards
Print " a card from the deck."
Print " a card from the deck."
deck(k) -= 1
deck(k) -= 1
Computer(k) += 1
Computer(k) += 1

End fn
End fn





local fn InitCards
cards = "A234567890JQK"
RemainingCards = 4 * len$(cards) // the length of cards is 13. There are 4 suits of cards. so RemainingCards is 52
i = 0:k = 0:j = 0:CardNumber = 0
for i = 0 to 1
Points(i) = 0
next i
FOR i = 1 TO 13 ' Reset each element to 0
play(i) = 0
Computer(i) = 0
deck(i) = 0
guess(i) = 0
poss(i) = 0
asked(i) = 0
NEXT i
For i = 1 To 13
deck(i) = 4
Next i
For i = 1 To 9
fn DealCards
deck(k) -= 1
Computer(k) += 1
fn DealCards
deck(k) -= 1
play(k) += 1
Next i
end fn




void local fn CheckForCompletedBook
void local fn CheckForCompletedBook

For i = 1 To 13
For i = 1 To 13
If play(i) <> 4
If play(i) <> 4
Else
Else
text ,,fn colorcyan
text ,,fn colorcyan

str255 WantsCard
str255 WantsCard
WantsCard = Mid$(cards,i,1)
WantsCard = Mid$(cards,i,1)

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"
if WantsCard = "0" then WantsCard = "10"

Print YourName + " completed the book of " + WantsCard + "'s."
Print YourName + " completed the book of " + WantsCard + "'s."
text ,,fn colorWhite
text ,,fn colorWhite
play(i) = 0
play(i) = 0
Points(0) += 1
Points(0) += 1
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))
End If
End If
Next i
Next i

End fn
End fn


local fn CheckCPUForCompletedBook as boolean
local fn CheckCPUForCompletedBook

bool Completed = _false
For i = 1 To 13

For i = 1 To 13
If Computer(i) <> 4
Else
If Computer(i) <> 4
text ,,fn colorCyan
Else
str255 WantsCard
text ,,fn colorCyan
WantsCard = Mid$(cards,i,1)
str255 WantsCard

WantsCard = Mid$(cards,i,1)
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"

if WantsCard = "0" then WantsCard = "10"
Print "CPU completed the book of " + WantsCard + "'s."

Print "CPU completed the book of " + WantsCard + "'s."
text ,,fn colorWhite
Completed = _true
Computer(i) = 0
text ,,fn colorWhite
Computer(i) = 0
Points(1) += 1
fn PrintViewScrollToBottom( fn WindowPrintView(1))
Points(1) += 1
End If
fn PrintViewScrollToBottom( fn WindowPrintView(1))
Next i
End If

Next i
End fn

End fn = Completed

local fn InitCards

cards = "A234567890JQK"
RemainingCards = 4 * len$(cards) // the length of cards is 13. There are 4 suits of cards. so RemainingCards is 52
i = 0:k = 0:j = 0:CardNumber = 0

for i = 0 to 1
Points(i) = 0
next i

FOR i = 1 TO 13 ' Reset each element to 0
play(i) = 0
Computer(i) = 0
deck(i) = 0
guess(i) = 0
poss(i) = 0
asked(i) = 0

NEXT i


For i = 1 To 13
deck(i) = 4
Next i
For i = 1 To 9
fn DealCards
deck(k) -= 1
Computer(k) += 1
fn DealCards
deck(k) -= 1
play(k) += 1
Next i

fn CheckForCompletedBook // Rich added 5/1/24
fn CheckForCompletedBook // Rich added 5/1/24
end fn



local fn QuitOrPlayAlert(GameResult as CFStringRef)
local fn QuitOrPlayAlert(GameResult as CFStringRef)

alert -2,,GameResult,@"Game Over",@"Quit;Play Again"
alert -2,,GameResult,@"Game Over",@"Quit;Play Again"
AlertButtonSetKeyEquivalent( 2, 2, @"\e" )
AlertButtonSetKeyEquivalent( 2, 2, @"\e" )
short result
short result
result = alert 2
result = alert 2
if ( result != NSAlertSecondButtonReturn ) then end
if ( result != NSAlertSecondButtonReturn ) then end

end fn
end fn


local fn QuitOrResumeAlert(GameResult as CFStringRef)
local fn QuitOrResumeAlert(GameResult as CFStringRef)

alert -3,,GameResult,@"Quit the game?",@"Quit;Resume game"
alert -3,,GameResult,@"Quit the game?",@"Quit;Resume game"
AlertButtonSetKeyEquivalent( 3, 2, @"\e" )
AlertButtonSetKeyEquivalent( 3, 2, @"\e" )
short result
short result
result = alert 3
result = alert 3
if ( result != NSAlertSecondButtonReturn ) then end
if ( result != NSAlertSecondButtonReturn ) then end

end fn
end fn


local fn CheckForEndGame as boolean
local fn CheckForEndGame as boolean

bool PlayAgain = _False
bool PlayAgain = _False
short np = 0, nc = 0
short np = 0, nc = 0
For i = 1 To 13
For i = 1 To 13
np += play(i)
np += play(i)
nc += Computer(i)
nc += Computer(i)
Next i
Next i

If RemainingCards = <0 Or np = 0 Or nc = 0
If RemainingCards = <0 Or np = 0 Or nc = 0

text ,,fn colorRed
text ,,fn colorRed
Print "*** Game Over! ***"
Print "*** Game Over! ***"
Print
Print
If Points(0) < Points(1)
If Points(0) < Points(1)
Print "The CPU has won."
Print "The CPU has won."
print:print
print:print
fn QuitOrPlayAlert(@"the CPU won!")
fn QuitOrPlayAlert(@"the CPU won!")
PlayAgain = _True
PlayAgain = _True
Else if Points(0) > Points(1)
Else if Points(0) > Points(1)
Print YourName + " has won."
Print YourName + " has won."
print:print
print:print
fn QuitOrPlayAlert(@"You Won!")
fn QuitOrPlayAlert(@"You Won!")
PlayAgain = _True
PlayAgain = _True
Else
Else
Print "­It's a tie!"
Print "­It's a tie!"
fn QuitOrPlayAlert(@"It's a tie!.")
fn QuitOrPlayAlert(@"It's a tie!.")
PlayAgain = _True
PlayAgain = _True
End If
End If
fn PrintViewScrollToBottom( fn WindowPrintView(1) )
fn PrintViewScrollToBottom( fn WindowPrintView(1) )

End If
End If

PlayAgain = _True
PlayAgain = _True

End If
End If


Line 493: Line 500:


void local fn Intro
void local fn Intro

text ,,fn colorGreen
text ,,fn colorGreen
Print " __ _ _ "
Print " __ _ _ "
Print " __ _ ___ / _(_)___| |__ "
Print " __ _ ___ / _(_)___| |__ "
Print " / ` |/ _ \ | |_| / __| '_ \ "
Print " / ` |/ _ \ | |_| / __| '_ \ "
Print "| (_) | (_) | | _| \__ \ | | | "
Print "| (_) | (_) | | _| \__ \ | | | "
Print " \__, |\___/ |_| |_|___/_| |_| "
Print " \__, |\___/ |_| |_|___/_| |_| "
Print " |___/ "
Print " |___/ "
Print ""
Print ""

text ,,fn colorCyan
text ,,fn colorCyan
print %(301,90),"( x to exit the game )"
print %(301,90),"( x to exit the game )"
text ,,fn colorWhite
text ,,fn colorWhite

print " Go Fish Rules:"
print " Go Fish Rules:"
print
print
print " You are playing against the CPU."
print " You are playing against the CPU."
print " You are dealt nine cards to start with."
print " You are dealt nine cards to start with."
print " The remaining cards are placed face down in the center of the table"
print " The remaining cards are placed face down in the center of the table"
print " to form the draw pile (the fish pond)."
print " to form the draw pile (the fish pond)."
print " On your turn, you ask the CPU for a card."
print " On your turn, you ask the CPU for a card."
print " You must already have at least one card of a given rank to ask for more."
print " You must already have at least one card of a given rank to ask for more."
print " (A rank is one or more of any card.)"
print " (A rank is one or more of any card.)"
print " If the CPU has any cards of the named rank, it must hand over all such cards,"
print " If the CPU has any cards of the named rank, it must hand over all such cards,"
print " and you can then ask again."
print " and you can then ask again."
print " If the CPU has no cards of the named rank, a card will be drawn from the pile,"
print " If the CPU has no cards of the named rank, a card will be drawn from the pile,"
print " and placed in your hand, which then ends your turn."
print " and placed in your hand, which then ends your turn."
print " A book is a collection of four cards in a given rank."
print " A book is a collection of four cards in a given rank."
print " Whenever you complete a book, it will be removed from your hand."
print " Whenever you complete a book, it will be removed from your hand."
print " If at any time, your hand is empty, a new card will be drawn from the pile."
print " If at any time, your hand is empty, a new card will be drawn from the pile."
print " The game ends when every book is complete,"
print " The game ends when every book is complete,"
print " or there are no more cards left in the pile."
print " or there are no more cards left in the pile."
print " The player with the most books wins."
print " The player with the most books wins."


CFStringRef UserInput
CFStringRef UserInput
"InputYourName"
"InputYourName"
UserInput = input % (300, 70), @"What's your name?: "
UserInput = input % (300, 70), @"What's your name?: "
if ( UserInput == NULL ) then "InputYourName"
if ( UserInput == NULL ) then "InputYourName" // Rich added this 5/1/24
fn CFStringGetPascalString (UserInput, @YourName, 256, _kCFStringEncodingMacRoman)
fn CFStringGetPascalString (UserInput, @YourName, 256, _kCFStringEncodingMacRoman)
gNeedToClearScreen = _True
gNeedToClearScreen = _True
cls
cls

if YourName = "X" or YourName = "x" or YourName = chr$(127) then fn QuitOrResumeAlert(@"EXIT")
if YourName = "X" or YourName = "x" or YourName = chr$(127) then fn QuitOrResumeAlert(@"EXIT")

End fn
End fn




local fn WhatCardInputHeight as short
local fn WhatCardInputHeight as short

CGRect mainScreenFrame = fn ScreenMainFrame
CGRect mainScreenFrame = fn ScreenMainFrame
float InputHeight = int(mainScreenFrame.size.height - 120)
float InputHeight = int(mainScreenFrame.size.height - 120)

end fn = InputHeight
end fn = InputHeight




local fn BuildWindow
local fn BuildWindow

// ---> Get the size of the Main Screen. <---
// ---> Get the size of the Main Screen. <---
CGRect mainScreenFrame = fn ScreenMainFrame
CGRect mainScreenFrame = fn ScreenMainFrame
float msh = mainScreenFrame.size.height
float msh = mainScreenFrame.size.height
CGRect r = fn CGRectMake( 0, 0, 600, int(msh) - 110)
CGRect r = fn CGRectMake( 0, 0, 600, int(msh) - 110)

window 1, @"Go Fish", r
window 1, @"Go Fish", r
windowcenter(1)
windowcenter(1)
WindowSetBackgroundColor(1,fn ColorBlack)
WindowSetBackgroundColor(1,fn ColorBlack)

end fn
end fn


Line 583: Line 590:


While ShowHand = _false
While ShowHand = _false
text ,,fn colorGreen
text ,,fn colorGreen
Print Chr$(10) + "Points >> ";
Print Chr$(10) + "Points >> ";
text ,,fn colorYellow
text ,,fn colorYellow
print YourName + ": ";
print YourName + ": ";
text ,,fn colorGreen
text ,,fn colorGreen
print Points(0);
print Points(0);
text ,,fn colorOrange
text ,,fn colorOrange
print " CPU: ";
print " CPU: ";
text ,,fn colorGreen
text ,,fn colorGreen
print Points(1)
print Points(1)
text ,,fn colorWhite
text ,,fn colorWhite
Print Chr$(10) + " " + str$(RemainingCards) + " remaining cards"
Print Chr$(10) + " " + str$(RemainingCards) + " remaining cards"
text ,,fn colorWhite
text ,,fn colorWhite

/*
/*
// Uncomment this to see the CPU's cards for testing
// Uncomment this to see the CPU's cards for testing
Print Chr$(10) + "CPU Cards: ";
Print Chr$(10) + "CPU Cards: ";
For i = 1 To 13
For i = 1 To 13
if Computer(i) <> 0
if Computer(i) <> 0
For j = 1 To Computer(i)
For j = 1 To Computer(i)
if Mid$(cards,i,1) = "0"
if Mid$(cards,i,1) = "0"
Print @"10"; " ";
Print @"10"; " ";
else
else
Print Mid$(cards,i,1); " ";
Print Mid$(cards,i,1); " ";
end if
end if
Next j
Next j
End If
End If
Next i
Next i
Print
Print
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))
*/
*/


Print Chr$(10) + "Your Cards: ";
Print Chr$(10) + "Your Cards: ";
For i = 1 To 13
For i = 1 To 13
if play(i) <> 0
if play(i) <> 0
For j = 1 To play(i)
For j = 1 To play(i)
if Mid$(cards,i,1) = "0"
if Mid$(cards,i,1) = "0"
Print @"10"; " ";
Print @"10"; " ";
else
else
Print Mid$(cards,i,1); " ";
Print Mid$(cards,i,1); " ";
end if
end if
Next j
Next j
End If
End If
Next i
Next i
Print
Print
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))

RequestCard = _false
RequestCard = _false

While RequestCard = _false
While RequestCard = _false
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"

loopcounter ++
loopcounter ++
Someone = YourName
Someone = YourName

if gNeedToClearScreen = _False then fn PrintViewScrollToBottom( fn WindowPrintView(1) ):gNeedToClearScreen = _False
if gNeedToClearScreen = _False then fn PrintViewScrollToBottom( fn WindowPrintView(1) ):gNeedToClearScreen = _False

CFStringRef UserInput = 0
CFStringRef UserInput = 0
"InputCard"
"InputCard"
UserInput = input % (20, fn WhatCardInputHeight),@"What card do you want? "
UserInput = input % (20, fn WhatCardInputHeight),@"What card do you want? "
if ( UserInput == NULL ) then "InputCard"
if ( UserInput == NULL ) then "InputCard" // Rich added this 5/1/24
fn CFStringGetPascalString (UserInput, @RequestedCard, 256, _kCFStringEncodingMacRoman)
fn CFStringGetPascalString (UserInput, @RequestedCard, 256, _kCFStringEncodingMacRoman)
if RequestedCard = "10" then RequestedCard = "0"// card zero is a 10
if RequestedCard = "10" then RequestedCard = "0"// card zero is a 10
text ,,fn ColorYellow
text ,,fn ColorYellow
Print
Print

WantsCard = RequestedCard
WantsCard = RequestedCard

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"
if WantsCard = "0" then WantsCard = "10"

print "-------------------------------------"
print "-------------------------------------"
print
print
str255 AorAn
str255 AorAn
AorAn = "a"
AorAn = "a"
if WantsCard = "Ace" then AorAn = "an"
if WantsCard = "Ace" then AorAn = "an"
print YourName + " asked for " + AorAn + " " + WantsCard
print YourName + " asked for " + AorAn + " " + WantsCard
print
print
text ,,fn ColorWhite
text ,,fn ColorWhite

fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))

if RequestedCard = "X" or RequestedCard = "x" then fn QuitOrResumeAlert(@"EXIT")
if RequestedCard = "X" or RequestedCard = "x" then fn QuitOrResumeAlert(@"EXIT")

CardNumber = 0
If RequestedCard <> "" Then CardNumber = Instr$(1,cards, Ucase$(RequestedCard)): RequestCard = _true
If RequestedCard <> "" Then CardNumber = Instr$(1,cards, Ucase$(RequestedCard)): RequestCard = _true

If CardNumber = 0
If CardNumber = 0
text,,fn ColorRed
text,,fn ColorRed
Print "Sorry, that is not a valid card.": RequestCard = _false
Print "Sorry, that is not a valid card.": RequestCard = _false
print
print
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))
Else if play(CardNumber) = 0 Then text ,,fn colorRed: Print "You don't have that card!": text ,,fn colorRed: RequestCard = _false
Else if play(CardNumber) = 0 Then text ,,fn colorRed: Print "You don't have that card!": text ,,fn colorRed: RequestCard = _false
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))
text,,fn ColorWhite
text,,fn ColorWhite

End If
End If
// loopcounter should never reach 100 but just in case, prevent hangs
// loopcounter should never reach 100 but just in case, prevent hangs
if loopcounter > 100 then loopcounter = 0:exit while
if loopcounter > 100 then loopcounter = 0:exit while
Wend
Wend

guess(CardNumber) = 1
guess(CardNumber) = 1

If Computer(CardNumber) = 0
If Computer(CardNumber) = 0
Print Someone + ",";
Print Someone + ",";
text ,,fn colorRed
text ,,fn colorRed
Print " Go fish!"
Print " Go fish!"
text ,,fn colorWhite
text ,,fn colorWhite
Print Someone + " got a";: fn youGoFishing
Print Someone + " got a";: fn youGoFishing
print
print
fn CheckForCompletedBook
fn CheckForCompletedBook
ShowHand = _true
ShowHand = _true
Else
Else
v = Computer(CardNumber)
v = Computer(CardNumber)
Computer(CardNumber) = 0
Computer(CardNumber) = 0
play(CardNumber) += v
play(CardNumber) += v
if v > 1 then AddTheS = "s" else AddTheS = ""
if v > 1 then AddTheS = "s" else AddTheS = ""
Print Someone + " got" + str$(v) + " card" + AddTheS
Print Someone + " got" + str$(v) + " card" + AddTheS
fn CheckForCompletedBook
fn CheckForCompletedBook
fn PrintViewScrollToBottom( fn WindowPrintView(1))
fn PrintViewScrollToBottom( fn WindowPrintView(1))
ShowHand = _false
ShowHand = _false
End If
End If
// loopcounter should never reach 100 but just in case, prevent hangs
// loopcounter should never reach 100 but just in case, prevent hangs
if loopcounter > 100 then loopcounter = 0:exit while
if loopcounter > 100 then loopcounter = 0:exit while
Wend
Wend


Line 716: Line 723:
Someone = "CPU"
Someone = "CPU"
For i = 1 To 13
For i = 1 To 13
asked(i) = 0
asked(i) = 0
Next i
Next i


Line 722: Line 729:


While CPUsTurn = _false
While CPUsTurn = _false
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"

po = 0
po = 0
For i = 1 To 13
For i = 1 To 13
If (Computer(i) > 0) And (guess(i) > 0) Then poss(i) = 1: po += 1
If (Computer(i) > 0) And (guess(i) > 0) Then poss(i) = 1: po += 1
Next i
Next i

If po = 0
If po = 0
// this k is the card the CPU gets after go fish
// this k is the card the CPU gets after go fish
while computer(k) = 0 Or asked(k)
while computer(k) = 0 Or asked(k)
k = rnd(12)+1
k = rnd(12)+1
wend
wend
Else
Else
// this k is the card you get after go fish
// this k is the card you get after go fish
while poss(k) = 0
while poss(k) = 0
k = rnd(12) + 1
k = rnd(12) + 1
wend
wend

guess(k) = 0
guess(k) = 0
asked(k) = 1
asked(k) = 1

end if
end if



WantsCard = fn CheckForFaceCard(k)

WantsCard = fn CheckForFaceCard(k)
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"

if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "0" then WantsCard = "10"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"
text ,,fn ColorOrange

text ,,fn ColorOrange
print "-------------------------------------"

print "-------------------------------------"
Print:Print Someone + " wants your " + wantsCard + "'s."

print
Print:Print Someone + " wants your " + wantsCard + "'s."
print
text ,,fn ColorWhite

text ,,fn ColorWhite
asked(k) = 1

If play(k) = 0
asked(k) = 1

Print Someone + ", ";
If play(k) = 0
text ,,fn colorRed: Print "go fish!"
text ,,fn colorWhite:Print Someone + " got";: fn cpuGoFishing
Print Someone + ", ";
text ,,fn colorRed: Print "go fish!"
text ,,fn colorWhite:Print Someone + " got";: fn cpuGoFishing
if fn CheckCPUForCompletedBook then CPUsTurn = _false else CPUsTurn = _true
fn CheckCPUForCompletedBook
CPUsTurn = _true

Else
Else

v = play(k)
play(k) = 0
v = play(k)
Computer(k) += v
play(k) = 0
Computer(k) += v
if v > 1 then AddTheS = "s" else AddTheS = ""
Print Someone + " got" + str$(v) + " card" + AddTheS
if v > 1 then AddTheS = "s" else AddTheS = ""
Print Someone + " got" + str$(v) + " card" + AddTheS
fn CheckCPUForCompletedBook
fn CheckCPUForCompletedBook
CPUsTurn = _false
CPUsTurn = _false
End If
End If


Wend
Wend


Line 792: Line 800:


handleevents
handleevents






Revision as of 15:25, 1 May 2024

Task
Go Fish
You are encouraged to solve this task according to the task description, using any language you may know.

Write a program to let the user play Go Fish against a computer opponent. Use the following rules:

  • Each player is dealt nine cards to start with.
  • On their turn, a player asks their opponent for a given rank (such as threes or kings). A player must already have at least one card of a given rank to ask for more.
    • If the opponent has any cards of the named rank, they must hand over all such cards, and the requester can ask again.
    • If the opponent has no cards of the named rank, the requester draws a card and ends their turn.
  • A book is a collection of every card of a given rank. Whenever a player completes a book, they may remove it from their hand.
  • If at any time a player's hand is empty, they may immediately draw a new card, so long as any new cards remain in the deck.
  • The game ends when every book is complete. The player with the most books wins.

The game's AI need not be terribly smart, but it should use at least some strategy. That is, it shouldn't choose legal moves entirely at random.

You may want to use code from Playing Cards.

Related tasks:


Aime

See Go Fish/Aime

AutoHotkey

See Go Fish/AutoHotkey

C

See Go Fish/C

C++

See Go Fish/C++

D

See Go Fish/D

Erlang

See Go Fish/Erlang

FreeBASIC

' Go Fish ~ ¡Pesca!

Const cartas = "A234567890JQK"

Declare Sub Reparto_Cartas
Declare Sub Pescar_Carta_Jug
Declare Sub Pescar_Carta_CPU
Declare Sub Comprobar_Libro_Jug
Declare Sub Comprobar_Libro_CPU
Declare Sub Comprobar_Fin_Partida
Declare Sub Intro

Dim Shared As Integer play(13), compu(13), deck(13), guess(13), poss(13), asked(13)
Dim Shared As String nombre, Snombre, CartaPedida
Dim Shared puntos(2) As Byte = {0,0}
Dim Shared As Integer remca = 4*Len(cartas)
Dim Shared As Integer i, k, j, cn
For i = 1 To 13
    deck(i) = 4
Next i
For i = 1 To 9
    Reparto_Cartas
    deck(k) -= 1
    compu(k) += 1
    Reparto_Cartas
    deck(k) -= 1
    play(k) += 1
Next i
Dim As Integer v, po

Sub Reparto_Cartas
    remca -= 1
    Dim As Integer sc = remca * Rnd + 1
    For k = 1 To 13
        sc -= deck(k)
        If sc <= 0 Then Return
    Next k
End Sub

Sub Pescar_Carta_Jug
    Reparto_Cartas
    Print " " &Mid(cartas,k,1) &"."
    deck(k) -= 1
    play(k) += 1
End Sub

Sub Pescar_Carta_CPU
    Reparto_Cartas
    Print "a carta."
    deck(k) -= 1
    compu(k) += 1
End Sub

Sub Comprobar_Libro_Jug
    For i = 1 To 13
        If play(i) <> 4 Then
        Else
            Color 11: Print Snombre &" completa el libro de " &Mid(cartas,i,1) &"'s.": Color 7
            play(i) = 0
            puntos(0) += 1
        End If
    Next i
End Sub

Sub Comprobar_Libro_CPU
    For i = 1 To 13
        If compu(i) <> 4 Then
        Else
            Color 11: Print Snombre &" completa el libro de " &Mid(cartas,i,1) &"'s.": Color 7
            compu(i) = 0
            puntos(1) += 1
        End If
    Next i
End Sub

Sub Comprobar_Fin_Partida
    Dim As Integer np = 0, nc = 0
    For i = 1 To 13
        np += play(i)
        nc += compu(i)
    Next i
    If remca = 0 Or np = 0 Or nc = 0 Then         
        Color 15: Print
        Print "*** ­FIN de la partida! ***"
        Print
        If puntos(0) < puntos(1) Then 
            Print "La CPU ha ganado."
        Elseif puntos(0) > puntos(1) Then 
            Print nombre &" ha ganado." 
        Else 
            Print "­Es un empate!"
        End If
        Sleep: End
    End If
End Sub

Sub Intro
    Color 15 
    Print "                __ _     _      "
    Print "  __ _  ___    / _(_)___| |__   "
    Print " /  ` |/ _ \  | |_| / __| '_ \  "
    Print "| (_) | (_) | |  _| \__ \ | | | "
    Print " \__, |\___/  |_| |_|___/_| |_| "
    Print " |___/                          "
    Print "                                "
    Color 14: Locate 10, 2: Input "Como te llamas: ", nombre
End Sub

'--- Programa Principal ---
Cls
Randomize Timer
Intro
Do
    Dim As boolean MuestraMano = false
    While MuestraMano = false
        Color 15: Print Chr(10) &"Puntos >> " &nombre &": "; puntos(0); "  CPU: "; puntos(1)
        Color 13: Print Chr(10) &space(10) &remca &" cartas restantes"
        Color 14: Print Chr(10) &"Tu mano: ";
        For i = 1 To 13
            If Not play(i) Then 
                For j = 1 To play(i)
                    Print Mid(cartas,i,1); " ";
                Next j
            End If
        Next i
        Print
        
        Dim As boolean PideCarta = false
        While PideCarta = false
            Comprobar_Fin_Partida
            Snombre = nombre
            Color 7: Print
            Input "¨Que carta pides... "; CartaPedida
            Print
            If CartaPedida <> "" Then cn = Instr(cartas, Ucase(CartaPedida)): PideCarta = true
            If cn = 0 Then 
                Print "Lo siento, no es una opción valida.": PideCarta = false
                Elseif play(cn) = 0 Then Color 12: Print "­No tienes esa carta!": Color 7: PideCarta = false
            End If
        Wend
        
        guess(cn) = 1
        If compu(cn) = 0 Then 
            Print Snombre &", ";
            Color 15: Print "­ve a pescar!"
            Color 7: Print Snombre &" pesca un";: Pescar_Carta_Jug
            Comprobar_Libro_Jug
            MuestraMano = true
        Else
            v = compu(cn)
            compu(cn) = 0
            play(cn) += v
            Print Snombre &" consigue " &v &" carta(s) mas."
            Comprobar_Libro_Jug
            MuestraMano = false
        End If
    Wend

    Snombre = "CPU"
    For i = 1 To 13
        asked(i) = 0
    Next i
    Dim As boolean Turno_CPU_2 = false
    While Turno_CPU_2 = false
        Comprobar_Fin_Partida
        po = 0
        For i = 1 To 13
            If (compu(i) > 0) And (guess(i) > 0) Then poss(i) = 1: po += 1
        Next i
        If po = 0 Then 
            Do
                k = (Rnd*12)+1
            Loop While compu(k) = 0 Or asked(k)
        Else
            Do
                k = (Rnd*12)+1
            Loop While poss(k) = 0
            guess(k) = 0
            asked(k) = 1
        End If

        Print: Print Snombre &" quiere tus " &Mid(cartas,k,1) &"'s."
        asked(k) = 1
        If play(k) = 0 Then 
            Print Snombre &", ";
            Color 15: Print "­ve a pescar!"
            Color 7:Print Snombre &" pesca un";: Pescar_Carta_CPU
            Comprobar_Libro_CPU
            Turno_CPU_2 = true
        Else
            v = play(k)
            play(k) = 0
            compu(k) += v
            Print Snombre &" consigue " &v &" carta(s) mas."
            Comprobar_Libro_CPU
            Turno_CPU_2 = false
        End If
    Wend 
Loop
End

FutureBasic

/*

Go Fish
-- Rich Love --

FutureBasic app for Macintosh
Get the latest FutureBasic here 
http://www.brilorsoftware.com/fb/pages/home.html

*/


_window = 1
begin enum 1
_scrollView
_textView
end enum

override _forLoopsAlwaysExecuteAtLeastOnce = _true

begin globals

str255 cards
cards = "A234567890JQK"
short play(13), Computer(13), deck(13), guess(13), poss(13), asked(13)
str255 YourName, Someone,RequestedCard
bool gNeedToClearScreen
short Points(2) : Points(0) = 0 : Points(1) = 0
short i, k, j, CardNumber
short RemainingCards

end globals


local fn CheckForFaceCard(TheCard as short) as str255
str255 WantsCard
WantsCard = str$(TheCard)
WantsCard = Mid$(cards,k,1)
if TheCard = 0 then WantsCard = "10"
if TheCard = 11 then WantsCard = "jack"
if TheCard = 12 then WantsCard = "Queen"
if TheCard = 13 then WantsCard = "King"
if TheCard = 1 then WantsCard = "Ace"
end fn = WantsCard


void local fn PrintViewScrollToBottom( printView as ViewRef )
'~'1
BeginCCode
    NSScrollView *scrollView = [printView enclosingScrollView];
    NSClipView *clipView = [scrollView contentView];
    [clipView scrollToPoint:NSMakePoint(0,printView.frame.size.height-scrollView.contentSize.height + 20)];
    [scrollView reflectScrolledClipView:clipView];
  EndC
end fn


void local fn DealCards

RemainingCards -= 1
short sc
sc = rnd(RemainingCards)

For k = 1 To 13
sc -= deck(k)
If sc <= 0 Then exit fn
Next k

End fn

void local fn youGoFishing

fn DealCards

str255 WantsCard
WantsCard = fn CheckForFaceCard(k)

if WantsCard = "0" then WantsCard = "10"

Print " "  + WantsCard + "."
deck(k) -= 1
play(k) += 1

End fn

void local fn cpuGoFishing

fn DealCards
Print " a card from the deck."
deck(k) -= 1
Computer(k) += 1

End fn





void local fn CheckForCompletedBook

For i = 1 To 13
If play(i) <> 4
Else
text ,,fn colorcyan

str255 WantsCard
WantsCard = Mid$(cards,i,1)

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"

Print YourName + " completed the book of " + WantsCard + "'s."
text ,,fn colorWhite
play(i) = 0
Points(0) += 1
fn PrintViewScrollToBottom( fn WindowPrintView(1))
End If
Next i

End fn

local fn CheckCPUForCompletedBook

For i = 1 To 13

If Computer(i) <> 4
Else
text ,,fn colorCyan
str255 WantsCard
WantsCard = Mid$(cards,i,1)

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"

Print "CPU completed the book of " + WantsCard + "'s."

text ,,fn colorWhite
Computer(i) = 0
Points(1) += 1
fn PrintViewScrollToBottom( fn WindowPrintView(1))
End If
Next i

End fn


local fn InitCards

cards = "A234567890JQK"
RemainingCards = 4 * len$(cards)  // the length of cards is 13. There are 4 suits of cards. so RemainingCards is 52
i = 0:k = 0:j = 0:CardNumber = 0

for i = 0 to 1
Points(i) = 0
next i

FOR i = 1 TO 13 ' Reset each element to 0
play(i) = 0
Computer(i) = 0
deck(i) = 0
guess(i) = 0
poss(i) = 0
asked(i) = 0

NEXT i


For i = 1 To 13
deck(i) = 4
Next i
For i = 1 To 9
fn DealCards
deck(k) -= 1
Computer(k) += 1
fn DealCards
deck(k) -= 1
play(k) += 1
Next i

fn CheckForCompletedBook  // Rich added 5/1/24
fn CheckForCompletedBook  // Rich added 5/1/24
end fn


local fn QuitOrPlayAlert(GameResult as CFStringRef)

alert -2,,GameResult,@"Game Over",@"Quit;Play Again"
AlertButtonSetKeyEquivalent( 2, 2, @"\e" )
short result
result = alert 2
if ( result != NSAlertSecondButtonReturn ) then end

end fn

local fn QuitOrResumeAlert(GameResult as CFStringRef)

alert -3,,GameResult,@"Quit the game?",@"Quit;Resume game"
AlertButtonSetKeyEquivalent( 3, 2, @"\e" )
short result
result = alert 3
if ( result != NSAlertSecondButtonReturn ) then end

end fn

local fn CheckForEndGame as boolean

bool PlayAgain = _False
short np = 0, nc = 0
For i = 1 To 13
np += play(i)
nc += Computer(i)
Next i

If RemainingCards = <0 Or np = 0 Or nc = 0

text ,,fn colorRed
Print "*** Game Over! ***"
Print
If Points(0) < Points(1)
Print "The CPU has won."
print:print
fn QuitOrPlayAlert(@"the CPU won!")
PlayAgain = _True
Else if Points(0) > Points(1)
Print YourName + " has won."
print:print
fn QuitOrPlayAlert(@"You Won!")
PlayAgain = _True
Else
Print "­It's a tie!"
fn QuitOrPlayAlert(@"It's a tie!.")
PlayAgain = _True
End If
fn PrintViewScrollToBottom( fn WindowPrintView(1) )

End If

PlayAgain = _True

End If

End fn = PlayAgain


void local fn Intro

text ,,fn colorGreen
Print "                __ _     _      "
Print "  __ _  ___    / _(_)___| |__   "
Print " /  ` |/ _ \  | |_| / __| '_ \  "
Print "| (_) | (_) | |  _| \__ \ | | | "
Print " \__, |\___/  |_| |_|___/_| |_| "
Print " |___/                          "
Print ""

text ,,fn colorCyan
print %(301,90),"( x to exit the game )"
text ,,fn colorWhite

print " Go Fish Rules:"
print
print " You are playing against the CPU."
print " You are dealt nine cards to start with."
print " The remaining cards are placed face down in the center of the table"
print " to form the draw pile (the fish pond)."
print " On your turn, you ask the CPU for a card."
print " You must already have at least one card of a given rank to ask for more."
print " (A rank is one or more of any card.)"
print " If the CPU has any cards of the named rank, it must hand over all such cards,"
print " and you can then ask again."
print " If the CPU has no cards of the named rank, a card will be drawn from the pile,"
print " and placed in your hand, which then ends your turn."
print " A book is a collection of four cards in a given rank."
print " Whenever you complete a book, it will be removed from your hand."
print " If at any time, your hand is empty, a new card will be drawn from the pile."
print " The game ends when every book is complete,"
print " or there are no more cards left in the pile."
print " The player with the most books wins."


CFStringRef UserInput
"InputYourName"
UserInput = input % (300, 70), @"What's your name?: "
if ( UserInput == NULL ) then "InputYourName" // Rich added this 5/1/24
fn CFStringGetPascalString (UserInput, @YourName, 256, _kCFStringEncodingMacRoman)
gNeedToClearScreen = _True
cls

if YourName = "X" or YourName = "x" or YourName = chr$(127) then fn QuitOrResumeAlert(@"EXIT")

End fn


local fn WhatCardInputHeight as short

CGRect mainScreenFrame = fn ScreenMainFrame
float InputHeight = int(mainScreenFrame.size.height - 120)

end fn = InputHeight


local fn BuildWindow

// ---> Get the size of the Main Screen. <---
CGRect mainScreenFrame = fn ScreenMainFrame
float msh = mainScreenFrame.size.height
CGRect r = fn CGRectMake( 0, 0, 600, int(msh) - 110)

window 1, @"Go Fish", r
windowcenter(1)
WindowSetBackgroundColor(1,fn ColorBlack)

end fn

'--- Start ---

fn BuildWindow

fn Intro

fn InitCards

str255 AddTheS
bool RequestCard = _false
short v = 0
short po = 0
boolean ShowHand = _false
str255 WantsCard

"Main"

ShowHand = _false
short loopcounter = 0

While ShowHand = _false
text ,,fn colorGreen
Print Chr$(10)  + "Points >> ";
text ,,fn colorYellow
print YourName + ": ";
text ,,fn colorGreen
print Points(0);
text ,,fn colorOrange
print "  CPU: ";
text ,,fn colorGreen
print Points(1)
text ,,fn colorWhite
Print Chr$(10) + "          " + str$(RemainingCards) + " remaining cards"
text ,,fn colorWhite

/*
// Uncomment this to see the CPU's cards for testing
Print Chr$(10) + "CPU Cards:  ";
For i = 1 To 13
if Computer(i) <> 0
For j = 1 To Computer(i)
if Mid$(cards,i,1) = "0"
Print @"10"; " ";
else
Print Mid$(cards,i,1); " ";
end if
Next j
End If
Next i
Print
fn PrintViewScrollToBottom( fn WindowPrintView(1))
*/


Print Chr$(10) + "Your Cards: ";
For i = 1 To 13
if play(i) <> 0
For j = 1 To play(i)
if Mid$(cards,i,1) = "0"
Print @"10"; " ";
else
Print Mid$(cards,i,1); " ";
end if
Next j
End If
Next i
Print
fn PrintViewScrollToBottom( fn WindowPrintView(1))

RequestCard = _false

While RequestCard = _false
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"

loopcounter ++
Someone = YourName

if gNeedToClearScreen = _False then fn PrintViewScrollToBottom( fn WindowPrintView(1) ):gNeedToClearScreen = _False

CFStringRef UserInput = 0
"InputCard"
UserInput = input % (20, fn WhatCardInputHeight),@"What card do you want? "
if ( UserInput == NULL ) then "InputCard" // Rich added this 5/1/24
fn CFStringGetPascalString (UserInput, @RequestedCard, 256, _kCFStringEncodingMacRoman)
if RequestedCard = "10" then RequestedCard = "0"// card zero is a 10
text ,,fn ColorYellow
Print

WantsCard = RequestedCard

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"

print "-------------------------------------"
print
str255 AorAn
AorAn  = "a"
if WantsCard = "Ace" then AorAn = "an"
print YourName + " asked for " + AorAn + " " + WantsCard
print
text ,,fn ColorWhite

fn PrintViewScrollToBottom( fn WindowPrintView(1))

if RequestedCard = "X" or RequestedCard = "x" then fn QuitOrResumeAlert(@"EXIT")

If RequestedCard <> "" Then CardNumber = Instr$(1,cards, Ucase$(RequestedCard)): RequestCard = _true

If CardNumber = 0
text,,fn ColorRed
Print "Sorry, that is not a valid card.": RequestCard = _false
print
fn PrintViewScrollToBottom( fn WindowPrintView(1))
Else if play(CardNumber) = 0 Then text ,,fn colorRed: Print "You don't have that card!": text ,,fn colorRed: RequestCard = _false
fn PrintViewScrollToBottom( fn WindowPrintView(1))
text,,fn ColorWhite

End If
// loopcounter should never reach 100 but just in case, prevent hangs
if loopcounter > 100 then  loopcounter = 0:exit while
Wend

guess(CardNumber) = 1

If Computer(CardNumber) = 0
Print Someone + ",";
text ,,fn colorRed
Print " Go fish!"
text ,,fn colorWhite
Print Someone + " got a";: fn youGoFishing
print
fn CheckForCompletedBook
ShowHand = _true
Else
v = Computer(CardNumber)
Computer(CardNumber) = 0
play(CardNumber) += v
if v > 1 then AddTheS = "s" else AddTheS = ""
Print Someone + " got" + str$(v) + " card" + AddTheS
fn CheckForCompletedBook
fn PrintViewScrollToBottom( fn WindowPrintView(1))
ShowHand = _false
End If
// loopcounter should never reach 100 but just in case, prevent hangs
if loopcounter > 100 then  loopcounter = 0:exit while
Wend



Someone = "CPU"
For i = 1 To 13
asked(i) = 0
Next i

bool CPUsTurn = _false

While CPUsTurn = _false
if fn CheckForEndGame = _True then cls:fn InitCards:goto "Loop"

po = 0
For i = 1 To 13
If (Computer(i) > 0) And (guess(i) > 0) Then poss(i) = 1: po += 1
Next i

If po = 0
// this k is the card the CPU gets after go fish
while computer(k) = 0 Or asked(k)
k = rnd(12)+1
wend
Else
// this k is the card you get after go fish
while poss(k) = 0
k = rnd(12) + 1
wend

guess(k) = 0
asked(k) = 1

end if




WantsCard = fn CheckForFaceCard(k)

if WantsCard = "j" or WantsCard = "J" then WantsCard = "Jack"
if WantsCard = "q" or WantsCard = "Q" then WantsCard = "Queen"
if WantsCard = "k" or WantsCard = "K" then WantsCard = "King"
if WantsCard = "a" or WantsCard = "A" then WantsCard = "Ace"
if WantsCard = "0" then WantsCard = "10"

text ,,fn ColorOrange

print "-------------------------------------"

Print:Print Someone + " wants your " + wantsCard + "'s."
print

text ,,fn ColorWhite

asked(k) = 1

If play(k) = 0
Print Someone + ", ";
text ,,fn colorRed: Print "go fish!"
text ,,fn colorWhite:Print Someone + " got";: fn cpuGoFishing
fn CheckCPUForCompletedBook
CPUsTurn = _true

Else

v = play(k)
play(k) = 0
Computer(k) += v
if v > 1 then AddTheS = "s" else AddTheS = ""
Print Someone + " got" + str$(v) + " card" + AddTheS
fn CheckCPUForCompletedBook
CPUsTurn = _false
End If


Wend

"Loop"
goto "Main"


handleevents

Go

See Go Fish/Go

Haskell

See Go Fish/Haskell

Icon and Unicon

See Go Fish/Unicon

J

See Go Fish/J

Java

See Go Fish/Java

Julia

see Go Fish/Julia

Kotlin

See Go Fish/Kotlin

Lua

See Go Fish/Lua

Locomotive Basic

See Go Fish/Locomotive Basic

Mathematica / Wolfram Language

See Go Fish/Mathematica

Nim

See Go Fish/Nim

OCaml

See Go Fish/OCaml

Perl

#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Go_Fish
use warnings;
use List::Util qw( first shuffle );

my $pat = qr/[atjqk2-9]/; # ranks
my $deck = join '', shuffle map { my $rank = $_; map "$rank$_", qw( S H C D ) }
  qw( a t j q k ), 2 .. 9;

my $mebooks = my $youbooks = 0;

my $me = substr $deck, 0, 2 * 9, '';
my $mepicks = join '', $me =~ /$pat/g;
arrange($me);
$mebooks++ while $me =~ s/($pat).\1.\1.\1.//;
my $you = substr $deck, 0, 2 * 9, '';
my $youpicks = join '', $you =~ /$pat/g;
arrange($you);
$youbooks++ while $you =~ s/($pat).\1.\1.\1.//;

while( $mebooks + $youbooks < 13 )
  {
  play( \$you, \$youbooks, \$youpicks, \$me, \$mebooks, 1 );
  $mebooks + $youbooks == 13 and last;
  play( \$me, \$mebooks, \$mepicks, \$you, \$youbooks, 0 );
  }
print "me $mebooks you $youbooks\n";

sub arrange { $_[0] = join '', sort $_[0] =~ /../g }

sub human
  {
  my $have = shift =~ s/($pat).\K(?!\1)/ /gr;
  local $| = 1;
  my $pick;
  do
    {
    print "You have $have, enter request: ";
    ($pick) = lc(<STDIN>) =~ /$pat/g;
    } until $pick and $have =~ /$pick/;
  return $pick;
  }

sub play
  {
  my ($me, $mb, $lastpicks, $you, $yb, $human) = @_;
  my $more = 1;
  while( arrange( $$me ), $more and $$mb + $$yb < 13 )
    {
#   use Data::Dump 'dd'; dd \@_, "deck $deck";
    if( $$me =~ s/($pat).\1.\1.\1.// )
      {
      print "book of $&\n";
      $$mb++;
      }
    elsif( $$me )
      {
      my $pick = $human ? do { human($$me) } : do
        {
        my %picks;
        $picks{$_}++ for my @picks = $$me =~ /$pat/g;
        my $pick = first { $picks{$_} } split(//, $$lastpicks), shuffle @picks;
        print "pick $pick\n";
        $$lastpicks =~ s/$pick//g;
        $$lastpicks .= $pick;
        $pick;
        };
      if( $$you =~ s/(?:$pick.)+// )
        {
        $$me .= $&;
        }
      else
        {
        print "GO FISH !!\n";
        $$me .= substr $deck, 0, 2, '';
        $more = 0;
        }
      }
    elsif( $deck )
      {
      $$me .= substr $deck, 0, 2, '';
      }
    else
      {
      $more = 0;
      }
    }
  arrange( $$me );
  }

Phix

See Go Fish/Phix

PicoLisp

See Go Fish/PicoLisp

PowerShell

See Go Fish/PowerShell

PureBasic

See Go Fish/PureBasic

Python

See Go Fish/Python

Raku

(formerly Perl 6) See Go Fish/Raku

Red

Red [
    Title:  "Go Fish"
    Author: "gltewalt"
]
 
chand: []   ;-- c and p = computer and player
cguesses: []
phand: []
cbooks: 0
pbooks: 0
gf: {
    ***************
    *   GO FISH   *
    ***************
}
pip: ["a" "2" "3" "4" "5" "6" "7" "8" "9" "10" "j" "q" "k"] ;-- suits are not relevant
pile: []    ;-- where discarded cards go
 
;---------------------
;  Helper functions  -                                           
;---------------------
 
clear-screen: does [
    "clears the console"
    call/console either system/platform = 'Linux ["clear"]["cls"]
]
 
clear-and-show: func [duration str][
    {
        Poor persons animation. 
        Blips message to screen after a pause of duration length.

    }
    clear-screen
    print str 
    wait duration 
    clear-screen
]
 
deal-cards: func [num hand][ 
    loop num [
        append hand rejoin [trim/all form take deck]
    ] 
]
 
find-in: func [blk str][
    "Finds a string value in a block. Series in series."
    foreach i blk [if find i str [return i]]
]
 
go-fish: func [num hand][
    either not empty? deck [
        deal-cards num hand
    ][
        append hand rejoin [trim/all form take pile]    ;-- take from pile if deck is empty
    ]
]
 
guess-from: func [hand guessed][
    {
        Randomly picks from hand minus guessed.

        Simulates a person asking for different cards on
        their next turn if their previous guess resulted
        in a Go Fish.
    }
    random/seed now/time
    either any [empty? guessed empty? exclude hand guessed][
        random/only hand 
    ][
        random/only exclude hand guessed
    ]
]
 
make-deck: function [] [
    "make-deck and shuffle from https://rosettacode.org/wiki/Playing_cards#Red"
     new-deck: make block! 52
     foreach p pip [loop 4 [append/only new-deck p]]
     return new-deck
]

show-cards: does [
    clear-and-show 0 ""
    print [newline "Player cards:" newline sort phand newline]
    print ["Computer books:" cbooks]
    print ["Player books:" pbooks newline]
]

shuffle: function [deck [block!]] [deck: random deck]
 
;------------- end of helper functions -----------------

check-for-books: func [
    {
        Checks for a book in a players hand.
        Increments the players book score, and
        discards the book from the players hand
    }
    hand "from or to hand"
    kind "rank of cards"
    /local 
        c "collected"
][
    c: collect [
        forall hand [keep find hand/1 kind]
    ]
    remove-each i c [none = i] 
    if 4 = length? c [
        either hand = phand [pbooks: pbooks + 1][cbooks: cbooks + 1]
        remove-each i hand [if find/only c i [i]]   ;-- remove book from hand
        forall c [append pile c/1]  ;-- append discarded book to the pile
    ]
]
 
transfer-cards: func [
    "Transfers cards from player to player"
    fhand "from hand"
    thand "to hand"
    kind "rank of cards"
    /local 
        c "collected"
][
    c: collect [forall fhand [keep find fhand/1 kind]]
    remove-each i c [none = i]  ;-- remove none values from collected
    forall c [append thand c/1] ;-- append remaining values to "to hand"
    remove-each i fhand [if find/only c i [i]] ;-- remove those values from "from hand"
]
 
computer-turn: func [
    fhand "from hand"
    thand "to hand"
    kind  "rank of cards"
    /local 
        a 
][
    a: ask rejoin ["Do you have any " kind " s? "]
    if a = "x" [halt]
    either any [a = "y" a = "yes"][
        check-for-books thand kind
        transfer-cards fhand thand kind
        show-cards
        computer-turn fhand thand guess-from thand cguesses
    ][  
        clear-and-show 0.4 gf 
        go-fish 1 thand   
        append cguesses kind 
    ]
]
 
player-turn: func [
    fhand "from hand"
    thand "to hand"
    kind  "rank of cards"
    /local
        p 
][
    if empty? fhand [go-fish 3 fhand]

    if none? find-in thand kind [   ;-- player has to hold rank asked for
        clear-and-show 1.0 
        "You have to have that rank in your hand to ask for it.^/Computers turn..."
        exit
    ]

    either find-in fhand kind [
        check-for-books thand kind
        transfer-cards fhand thand kind 
        show-cards
        if find-in thand kind [ 
            p: ask "Your guess: "
            either p = "x" [halt][player-turn fhand thand p]
            check-for-books thand p 
        ]
    ][
        clear-and-show 0.4 gf 
        go-fish 1 thand 
    ]
]
 
game-round: has [c p][
    print {
          -------------------
          -  COMPUTER TURN  -
          -------------------
          }
 
    if empty? chand [  ; computer has no more cards? fish 3 cards.
        go-fish 3 chand
        show-cards
    ]
    computer-turn phand chand c: guess-from chand cguesses
    check-for-books chand c
    show-cards
 
    print {
          -------------------
          -   PLAYER TURN   -
          -------------------
          }

    if empty? phand [   ;-- player has no more cards? fish 3 cards.
        go-fish 3 phand
        show-cards
    ]
    p: ask "Your guess: "
    either p = "x" [halt][player-turn chand phand find-in phand p]
    check-for-books phand p 
    show-cards
]
 
main: does [
    deck: shuffle make-deck
    deal-cards 9 chand
    deal-cards 9 phand
    show-cards
    while [cbooks + pbooks < 13][
        game-round  
    ]
    clear-and-show 0 ""
    print "GAME OVER" 
    print [newline "Computer books:" cbooks newline "Player books:" pbooks]
]

main

Rust

See Go Fish/Rust

Ruby

See Go Fish/Ruby

Tcl

See Go Fish/Tcl

V (Vlang)

See Go Fish/V (Vlang)

Wren

See Go Fish/Wren