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
 
""" challenge flagsflag: true if challenge taken by player, display button """
const challenge = [false, false]
 
#============ 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, 42); drawcardsfromdeck!(game, 2)
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 = 8641120, hcanwcan = 700810, hlogh = 100700)
win = GtkWindow("Uno Card Game", w, hcan + hlogh) |> (GtkFrame() |> (vboxhbox = GtkBox(:vh)))
swinvbox = GtkScrolledWindowGtkBox(:v)
can = GtkCanvas(wwcan, hcanh)
set_gtk_propertypush!(canhbox, :expand, truecan)
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")
signal_connect(w -> (challenge[begin] = true), chal, "clicked")
push!(vbox, swinb, g, r, y, chal)
push!(swinhbox, canvbox)
fontpointsize = w / 50
cardpositions = Dict{Int, Vector{Int}}()
 
colorpositions = Dict("Red" => [280, 435, 320, 475], "Yellow" => [340, 435, 380, 475],
# announce the rules and penalties per task description
"Green" => [400, 435, 440, 475], "Blue" => [460, 435, 500, 475])
info_dialog(unodocshtml, win)
challengeposition = [300, 475, 470, 465]
 
# create a game instance to start play
game = UnoCardGameState()
 
Line 430 ⟶ 449:
color = colorant"navy"
set_source(ctx, color)
move_to(ctx, 360, 400420)
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)
if challenge[end]
set_source(ctx, colorant"black")
move_to(ctx, challengeposition[1], challengeposition[2])
show_text(ctx, "Challenge Draw Four")
stroke(ctx)
else
for (i, p) in enumerate(colorpositions)
set_source(ctx, cairocolor[first(p)])
x0, y0, x1, y1 = last(p)
rectangle(ctx, x0, y0, 40, 40)
fill(ctx)
end
end
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
if challengeposition[1] < evt.x < challengeposition[3] &&
challengeposition[4] < evt.y < challengeposition[2]
challenge[begin] = true
return
end
challenge[begin] = false
for p in colorpositions
x0, y0, x1, y1 = last(p)
if x0 < evt.x < x1 && y0 < evt.y < y1
push!(channel, first(p))
return
end
end
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
challenge[end] = true
draw(can)
Gtk.showall(win)
info_dialog("ChooseClick Challenge within 5 seconds to challenge a Draw Four")
sleep(53)
challenge[end] = false
end
sleep(2)
Line 516 ⟶ 508:
if type(game.discardpile[end]) == "Draw Two"
nextplayer!(game) # next player might have to draw before scoring done
drawcardsdrawcardsfromdeck!(game, 2)
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"
4,102

edits