Hangman

include GtkEngine.e
include std/search.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 = call_back(routine_id("KeyPressed")) -- 'forward' link to the 'brains' of the game;

sequence file = canonical_path("~/demos/resources/words.txt") sequence words = read_lines(file)
------------------------------------------------------------------------
-- interface; ------------------------------------------------------------------------ constant win = create(GtkWindow) set(win,"border width",10) connect(win,"destroy","Quit") -- on program end; connect(win,"key-press-event",keypressed) constant panel = create(GtkBox,1) add(win,panel) constant display = create(GtkLabel) -- for word being guessed; set(display,"font","bold 24") add(panel,display) constant lbl1 = create(GtkLabel,"Guess the word") -- for status; set(lbl1,"font","8") add(panel,lbl1) 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 = 1, y = 3, z = 0 for i = 1 to length(letters) do z = 'a'+i-1 letters[i] = create(GtkButton,sprintf("%s",z),keypressed,z) set(grid,"attach",letters[i],x,y,1,1) x += 1 if x > 13 then x = 1 y += 1 end if -- time for a new row; end for new_word() -- get a new word and initialize counters; set(display,"markup",FormatWord(current_word)) show_all(win) main() ---------------------------------------------------------------------------------------------------------- procedure new_word() -- selects a random word, resets available letters; ---------------------------------------------------------------------------------------------------------- current_word = words[rand(length(words))] 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)) for i = 1 to length(letters) do -- reset colors; set(letters[i],"background","gray") end for end procedure --------------------------------------------------------------------------------------------------- global function KeyPressed(atom ctl, atom event) -- event handler; --------------------------------------------------------------------------------------------------- -- 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 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") else set(letters[key-'a'+1],"background","yellow") end if avail = remove_all(key,avail) -- remove letter from available set; set(display,"markup",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 new_word() else abort(0) end if end if end if return 1 end function ------------------------------------------------------------------------------------------------------------- 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})) 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})) 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) else abort(0) end if end if return result end function

Updated ver. 4.5.9 May 30
© 2012 by Irv Mullins

Comments