Hangman game

Hi all,

I whipped up this little Hangman game, partially for practice but also for fun. I found a couple of Unix commands on a blog that will generate a random word and then use this to play Hangman. The words can be pretty esoteric and bizarre but I think it makes it fun. Regardless if you guess it right or not, the script then asks if you want to try looking it up via the free online dictionary.

Does anyone know of another way to get a random word, say from the dictionary provided in OSX, or some other method?

Anyway, if anyone wants to try it out, or if anyone would like to comment on how I could improve this, I’d love feedback :slight_smile:

--hangman for fun
--thanks to Greg Miller for the Unix random word command!
--http://unixjunkie.blogspot.com/2007/10/generating-random-words.html

set do_repeat to "Yes"
repeat until do_repeat is "No"
	
	
	--pick the word and set up game variables
	set theWord to do shell script "n=$(cat /usr/share/dict/words | wc -l); cat -n /usr/share/dict/words | grep -w $(jot -r 1 1 $n) | cut -f2"
	set theNumberofGuesses to 10
	set GuessedLetters to {}
	set curr_guess to ""
	set word_Check to ""
	set gameover to 0
	
	--game guessing loop
	repeat while gameover is 0
		set word_Check to ""
		set curr_guess to ""
		ignoring case
			repeat with i in characters of theWord
				-- set up output of guess and check to see if it's correct
				if i is in GuessedLetters then
					set curr_guess to curr_guess & " " & i & " "
					set word_Check to word_Check & i
				else
					set curr_guess to curr_guess & " _ "
				end if
			end repeat
			if word_Check is not equal to theWord then
				--get the output ready for next guess
				set GuessesLeft to "Guesses left:" & theNumberofGuesses
				set LettersGuessed to "Letters already guessed:" & (GuessedLetters as text)
				set HangManOutput to curr_guess & return & LettersGuessed & return & GuessesLeft
				--get next user guess
				set ThisGuess to (character 1 of text returned of (display dialog HangManOutput default answer ""))
				set GuessedLetters to GuessedLetters & ThisGuess
				--are we out of guesses?
				if ThisGuess is not in theWord then
					set theNumberofGuesses to theNumberofGuesses - 1
				end if
				if theNumberofGuesses is 0 then set gameover to 1
			else
				--not out of guesses, but word has been guessed correctly!
				set gameover to 2
			end if
		end ignoring
	end repeat
	--game over, man, game over!
	if gameover is 2 then
		set finalmessage to "Congratulations! You won!"
	else
		set finalmessage to "Sorry, try again next time!"
	end if
	set FinalOutput to finalmessage & return & "The word was: " & theWord & return & "Would you like to see the online definition of this word?"
	set lookupQuery to button returned of (display dialog FinalOutput buttons {"Yes", "No"})
	if lookupQuery is "Yes" then
		tell application "Safari"
			make new document at end of documents
			set URL of document 1 to "http://www.thefreedictionary.com/" & theWord
		end tell
	end if
	set do_repeat to button returned of (display dialog "Thanks for playing. Would you like to play again?" buttons {"Yes", "No"})
end repeat

Fun game. A couple suggestions…

  1. If I guess “R” for example, it lets me guess R again and it counts as another guess. You should check the guessed letter against a list of the letters already guessed and tell the user if he is guessing the same letter twice.

  2. rather than giving the user 10 guesses, you should allow him to have 6 bad guesses and unlimited correct guesses… I think this is how hangman is normally played.

  3. the “display dialog” command allows you to use an image in the window. The image must be an “icns” file. So I would make the 6 images needed for hangman in icns format. Put those inside the “Contents:Resources” folder of the app. Each image would be the different states of the hangman body as wrong guesses are made. Then you could essentially grow a body as the user miss-guesses by attaching the appropriate icns file to the dialog box.

display dialog "whatever" with icon file (path to me as text) & "Contents:Resources:" & numberWrongGuesses.icns
  1. the safari tell block of code for opening the dictionary website can be reduced to the following. This also gives the advantage of opening the website in the user’s preferred browser.
open location "http://www.thefreedictionary.com/" & theWord

One other thought. Some of the words in /usr/share/dict/words are pretty obscure and not in the online dictionary. In order to eliminate some of those obscure words you could make sure the word can be found in the online dictionary before using it. The following code will get a word, then check it online. If the word is found online then we can use the word. If not found then it gets another word and checks that… repeating until a word is found in the online dictionary. We use the counter numTries to make sure we don’t stay in the repeat loop indefinitely.

set maxTries to 10
set numTries to 0

repeat until numTries is greater than maxTries
	set numTries to numTries + 1
	set theWord to do shell script "n=$(cat /usr/share/dict/words | wc -l); cat -n /usr/share/dict/words | grep -w $(jot -r 1 1 $n) | cut -f2"
	try
		do shell script "curl [url=http://www.thefreedictionary.com/]http://www.thefreedictionary.com/"[/url] & theWord & " | grep -i \"word not found\""
	on error
		exit repeat
	end try
end repeat
return {numTries, theWord}