While there are many viable strategies for building competitive computer game players, there is one approach that has been fairly neglected in modern research – cheating. Why spend all the effort trying to teach a computer the nuances of strategy when you can simply write a program to play dirty and win handily all the time?
Here, we build a mischievous program that bends the rules of Hangman to trounce its human opponent time and time again. In doing so, we use abstract data types and iterators to end up with a piece of software which will be highly entertaining. At least, from your perspective. ☺
In case you aren’t familiar with the game Hangman, the rules are as follows:
-
One player chooses a secret word, then writes out a number of dashes equal to the word length.
-
The other player begins guessing letters. Whenever she guesses a letter contained in the hidden word, the first player reveals each instance of that letter in the word. Otherwise, the guess is wrong.
-
The game ends either when all the letters in the word have been revealed or when the guesser has run out of guesses.
Fundamental to the game is the fact the first player accurately represents the word she has chosen. That way, when the other players guess letters, she can reveal whether that letter is in the word.
But what happens if the player doesn’t do this? This gives the player who chooses the hidden word an enormous advantage. For example, suppose that you’re the player trying to guess the word, and at some point you end up revealing letters until you arrive at this point with only one guess remaining: D O – B L E
There are only two words in the English language that match this pattern: “doable” and “double.” If the player who chose the hidden word is playing fairly, then you have a fifty-fifty chance of winning this game if you guess 'A' or 'U' as the missing letter. However, if your opponent is cheating and hasn’t actually committed to either word, then there is no possible way you can win this game. No matter what letter you guess, your opponent can claim that she had picked the other word, and you will lose the game.
That is, if you guess that the word is “doable,” she can pretend that she committed to “double” the whole time, and vice-versa.
The program does the following:
-
Reads the file dictionary.txt, which contains the full contents of the Official Scrabble Player’s Dictionary, Second Edition. This word list has over 120,000 words, which should be more than enough for our purposes.
-
Prompt the user for a word length, reprompting as necessary until she enters a number such that there’s at least one word that’s exactly that long. That is, if the user wants to play with words of length -42 or 137, since no English words are that long, you should reprompt her.
-
Prompt the user for a number of guesses, which must be an integer greater than zero. Don’t worry about unusually large numbers of guesses – after all, having more than 26 guesses is clearly not going to help your opponent!
-
Prompt the user for whether she wants to have a running total of the number of words remaining in the word list. This completely ruins the illusion of a fair game that you’ll be cultivating, but it’s quite useful for testing (and grading!)
-
Play a game of Hangman using the Evil Hangman algorithm, as described below:
-
Construct a list of all words in the English language whose length matches the input length.
-
Print out how many guesses the user has remaining, along with any letters the player has guessed and the current blanked-out version of the word. If the user chose earlier to see the number of words remaining, print that out too.
-
Prompt the user for a single letter guess, reprompting until the user enters a letter that she hasn’t guessed yet. Make sure that the input is exactly one character long and that it’s a letter of the alphabet.
-
Partition the words in the dictionary into groups by word family.
-
Find the most common “word family” in the remaining words, remove all words from the word list that aren’t in that family, and report the position of the letters (if any) to the user. If the word family doesn’t contain any copies of the letter, subtract a remaining guess from the user.
-
If the player has run out of guesses, pick a word from the word list and display it as the word that the computer initially “chose.”
-
If the player correctly guesses the word, congratulate her.
-
-
Ask if the user wants to play again and loop accordingly.