Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
209
Task/Mastermind/Julia/mastermind.julia
Normal file
209
Task/Mastermind/Julia/mastermind.julia
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
using Gtk, Colors, Cairo, Graphics
|
||||
|
||||
struct Guess
|
||||
code::Vector{Color}
|
||||
guess::Vector{Color}
|
||||
hint::Vector{Color}
|
||||
end
|
||||
|
||||
function Guess(code, guess)
|
||||
len = length(code)
|
||||
hints = fill(colorant"gray", len) # gray default
|
||||
for (i, g) in enumerate(guess), (j, c) in enumerate(code)
|
||||
if g == c
|
||||
if i == j
|
||||
hints[i] = colorant"black"
|
||||
elseif hints[i] != colorant"black"
|
||||
hints[i] = colorant"white"
|
||||
end
|
||||
end
|
||||
end
|
||||
g = Guess([c for c in code], [c for c in guess], [c for c in hints])
|
||||
end
|
||||
|
||||
tovec(guess) = [x for x in [guess.code; guess.guess; guess.hint]]
|
||||
|
||||
function mastermindapp()
|
||||
allu(s) = length(unique(s)) == length(s)
|
||||
ccode(c, n, rok) = while true a = rand(c, n); if rok || allu(a) return a end end
|
||||
|
||||
numcolors, codelength, maxguesses, allowrep, gameover = 10, 4, 10, false, false
|
||||
colors = distinguishable_colors(numcolors)
|
||||
code = ccode(colors, numcolors, allowrep)
|
||||
guesshistory = Vector{Guess}()
|
||||
|
||||
win = GtkWindow("Mastermind Game", 900, 750) |> (GtkFrame() |> (box = GtkBox(:v)))
|
||||
settingsbox = GtkBox(:h)
|
||||
playtoolbar = GtkToolbar()
|
||||
|
||||
setcolors = GtkScale(false, 4:20)
|
||||
set_gtk_property!(setcolors, :hexpand, true)
|
||||
adj = GtkAdjustment(setcolors)
|
||||
set_gtk_property!(adj, :value, 10)
|
||||
clabel = GtkLabel("Number of Colors")
|
||||
|
||||
setcodelength = GtkScale(false, 4:10)
|
||||
set_gtk_property!(setcodelength, :hexpand, true)
|
||||
adj = GtkAdjustment(setcodelength)
|
||||
set_gtk_property!(adj, :value, 4)
|
||||
slabel = GtkLabel("Code Length")
|
||||
|
||||
setnumguesses = GtkScale(false, 4:40)
|
||||
set_gtk_property!(setnumguesses, :hexpand, true)
|
||||
adj = GtkAdjustment(setnumguesses)
|
||||
set_gtk_property!(adj, :value, 10)
|
||||
nlabel = GtkLabel("Max Guesses")
|
||||
|
||||
allowrepeatcolor = GtkScale(false, 0:1)
|
||||
set_gtk_property!(allowrepeatcolor, :hexpand, true)
|
||||
rlabel = GtkLabel("Allow Repeated Colors (0 = No)")
|
||||
|
||||
newgame = GtkToolButton("New Game")
|
||||
set_gtk_property!(newgame, :label, "New Game")
|
||||
set_gtk_property!(newgame, :is_important, true)
|
||||
|
||||
tryguess = GtkToolButton("Submit Current Guess")
|
||||
set_gtk_property!(tryguess, :label, "Submit Current Guess")
|
||||
set_gtk_property!(tryguess, :is_important, true)
|
||||
|
||||
eraselast = GtkToolButton("Erase Last (Unsubmitted) Pick")
|
||||
set_gtk_property!(eraselast, :label, "Erase Last (Unsubmitted) Pick")
|
||||
set_gtk_property!(eraselast, :is_important, true)
|
||||
|
||||
map(w->push!(settingsbox, w),[clabel, setcolors, slabel, setcodelength,
|
||||
nlabel, setnumguesses, rlabel, allowrepeatcolor])
|
||||
map(w->push!(playtoolbar, w),[newgame, tryguess, eraselast])
|
||||
|
||||
scrwin = GtkScrolledWindow()
|
||||
can = GtkCanvas()
|
||||
set_gtk_property!(can, :expand, true)
|
||||
map(w -> push!(box, w),[settingsbox, playtoolbar, scrwin])
|
||||
push!(scrwin, can)
|
||||
|
||||
currentguess = RGB[]
|
||||
guessesused = 0
|
||||
colorpositions = Point[]
|
||||
|
||||
function newgame!(w)
|
||||
empty!(guesshistory)
|
||||
|
||||
numcolors = Int(GAccessor.value(setcolors))
|
||||
codelength = Int(GAccessor.value(setcodelength))
|
||||
maxguesses = Int(GAccessor.value(setnumguesses))
|
||||
allowrep = Int(GAccessor.value(allowrepeatcolor))
|
||||
|
||||
colors = distinguishable_colors(numcolors)
|
||||
code = ccode(colors, codelength, allowrep == 1)
|
||||
empty!(currentguess)
|
||||
currentneeded = codelength
|
||||
guessesused = 0
|
||||
gameover = false
|
||||
draw(can)
|
||||
end
|
||||
signal_connect(newgame!, newgame, :clicked)
|
||||
|
||||
function saywon!()
|
||||
warn_dialog("You have WON the game!", win)
|
||||
gameover = true
|
||||
end
|
||||
|
||||
function outofguesses!()
|
||||
warn_dialog("You have Run out of moves! Game over.", win)
|
||||
gameover = true
|
||||
end
|
||||
|
||||
can.mouse.button1press = @guarded (widget, event) -> begin
|
||||
if !gameover && (i = findfirst(p ->
|
||||
sqrt((p.x - event.x)^2 + (p.y - event.y)^2) < 20,
|
||||
colorpositions)) != nothing
|
||||
if length(currentguess) < codelength
|
||||
if allowrep == 0 && !allu(currentguess)
|
||||
warn_dialog("Please erase the duplicate color.", win)
|
||||
else
|
||||
push!(currentguess, colors[i])
|
||||
draw(can)
|
||||
end
|
||||
else
|
||||
warn_dialog("You need to submit this guess if ready.", win)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@guarded draw(can) do widget
|
||||
ctx = Gtk.getgc(can)
|
||||
select_font_face(ctx, "Courier", Cairo.FONT_SLANT_NORMAL, Cairo.FONT_WEIGHT_BOLD)
|
||||
fontpointsize = 12
|
||||
set_font_size(ctx, fontpointsize)
|
||||
workcolor = colorant"black"
|
||||
set_source(ctx, workcolor)
|
||||
move_to(ctx, 0, fontpointsize)
|
||||
show_text(ctx, "Color options: " * "-"^70)
|
||||
stroke(ctx)
|
||||
empty!(colorpositions)
|
||||
for i in 1:numcolors
|
||||
set_source(ctx, colors[i])
|
||||
circle(ctx, i * 40, 40, 20)
|
||||
push!(colorpositions, Point(i * 40, 40))
|
||||
fill(ctx)
|
||||
end
|
||||
set_gtk_property!(can, :expand, false) # kludge for good text overwriting
|
||||
move_to(ctx, 0, 80)
|
||||
set_source(ctx, workcolor)
|
||||
show_text(ctx, string(maxguesses - guessesused, pad = 2) * " moves remaining.")
|
||||
stroke(ctx)
|
||||
set_gtk_property!(can, :expand, true)
|
||||
for i in 1:codelength
|
||||
set_source(ctx, i > length(currentguess) ? colorant"lightgray" : currentguess[i])
|
||||
circle(ctx, i * 40, 110, 20)
|
||||
fill(ctx)
|
||||
end
|
||||
if length(guesshistory) > 0
|
||||
move_to(ctx, 0, 155)
|
||||
set_source(ctx, workcolor)
|
||||
show_text(ctx, "Past Guesses: " * "-"^70)
|
||||
for (i, g) in enumerate(guesshistory), (j, c) in enumerate(tovec(g)[codelength+1:end])
|
||||
x = j * 40 + (j > codelength ? 20 : 0)
|
||||
y = 150 + 40 * i
|
||||
set_source(ctx, c)
|
||||
circle(ctx, x, y, 20)
|
||||
fill(ctx)
|
||||
end
|
||||
end
|
||||
Gtk.showall(win)
|
||||
end
|
||||
|
||||
function submitguess!(w)
|
||||
if length(currentguess) == length(code)
|
||||
g = Guess(code, currentguess)
|
||||
push!(guesshistory, g)
|
||||
empty!(currentguess)
|
||||
guessesused += 1
|
||||
draw(can)
|
||||
if all(i -> g.code[i] == g.guess[i], 1:length(code))
|
||||
saywon!()
|
||||
elseif guessesused > maxguesses
|
||||
outofguesses!()
|
||||
end
|
||||
end
|
||||
end
|
||||
signal_connect(submitguess!, tryguess, :clicked)
|
||||
|
||||
function undolast!(w)
|
||||
if length(currentguess) > 0
|
||||
pop!(currentguess)
|
||||
draw(can)
|
||||
end
|
||||
end
|
||||
signal_connect(undolast!, eraselast, :clicked)
|
||||
|
||||
newgame!(win)
|
||||
Gtk.showall(win)
|
||||
|
||||
condition = Condition()
|
||||
endit(w) = notify(condition)
|
||||
signal_connect(endit, win, :destroy)
|
||||
showall(win)
|
||||
wait(condition)
|
||||
end
|
||||
|
||||
mastermindapp()
|
||||
Loading…
Add table
Add a link
Reference in a new issue