Go Fish/Julia: Difference between revisions
< Go Fish
Content added Content deleted
(Created page with "<lang julia>import Base.show const sorteddeck = reshape([string(r == 'T' ? "10" : r) * s for r in "23456789TJQKA", s in "♣♦♥♠"], 52) const maxdecklen = length(sortedd...") |
m (link) |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
See [[Go_Fish]] |
|||
⚫ | |||
⚫ | |||
const sorteddeck = reshape([string(r == 'T' ? "10" : r) * s for r in "23456789TJQKA", s in "♣♦♥♠"], 52) |
const sorteddeck = reshape([string(r == 'T' ? "10" : r) * s for r in "23456789TJQKA", s in "♣♦♥♠"], 52) |
||
const maxdecklen = length(sorteddeck) |
|||
isvaliddeck(a) = (s = Vector{UInt8}(unique(a)); (a == s && all(x -> 0 < x <= 52, s))) |
isvaliddeck(a) = (s = Vector{UInt8}(unique(a)); (a == s && all(x -> 0 < x <= 52, s))) |
||
Line 18: | Line 19: | ||
ascards(d::Deck) = [sorteddeck[i] for i in d.cards] |
ascards(d::Deck) = [sorteddeck[i] for i in d.cards] |
||
Base.show(io::IO, d::Deck) = show(io, join(ascards(d), " ")) |
Base.show(io::IO, d::Deck) = show(io, join(ascards(d), " ")) |
||
byrank(d::Deck) = filter(d -> !isempty(d.cards), |
|||
byrank(d::Deck) = filter(!isempty, [filter(x -> x in n:13:52, d.cards) for n in 1:13]) |
|||
printbyrank(d) = foreach(println, byrank(d)) |
printbyrank(d) = foreach(x -> println(map(y -> sorteddeck[y], x)), byrank(d)) |
||
function deal!(d::Deck, hlen) |
function deal!(d::Deck, hlen) |
||
Line 47: | Line 48: | ||
function gofish() |
function gofish() |
||
ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] |
ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] |
||
displayplayer(d, l, cl) = println("Player hand is |
displayplayer(d, l, cl) = (println("Player hand is"), printbyrank(d), |
||
" Computer score is $(length(cl)) books.") |
println(".\nYour score is $(length(l)) books. Computer score is $(length(cl)) books.")) |
||
discardfrom!(a, d) = (dis = Deck(a |
discardfrom!(a, d) = (dis = Deck(a); d.cards = filter(x -> !(x in a), d.cards); dis) |
||
books!(d, l) = (b = [discardfrom!(a, d) for a in byrank(d) if length(a |
books!(d, l) = (b = [discardfrom!(a, d) for a in byrank(d) if length(a) == 4]; append!(l, b); b) |
||
function cardswithrank(rankstring, d) |
function cardswithrank(rankstring, d) |
||
Line 61: | Line 62: | ||
d.cards[arr] |
d.cards[arr] |
||
end |
end |
||
function moverank!(rnk, srcdeck, dstdeck) |
function moverank!(rnk, srcdeck, dstdeck) |
||
Line 75: | Line 75: | ||
end |
end |
||
crd = popfirst!(maindeck.cards) |
crd = popfirst!(maindeck.cards) |
||
d = sort(push!(d.cards, crd)) |
d.cards = sort(push!(d.cards, crd)) |
||
if display |
if display |
||
println("You drew a ", Deck([crd])) |
println("You drew a ", Deck([crd])) |
||
Line 122: | Line 122: | ||
end |
end |
||
function computerasks!(cdeck, claid, pdeck, maindeck) |
function computerasks!(cdeck, claid, pdeck, maindeck, memory) |
||
choice = "" |
choice = "" |
||
while true |
while true |
||
Line 134: | Line 134: | ||
return |
return |
||
end |
end |
||
rankpick = 0 |
|||
while true |
|||
wmost = sort(byrank(cdeck), lt = (x, y) -> length(x.cards) < length(y.cards))[end] |
|||
r = rand(cdeck.cards) |
|||
rankpick = cardrank(r) |
|||
if haskey(memory, rankpick) && memory[rankpick] > 0 |
|||
memory[rankpick] -= 1 |
|||
continue |
|||
else |
|||
memory[rankpick] = 3 |
|||
break |
|||
end |
|||
end |
|||
choice = ranks[rankpick] |
|||
println("Computer asks you for \"$choice\" cards.") |
println("Computer asks you for \"$choice\" cards.") |
||
if (n = length(cardswithrank(choice, pdeck))) > 0 |
if (n = length(cardswithrank(choice, pdeck))) > 0 |
||
Line 164: | Line 173: | ||
plaid = Vector{Deck}() |
plaid = Vector{Deck}() |
||
claid = Vector{Deck}() |
claid = Vector{Deck}() |
||
memory= Dict{Int,Int}() |
|||
while sum(length, [pdeck.cards, cdeck.cards, fishd.cards]) > 0 |
while sum(length, [pdeck.cards, cdeck.cards, fishd.cards]) > 0 |
||
Line 170: | Line 180: | ||
drawacard!(pdeck, fishd) |
drawacard!(pdeck, fishd) |
||
computerasks!(cdeck, claid, pdeck, fishd) |
computerasks!(cdeck, claid, pdeck, fishd, memory) |
||
computerdiscards!(cdeck, claid) |
computerdiscards!(cdeck, claid) |
||
drawacard!(cdeck, fishd, false) |
drawacard!(cdeck, fishd, false) |
||
Line 181: | Line 191: | ||
end |
end |
||
gofish() |
gofish()</syntaxhighlight> |
||
</lang> |
Latest revision as of 08:19, 5 September 2022
See Go_Fish
import Base.show
const sorteddeck = reshape([string(r == 'T' ? "10" : r) * s for r in "23456789TJQKA", s in "♣♦♥♠"], 52)
isvaliddeck(a) = (s = Vector{UInt8}(unique(a)); (a == s && all(x -> 0 < x <= 52, s)))
mutable struct Deck
cards::Vector{UInt8}
Deck(a) = if isvaliddeck(a) new(a) else throw("bad deck constructor $a") end
end
suitrank(crd) = divrem((crd - 1), 13) .+ 1
cardsuit(crd) = suitrank(crd)[1]
cardrank(crd) = suitrank(crd)[2]
shuffledeck!(d) = shuffle!(d.cards)
ascards(d::Deck) = [sorteddeck[i] for i in d.cards]
Base.show(io::IO, d::Deck) = show(io, join(ascards(d), " "))
byrank(d::Deck) = filter(!isempty, [filter(x -> x in n:13:52, d.cards) for n in 1:13])
printbyrank(d) = foreach(x -> println(map(y -> sorteddeck[y], x)), byrank(d))
function deal!(d::Deck, hlen)
if hlen < length(d.cards)
hand = Deck(d.cards[1:hlen])
d.cards = d.cards[hlen+1:end]
else
hand = Deck(d.cards)
empty!(d.cards)
end
return hand
end
function queryprompt(query, choices, choicetxt="")
carr = map(x -> uppercase(strip(string(x))), collect(choices))
while true
print(query, " ", choicetxt == "" ? carr : choicetxt, ": ")
choice = uppercase(strip(readline(stdin)))
if choice in carr
return choice
end
println()
end
end
function gofish()
ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
displayplayer(d, l, cl) = (println("Player hand is"), printbyrank(d),
println(".\nYour score is $(length(l)) books. Computer score is $(length(cl)) books."))
discardfrom!(a, d) = (dis = Deck(a); d.cards = filter(x -> !(x in a), d.cards); dis)
books!(d, l) = (b = [discardfrom!(a, d) for a in byrank(d) if length(a) == 4]; append!(l, b); b)
function cardswithrank(rankstring, d)
r = indexin([rankstring], ranks)[1]
if r == nothing
return []::Vector{Int}
else
arr = findall(x -> cardrank(x) == r, d.cards)
end
d.cards[arr]
end
function moverank!(rnk, srcdeck, dstdeck)
arr = cardswithrank(rnk, srcdeck)
srcdeck.cards = sort(filter(x -> !(x in arr), srcdeck.cards))
dstdeck.cards = sort(unique(append!(dstdeck.cards, arr)))
end
function drawacard!(d, maindeck, display=true)
if isempty(maindeck.cards)
println("Draw pile is empty.")
return
end
crd = popfirst!(maindeck.cards)
d.cards = sort(push!(d.cards, crd))
if display
println("You drew a ", Deck([crd]))
end
end
function playerasks!(d, plaid, claid, cdeck, maindeck)
choice = ""
while true
if isempty(cdeck.cards)
drawacard!(cdeck, maindeck, false)
end
if isempty(d.cards)
drawacard!(d, maindeck)
end
if isempty(d.cards)
return
end
displayplayer(d, plaid, claid)
choice = queryprompt("Your turn. Rank you request? ", ranks)
if isempty(cardswithrank(choice, d))
println("You cannot ask for \"$choice\" cards since you have none.")
continue
end
println("You want the \"$choice\" cards.")
if (n = length(cardswithrank(choice, cdeck))) > 0
moverank!(choice, cdeck, d)
println("Computer gives you $n of the \"$choice\" cards.")
choice = queryprompt("Ask computer for cards again? ", ["Y", "N"])
if choice == "N"
break
end
else
println("Sorry, computer does not have any of those cards.")
break
end
end
end
function playerdiscards!(pd, plaid)
choice = queryprompt("Discard cards? ", ["Y","N"])
if choice == "Y"
bks = books!(pd, plaid)
println(length(bks) > 0 ? "Books: $(join(map(ascards, bks), ", ")))" : "No new books.")
end
end
function computerasks!(cdeck, claid, pdeck, maindeck, memory)
choice = ""
while true
if isempty(pdeck.cards)
drawacard!(pdeck, maindeck)
end
if isempty(cdeck.cards)
drawacard!(pdeck, maindeck, false)
end
if isempty(cdeck.cards)
return
end
rankpick = 0
while true
r = rand(cdeck.cards)
rankpick = cardrank(r)
if haskey(memory, rankpick) && memory[rankpick] > 0
memory[rankpick] -= 1
continue
else
memory[rankpick] = 3
break
end
end
choice = ranks[rankpick]
println("Computer asks you for \"$choice\" cards.")
if (n = length(cardswithrank(choice, pdeck))) > 0
moverank!(choice, pdeck, cdeck)
println("Computer accepts $n \"$choice\" cards from you.")
else
println("Computer cannot get those cards from you.")
return
end
end
end
function computerdiscards!(cdec, claid)
bks = books!(cdec, claid)
if length(bks) > 0
println("Computer new books: ", join(map(ascards, bks), ", "))
end
end
fishd = Deck(shuffle(collect(1:52)))
println("------------GO FISH GAME------------\n\nDealing:")
pdeck = deal!(fishd, 9)
cdeck = deal!(fishd, 9)
println("You are dealt $pdeck.")
plaid = Vector{Deck}()
claid = Vector{Deck}()
memory= Dict{Int,Int}()
while sum(length, [pdeck.cards, cdeck.cards, fishd.cards]) > 0
playerasks!(pdeck, plaid, claid, cdeck, fishd)
playerdiscards!(pdeck, plaid)
drawacard!(pdeck, fishd)
computerasks!(cdeck, claid, pdeck, fishd, memory)
computerdiscards!(cdeck, claid)
drawacard!(cdeck, fishd, false)
end
pscore = length(plaid)
cscore = length(claid)
println("Player has taken out $pscore books, and computer has taken out $cscore books.")
println(pscore > cscore ? "Player wins." : pscore < cscore ? "Computer wins." : "Tied game.")
end
gofish()