' Taken from: http://www.rosettacode.org/wiki/Go_Fish/Locomotive_Basic
' Converted to uBasic/4tH by J.L. Bezemer 2022
                                       ' original index begins at "1"
     dim @p(14)                        ' player
     dim @c(14)                        ' computer
     dim @d(14)                        ' deck
     dim @g(14)                        ' guess
     dim @s(14)                        ' possibilities
     dim @a(14)                        ' asked
     dim @o(2)                         ' scores

     c:="A234567890JQK"                ' deck of cards, 0=10
     r=4*13
     for i=1 to 13: @d(i)=4 : next
     for i=1 to 9
     gosub _DealCard

     @d(k)=@d(k)-1
     @c(k)=@c(k)+1
     gosub _DealCard

     @d(k)=@d(k)-1
     @p(k)=@p(k)+1
     next i
     print "Go Fish"
     print "======="
     print
     n = ask("What is your name? ")

_PrintHand
     print "Score: ";show(n);" ";@o(0);"  Computer ";@o(1)
     print "",r;" cards remaining" : print
     print "Your hand: ";
     for i=1 to 13
     if @p(i)=0 then goto _NextCard
     for j=1 to @p(i)
     print chr(peek(c,i-1));" ";
     next j

_NextCard
     next i
     print

_AskCard
     gosub _CheckEnd
     s=n
     d = ask("Which card do you ask for? ")
     if len(d)#1 then goto _AskCard    ' only one single character is valid
     e = peek (d,0)                    ' an awkward way to uppercase the char
     if (e > ord("a")-1) * (e < ord("z")+1) e = e-32

     for x=0 to 12                     ' now figure out if it is in the deck
       if peek(c, x) = e then e = x+1 : break
     next
                                       ' we overshot - cannot be valid
     if x=13 then print "Sorry, that is not a valid choice." : goto _AskCard
     if @p(e)=0 then print "You do not have that card!" : goto _AskCard
     @g(e)=1

     if @c(e)=0 then
       print show(s);", go fish!" : print show(s);" draws a ";
       gosub _DrawCardP : gosub _CheckBookP : goto _ComputerTurn1
     endif

     v=@c(e)
     @c(e)=0
     @p(e)=@p(e)+v
     print show(s);" gets ";v;" more cards."
     gosub _CheckBookP
     goto _PrintHand

_ComputerTurn1
     s := "Computer"
     for i=1 to 13
     @a(i)=0
     next

_ComputerTurn2
     gosub _CheckEnd
     f=0
     for i=1 to 13
       if (@c(i)>0) * (@g(i)>0) then @s(i)=1 : f=f+1
     next
     if f=0 then goto _DrawRand

_DrawGuess
     k=rnd(12)+1
     if @s(k)=0 then goto _DrawGuess
     @g(k)=0
     @a(k)=1
     goto _MakeTurn

_DrawRand
     k=rnd(12)+1
     if (@c(k)=0) + (@a(k)) then goto _DrawRand

_MakeTurn
     print show(s);" wants your ";chr(peek(c,k-1));"'s."
     @a(k)=1

     if @p(k)=0 then
       print show(s);", go fish!": print show(s);" draws a ";
       gosub _DrawCardC : gosub _CheckBookC : goto _PrintHand
     endif

     v=@p(k)
     @p(k)=0
     @c(k)=@c(k)+v
     print show(s);" gets ";v;" more cards."

     gosub _CheckBookC
     goto _ComputerTurn2
     goto _PrintHand
     end

_DrawCardP
     gosub _DealCard
     print chr(peek(c,k-1));"."
     @d(k)=@d(k)-1
     @p(k)=@p(k)+1
     return

_DrawCardC
     gosub _DealCard
     print "card."
     @d(k)=@d(k)-1
     @c(k)=@c(k)+1
     return

_CheckBookP
     for i=1 to 13
     if @p(i)#4 then goto _NextLoopP
     print show(s);" completes book of ";chr(peek(c,i-1));"'s."
     @p(i)=0
     @o(0)=@o(0)+1

_NextLoopP
     next i
     return

_CheckBookC
     for i=1 to 13
     if @c(i)#4 then goto _NextLoopC
     print show(s);" completes book of ";chr(peek(c,i-1));"'s."
     @c(i)=0
     @o(1)=@o(1)+1

_NextLoopC
     next i
     return

_CheckEnd
     g=0:h=0
     for i=1 to 13
     g=g+@p(i)
     h=h+@c(i)
     next i
     if (r=0) + (g=0) + (h=0) then goto _EndGame
     return

_EndGame
     print
     print "*** Game over! ***"
     print
     if @o(0)>@o(1) then print show(n);" has won." : end
     if @o(0)<@o(1) then print "The computer has won." : end
     print "It's a tie!" : end

_DealCard
     r=r-1
     l=rnd(r)+1
     for k=1 to 13
     l=l-@d(k)
     if l<1 then unloop: return
     next
