Uno (Card Game)/Julia: Difference between revisions
m
Fixed syntax highlighting.
m (add scoring) |
m (Fixed syntax highlighting.) |
||
(5 intermediate revisions by one other user not shown) | |||
Line 2:
Gtk based graphical version.
<
#=========== Channel and flag (IPC) section ===================#
""" channel, communicates player's mouse choice of card or color to game logic """
const channel = Channel{Any}(100)
""" flush the channel from mouse choice to game logic """
flushchannel() = while !isempty(channel) take!(channel); end
#============ Game play section ==================#
""" The Uno card type. The first field is color, second field is number or command. """
color(c::UnoCard) = first(c)
type(c::UnoCard) = last(c)
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 98 ⟶ 97:
hands = [deck[i:i+6] for i in 1:7:27]
game = UnoCardGameState(drawpile, discardpile, [UnoCardGamePlayer(playernames[i], 0,
startswith(playernames[i], "Bot")
for i in 1:length(playernames)], 1, "Wild", "Wild", true, true)
dealer = rand(1:length(playernames))
Line 153 ⟶ 152:
# bot will challenge half the time, player must challenge in 5 seconds.
if game.players[game.pnow].isabot && rand() < 0.5 ||
(!game.players[game.pnow].isabot && challenge[begin]
challenge[begin] = false
logline("$(game.players[game.pnow].name) challenged Draw Four!")
Line 159 ⟶ 158:
nextplayer!(game); nextplayer!(game); nextplayer!(game); # prior player
game.colornow = game.lastcolor
hand = game.players[game.pnow].hand
if any(
logline("Challenge sustained! Challenged Draw Four player draws 4.")
drawcardsfromdeck!(game,
game.pnow, game.colornow = challenger, savecolor
return
Line 172 ⟶ 170:
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 ⟶ 333:
const cairocolor = Dict("Red" => colorant"red", "Yellow" => colorant"gold",
"Green" => colorant"green", "Blue" => colorant"blue", "Wild" => colorant"black")
""" CSS style button for bold colored text """
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
nrow = (length(hand) + 15) ÷
for row in 1:nrow
cards = hand[(row - 1) *
startx, starty = 40 + (
for (i, card) in enumerate(cards)
idx, x0 = (row - 1) *
cardpositions[idx] = [x0, starty, x0 + 40, starty + 80]
cairocard(ctx, card, x0, starty, 40, 80)
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"
Line 543 ⟶ 536:
end
UnoCardGameApp()</syntaxhighlight>
|