--include GtkEngine.e
include tinewg.exw
include std/search.e
include std/io.e
include std/filesys.e
include std/sequence.e
include std/text.e
-- EuGTK keywords are in blue;
------------------------------------------------------------------------
-- variables;
------------------------------------------------------------------------
integer max, ct = 0
object avail, blanks, current_word
-- max limits number of guesses allowed;
-- ct tracks how many guesses so far;
-- avail is the set of un-guessed letters, initially a...z;
-- blanks holds substitute characters to use in place of hidden letters;
atom keypressed = routine_id("KeyPressed")
-- 'forward' link to the 'brains' of the game;
sequence file = canonical_path("worte.txt")
sequence words = read_lines(file)
------------------------------------------------------------------------
-- interface;
------------------------------------------------------------------------
--constant win = create(GtkWindow)
WindowType=StandardWin
Window("HangMan",-1,-1,460,240)
-- set(win,"border width",10)
-- connect(win,"destroy","Quit") -- on program end;
-- connect(win,"key-press-event",keypressed)
SetHandler(WinHwnd,Key,keypressed)
--constant panel = create(GtkBox,1)
-- add(win,panel)
--constant display = create(GtkLabel) -- for word being guessed;
constant display=Control(Label,"",30,10,400,80)
constant font1=NewFont("Arial",28,1,0,0,)
SetFont(display,font1)
-- set(display,"font","bold 24")
-- add(panel,display)
--constant lbl1 = create(GtkLabel,"Guess the word") -- for status;
constant lbl1=Control(Label,"Guess the word",30,90,400,40)
constant font2=NewFont("Arial",12,0,0,0)
SetFont(lbl1,font2)
-- set(lbl1,"font","8")
-- add(panel,lbl1)
-- There is no Grid in tinEWG
--constant grid = create(GtkGrid) -- to hold button set;
-- add(panel,grid)
-- set(grid,"row spacing",2)
-- set(grid,"column spacing",2)
object letters = repeat(0,'z'-'a'+1) -- build a set of empty buttons;
integer x = 0, y = 130, z = 0
constant font3=NewFont("Arial",14,0,0,0)
for i = 1 to length(letters) do
z = 'a'+i-1
letters[i] = Control(ClickLabel,sprintf("%s",z),x*35,y,35,35) --ClickLabel fits better
SetHandler(letters[i],Key,keypressed)
SetHandler(letters[i],Click,keypressed)
SetFont(letters[i],font3)
--SetWindowTheme(letters[i],0,0)
-- set(grid,"attach",letters[i],x,y,1,1)
x += 1 if x > 12 then x = 0 y += 35 end if -- time for a new row;
end for
new_word() -- get a new word and initialize counters;
--set(display,"markup",FormatWord(current_word))
SetText(display,FormatWord(current_word))
--show_all(win)
--main()
WinMain()
----------------------------------------------------------------------------------------------------------
procedure new_word() -- selects a random word, resets available letters;
----------------------------------------------------------------------------------------------------------
current_word = words[rand(length(words))]
current_word = lower(current_word) -- my german wordlist has uppercase letters
avail = series('a',1,32,'+') -- set of {'a'...'z'}
blanks = repeat('_',length(avail)) -- to hide unguessed letters;
ct = 0 -- number of tries so far;
max = 2 * length(current_word) -- number of tries allowed;
-- set(display,"markup",FormatWord(current_word))
SetText(display,FormatWord(current_word))
for i = 1 to length(letters) do -- reset colors;
-- set(letters[i],"background","gray")
SetColor(letters[i],CL_BLACK,CL_GRAY)
end for
end procedure
---------------------------------------------------------------------------------------------------
--global function KeyPressed(atom ctl, atom event) -- event handler;
global procedure KeyPressed()
--end function
---------------------------------------------------------------------------------------------------
-- this function is linked to both keypresses and button clicks,
-- so we need to determine which happened;
integer key
--if is_in_range(event,{'a','z'}) then key = event -- button clicked;
--else key = lower(peek(event+20)) -- keyboard input;
--end if
key=0 -- make sure key has a Value
if Event=Key then
if is_in_range(EventItem,{'a','z'}) then key = EventItem end if
else
if Event=Click then
for i=1 to length(letters) do
if EventOwner=letters[i] then
key=i+96 --for small letters
end if
end for
end if
end if
if is_in_list(key,avail) then -- in set of unused letters?;
ct += 1 -- new guess counts;
if find(key,current_word) > 0 then
-- set(letters[key-'a'+1],"background","green")
SetColor(letters[key-'a'+1],CL_BLACK,CL_GREEN)
else
-- set(letters[key-'a'+1],"background","yellow")
SetColor(letters[key-'a'+1],CL_BLACK,CL_YELLOW)
end if
avail = remove_all(key,avail) -- remove letter from available set;
-- set(display,"markup",FormatWord(current_word))
SetText(display,FormatWord(current_word))
if ct > max then -- too many tries;
-- if Question(win,"Sorry",
-- sprintf("The word was %s",{current_word}),
-- "Play again?") = MB_YES then
if AskMsg(sprintf("The word was %s",{current_word})&"\n\rPlay again?","Sorry") then
new_word()
else abort(0)
end if
end if
end if
--return 1
end procedure
-------------------------------------------------------------------------------------------------------------
function FormatWord(object word) -- handles display and testing a for win;
-------------------------------------------------------------------------------------------------------------
object result = ""
--set(lbl1,"text",sprintf("%d letter word,\n%d guesses left.",
-- {length(current_word),max-ct}))
SetText(lbl1,sprintf("%d letter word,\n%d guesses left.",
{length(current_word),max-ct}))
word = transmute(word,avail,blanks) -- change un-guessed letters to underscores,
-- using the still untried letters remaining;
for i = 1 to length(word) do -- add spaces between letters (looks better!);
result &= word[i] & ' '
end for
if not find('_',word) then -- if no hidden letters left, puzzle solved!
-- set(display,"markup",sprintf("%s",{result}))
SetText(display,sprintf("%s",{result}))
-- if Question(win,"Congratulations!",current_word,
-- sprintf("You guessed it in %d tries!\nPlay again?",ct)) = MB_YES then
-- new_word()
-- return FormatWord(current_word)
if AskMsg(sprintf("You guessed it in %d tries!\nPlay again?",ct),"Congratulations!") then
new_word()
return FormatWord(current_word)
--else abort(0)
else CloseApp(0) -- CloseApp is the better choice i think
end if
end if
return result
end function