--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