Uno (Card Game)/Julia: Difference between revisions
m
move logging area to side
m (add scoring) |
m (move logging area to side) |
||
Line 4:
<lang julia>using Random, Colors, Gtk, Cairo
#=========== Channel and flag (IPC) section ===================#
""" channel, communicates player's mouse choice of card or color to game logic """
Line 11:
""" flush the channel from mouse choice to game logic """
flushchannel() = while !isempty(channel) take!(channel); end
#============ Game play section ==================#
Line 59 ⟶ 62:
const originaldeck = [vec([UnoCard(c, v) for v in ttypes, c in colors]);
fill(UnoCard("Wild", "Wild"), 4); fill(UnoCard("Wild", "Draw Four"), 4)]
▲""" challenge flags: taken by player, display button """
▲const challenge = [false, false]
""" Set the next player to play to game.pnow (clockwise or counterclockwise) """
Line 162 ⟶ 161:
hand = game.players[game.pnow].hand
if any(i -> color(hand[i]) != "Wild", playableindices(game))
logline("Challenge sustained! Challenged Draw Four player draws 4.")
drawcardsfromdeck!(game,
game.pnow, game.colornow = challenger, savecolor
return
Line 172 ⟶ 171:
game.pnow, game.colornow = challenger, savecolor
end
challenge[begin] = false▼
end
logline("Player $(game.players[game.pnow].name) draws $n card$(n == 1 ? "" : "s").")
Line 334:
const cairocolor = Dict("Red" => colorant"red", "Yellow" => colorant"gold",
"Green" => colorant"green", "Blue" => colorant"blue", "Wild" => colorant"black")
function colorbutton(txt::String, clr::String)
button = GtkButton(txt)
sc = Gtk.GAccessor.style_context(button)
pr = Gtk.CssProviderLeaf(data="button {color:$(clr); font-weight: bolder}")
push!(sc, Gtk.StyleProvider(pr), 600)
return button
end
""" Draw a UnoCard as a rectangle with rounded corners. """
Line 403 ⟶ 411:
Uno card game Gtk app. Draws game on a canvas, logs play on box below canvas.
"""
function UnoCardGameApp(w =
win = GtkWindow("Uno Card Game", w,
can = GtkCanvas(
push!(swin, can)▼
push!(vbox, swin)▼
push!(vbox, logwindow) # from log section
set_gtk_property!(logwindow, :expand, true)
b, g = colorbutton("Blue", "blue"), colorbutton("Green", "green")
r, y = colorbutton("Red", "red"), colorbutton("Yellow", "gold")
chal = GtkButton("Challenge")
signal_connect(w -> push!(channel, "Blue"), b, "clicked")
signal_connect(w -> push!(channel, "Green"), g, "clicked")
signal_connect(w -> push!(channel, "Red"), r, "clicked")
signal_connect(w -> push!(channel, "Yellow"), y, "clicked")
fontpointsize = w / 50
cardpositions = Dict{Int, Vector{Int}}()
# announce the rules and penalties per task description
info_dialog(unodocshtml, win)
# create a game instance to start play
game = UnoCardGameState()
Line 430 ⟶ 449:
color = colorant"navy"
set_source(ctx, color)
move_to(ctx, 360,
show_text(ctx, game.players[1].name)
stroke(ctx)
Line 444 ⟶ 463:
cairocard(ctx, last(game.discardpile), 350, 240, 40, 80)
cairodrawfacedowncard(ctx, 410, 240, 40, 80)
hand = first(game.players).hand
isempty(hand) && return
Line 473 ⟶ 479:
""" Gtk mouse callback: translates valid mouse clicks to a channel item """
signal_connect(can, "button-press-event") do b, evt
▲ challenge[begin] = true
▲ challenge[begin] = false
for p in cardpositions
x0, y0, x1, y1 = last(p)
Line 495 ⟶ 488:
end
# do the turns of play in the game, keeping score totals from the rounds
for n in 1:1000
draw(can)
Line 502 ⟶ 496:
if startswith(game.players[game.pnow].name, "Play") &&
type(game.discardpile[end]) == "Draw Four" && game.commandsvalid
draw(can)
Gtk.showall(win)
info_dialog("
sleep(
end
sleep(2)
Line 516 ⟶ 508:
if type(game.discardpile[end]) == "Draw Two"
nextplayer!(game) # next player might have to draw before scoring done
elseif type(game.discardpile[end]) == "Draw Four"
nextplayer!(game)
drawcardsfromdeck!(game, 2)
drawcardsfromdeck!(game, 2) # D2 twice because not to be contested as a D4
end
roundpoints = sum(x -> handscore(x.hand), game.players)
Line 528 ⟶ 520:
info_dialog("The winner of round $n is $(game.players[winner].name).\n" *
"Winner gains $roundpoints points.", win)
logline("Scores: $([x.score for x in game.players])")
if any(x -> x.score >= 500, game.players)
s = "Game over. Scores:\n\n"
|