CSC 421: Algorithm Design and Analysis
Spring 2018

HW2: Decrease & Conquer Hangman


Hangman is a children's game in which one person picks a secret word, and the other tries to guess it one letter at a time. For this assignment, you will complete the implementation of a game of Hangman using honest and dishonest strategies. You are given an abstract Hangman class that provides the basic framework for playing a game. You are to define two different classes that complete its functionality (using vastly different strategies).

  1. HonestHangman.java: This class extends the Hangman abstract class in an honest way. That is, it should select the secret word at random from the supplied dictionary, and allow the player to guess that word.

    For example, suppose the secret word selected by the HonestHangman is "fresher". Initially, before any guesses have been made, this word would be redacted as "-------". However, after guessing 'e', the occurrences of 'e' in the word would be revealed, resulting in "--e--e-". A further guess of 's' would change the redacted form to "--es-e-". A game of Hangman continues until the player reveals the entire word (by guessing all of its letters). The goal is to do so uwing the fewest wrong guesses.

  2. DishonestHangman.java: This class extends the Hangman abstract class in a dishonest way. It works by randomly selecting a word and building a collection of all words in the dictionary that are that length. Each time the user makes a guess, however, the DishonestHangman cheats by producing a plausible response that is least helpful to the player. It does this by going through the collection of potential words and partitioning them based on their redacted forms. Whichever partition is the largest, it reports that redacted form as its response. The player has no way of knowing that the computer has cheated, since each response is consistent with all of the guesses to that point.

    For example, consider a dictionary that contains just eight 5-letter words:

        { "apple", "bread", "chair", "dread", "melee", "treat", "trust", "wreck" }
    
    Suppose the player's first guess was the letter 'e'. Then, the collection of plausible words would be partitioned based on their redacted pattern after guessing 'e':
    	"----e" → { "apple" }
    	"--e--"	→ { "bread", "dread", "treat", "wreck" }
    	"-----"	→ { "chair", "trust" }
    	"-e-ee"	→ { "melee" }
    
    Since the second partition is the largest, the DishonestHangman will say the guess was correct and update the redacted word to "--e--". If the next guess is the letter 't', then the DishonestHangman will partition this collection further:
    	"--e--"	→ { "bread", "dread", "wreck" }
    	"t-e-t"	→ { "treat" }
    
    and thus would select the first partition (responding that the guess was incorrect). The process continues until the partition is reduced to a single word, after which the DishonestHangman must respond honestly.

Note: you are provided two different drivers that can be used to test your two Hangman extensions. HangmanText is a text-based driver, where the user is repeatedly prompted to enter guesses and sees the results in a terminal window. HangmanGUI is a GUI-based driver, where the user enters guesses in a text field and clicks a button to see the results in a window. Both drivers are currently set up to test HonestHangman. To test DishonestHangman, simply comment out the line that initializes an HonestHangman and uncomment the line that initializes a DishonestHangman.