Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Needs to be in JAVA. The Assignment. Your assignment is to write a computer prog

ID: 3818939 • Letter: N

Question

Needs to be in JAVA.

The Assignment.

Your assignment is to write a computer program which plays a game of Hangman using this “Evil Hangman” algorithm. In particular, your program should do the following:

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

3. 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!

4. 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!)

5. Play a game of Hangman using the Evil Hangman algorithm, as described below:

1. Construct a list of all words in the English language whose length matches the input length.

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

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

4. Partition the words in the dictionary into groups by word family.

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

6. 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.”

7. If the player correctly guesses the word, congratulate her.

6. Ask the player if she would like the list of remaining words in the current list to be printed to a text file. This is also for grading purposes.

7. Ask if the user wants to play again and loop accordingly.

In this assignment it's up to you to think about how you want to partition words into word families. Think about what kind of collections would be best for tracking word families and the master word list. Thinking through the design before you start coding will save you a lot of time and headache.

Advice, Tips, and Tricks

Since you're building this project from scratch, you'll need to do a bit of planning to figure out what the best data structures are for the program. There is no “right way” to go about writing this program, but some design decisions are much better than others. Here are some general tips and tricks that might be useful:

1. Letter position matters just as much as letter frequency. When computing word families, it's not enough to count the number of times a particular letter appears in a word; you also have to consider their positions. For example, “BEER” and “HERE” are in two different families even though they both have two E's in them. Consequently, representing word families as numbers representing the frequency of the letter in the word will get you into trouble.

2. Watch out for gaps in the dictionary. When the user specifies a word length, you will need to check that there are indeed words of that length in the dictionary. You might initially assume that if the requested word length is less than the length of the longest word in the dictionary, there must be some word of that length. Unfortunately, the dictionary contains a few “gaps.” The longest word in the dictionary has length 29, but there are no words of length 27 or 26. Be sure to take this into account when checking if a word length is valid.

3. Don't explicitly enumerate word families. If you are working with a word of length n, then there are 2npossible word families for each letter. However, most of these families don't actually appear in the English language. For example, no English words contain three consecutive U's, and no word matches the pattern E-EE-EE--E. Rather than explicitly generating every word family whenever the user enters a guess, see if you can generate word families only for words that actually appear in the word list. One way to do this would be to scan over the word list, storing each word in a table mapping word families to words in that family.

Explanation / Answer

Main.java
----------------
package hangman;

import java.io.File;
import java.io.IOError;

import hangman.EvilHangmanGame;
import hangman.EvilHangmanGame.GuessAlreadyMadeException;

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
EvilHangmanGame myGame = new iEvilHangmanGame();

Scanner s = new Scanner(System.in);
boolean win = false;
File f = new File(args[0]);
Set<String> words = new HashSet<String>();
int length = Integer.parseInt(args[1]);
String guess;
int guesses = Integer.parseInt(args[2]);
int counter = 0;
myGame.startGame(f, length);
while(counter < guesses)
{
try {

System.out.println("You have " + (guesses - counter) + " guesses left");
System.out.println("Used letters: " + myGame.printGuesses());
System.out.println("Word: " + myGame.printWord());
System.out.print("Enter a guess:");
guess = s.next();
if(!valid(guess))
throw new IOError(null);
words = myGame.makeGuess(Character.toLowerCase(guess.toCharArray()[0]));
if(myGame.getPattern().filled == 0)
{
System.out.println("Sorry, there are no " + guess + "'s");
counter++;
}
else if(myGame.getPattern().filled == 1)
{
System.out.println("Yes, there is 1 " + guess);
}
else
{
System.out.println("Yes, there are " + myGame.getPattern().filled + " " + guess + "'s");
}
System.out.println("");
if(words.size()==1 && !myGame.printWord().contains("-"))
{
win = true;
break;
}
}
catch (GuessAlreadyMadeException e) {
System.out.println("You already used that letter");
System.out.println("");
}
catch(IOError e)
{
System.out.println("Invalid input");
System.out.println("");
}
}
if(win)
{
System.out.println("You Win!");
System.out.println(myGame.printWord());
}
else{
System.out.println("You lose!");
System.out.println("The word was: " + words.toArray(new String[0])[0]);
}
s.close();
}

private static boolean valid(String s) {
if(s.length() != 1)
return false;
if(!(Character.isLetter(s.toCharArray()[0])))
return false;
return true;
}

}

-----------------
EvilHangmanGame.java

---------------------------------------

package hangman;

import java.io.File;
import java.util.Set;

public interface EvilHangmanGame {

   @SuppressWarnings("serial")
   public static class GuessAlreadyMadeException extends Exception {
   }

   /**
   * Starts a new game of evil hangman using words from <code>dictionary</code>
   * with length <code>wordLength</code>
   *
   * @param dictionary Dictionary of words to use for the game
   * @param wordLength Number of characters in the word to guess
   */
   public void startGame(File dictionary, int wordLength);

   /**
   * Make a guess in the current game.
   *
   * @param guess The character being guessed
   * @return The set of strings that satisfy all the guesses made so far
   * in the game, including the guess made in this call. The game could claim
   * that any of these words had been the secret word for the whole game.
   *
   * @throws GuessAlreadyMadeException If the character <code>guess</code>
   * has already been guessed in this game.
   */
   public Set<String> makeGuess(char guess) throws GuessAlreadyMadeException;


   public String printDict();


   public void printMap();


   public String printWord();


   public String printGuesses();


   public Pattern getPattern();

}

-------------------------------------

iEvelHangmanGame.java
-----------------------------------------

package hangman;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


public class iEvilHangmanGame implements EvilHangmanGame{
   Dictionary myDict;
   ArrayList<String> currentWords;
   Map<Pattern, ArrayList<String> > myMap;
   Set<Character> guessed;
   ArrayList<Pattern> patternList;
   int length;
   StringBuilder word;
   public Pattern mergePattern;

   public iEvilHangmanGame()
   {
       word = new StringBuilder();
       patternList = new ArrayList<Pattern>();
       currentWords = new ArrayList<String>();
       myDict = new Dictionary();
       guessed = new HashSet<Character>();
       mergePattern = new Pattern();
       myMap = new HashMap<Pattern, ArrayList<String>>();
       length = 0;
   }

   @Override
   public void startGame(File dictionary, int wordLength) {
       for(int i = 0; i < wordLength; i++)
       {
           word.append('-');
       }
       myDict.create(dictionary, wordLength);
       currentWords = myDict.words;
       guessed = new HashSet<Character>();
       myMap = new HashMap<Pattern, ArrayList<String>>();
       length = wordLength;
   }

   public Set<String> makeGuess(char guess) throws GuessAlreadyMadeException {
       guess = toLower(guess);
       myMap = new HashMap<Pattern, ArrayList<String>>();
       patternList = new ArrayList<Pattern>();
       if(guessed.contains(guess))
       {
           throw new GuessAlreadyMadeException();
       }
       else{
           guessed.add(guess);
           fillMap(guess);
           biggest();
           if(patternList.size() != 1)
           {
               fewest();
               if(patternList.size() != 1)
               {
                   rightMost();
               }
           }
           mergePattern = patternList.get(0);
           currentWords = myMap.get(mergePattern);
           System.out.println(word);
       }
    
       Set<String> tempSet = new HashSet<String>(currentWords);
       merge(mergePattern);
       return tempSet;
   }


   public void fillMap(char g)
   {
       for(int i = 0; i < currentWords.size(); i++)
       {
           ArrayList<String> tempLst = new ArrayList<String>();
           Pattern p = new Pattern(currentWords.get(i),g);
           if(myMap.containsKey(p))
           {
               tempLst = myMap.get(p);
               tempLst.add(currentWords.get(i));
               myMap.put(p, tempLst);
           }
           else
           {
               tempLst.add(currentWords.get(i));
               myMap.put(p, tempLst);
           }
       }
   }

   public void biggest()
   {
       int biggest = 0;
       for(Map.Entry<Pattern, ArrayList<String>> entry : myMap.entrySet())
       {
           if(entry.getValue().size() > biggest)
           {
               biggest = entry.getValue().size();
           }
       }
    
       for(Map.Entry<Pattern, ArrayList<String>> entry : myMap.entrySet())
       {
           if(entry.getValue().size() == biggest)
           {
               patternList.add(entry.getKey());
           }
       }
   }

   public void fewest()
   {
       ArrayList<Pattern> tempList = patternList;
       patternList = new ArrayList<Pattern>();
       int fewest = length;
       for(int i = 0; i < tempList.size(); i++)
       {
           if(tempList.get(i).filled < fewest)
               fewest = tempList.get(i).filled;
       }
    
       for(int i = 0; i < tempList.size(); i++)
       {
           if(tempList.get(i).filled == fewest)
           {
               patternList.add(tempList.get(i));
           }
       }
   }

   public void rightMost()
   {
       ArrayList<Pattern> tempList = patternList;
       patternList = new ArrayList<Pattern>();
       Pattern tempPat = tempList.get(0);
       for(int i = 1; i < tempList.size(); i++)
       {
           if(tempPat.hashCode() > tempList.get(i).hashCode())
           {
               tempPat = tempList.get(i);
           }
       }
       patternList.add(tempPat);
   }

   public char toLower(char g)
   {
       String s = "" + g;
       s = s.toLowerCase();
       g = s.charAt(0);
       return g;
   }

   public void printMap()
   {
       System.out.println("PrintMap:");
       for(Map.Entry<Pattern, ArrayList<String> > entry : myMap.entrySet())
       {
           System.out.println("Key: " + entry.getKey().toString());
           for(int i = 0; i < entry.getValue().size(); i++)
           {
               System.out.println("Value: " + entry.getValue().get(i));
           }
       }

   }

   public String printDict()
   {
       return myDict.toString();
   }


   public String printWord() {
       return word.toString();
   }

   public Pattern getPattern(){
       return mergePattern;
   }

   public void merge(Pattern p)
   {
       for(int i = 0; i < word.length(); i++)
       {
           if(p.pattern.charAt(i) != '-')
           {
               word.setCharAt(i, p.pattern.charAt(i));
           }
       }
   }

   @Override
   public String printGuesses() {
       String out = "";
       Character[] s = guessed.toArray(new Character[0]);
       Arrays.sort(s);
       for(int i = 0; i < s.length; i++)
       {
           out = out + " " + (char)s[i];
       }
       return out;
   }

}


------------------------------------------
Pattern.java
--------------------------------------
package hangman;

public class Pattern {
String pattern;
int filled;
public Pattern()
{
pattern = "";
filled = 0;
}

public Pattern(int l)
{
pattern = "";
filled = 0;
for(int i = 0; i < l; i++)
{
pattern = pattern + '-';
}
}

public Pattern(String s, char g)
{
pattern = "";
filled = 0;
for(int i = 0; i < s.length(); i++)
{
if(s.charAt(i) == g)
{
pattern = pattern + g;
filled++;
}
else
pattern = pattern + '-';
}
}

@Override
public int hashCode() {
int t = 0;
for(int i = 0; i < pattern.length(); i++)
{
if(pattern.charAt(i) != '-')
{
t = (int) (t + Math.pow(2.0, (pattern.length() - i)));
}
}
return t;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pattern other = (Pattern) obj;
if (filled != other.filled)
return false;
if (pattern == null) {
if (other.pattern != null)
return false;
} else if (!pattern.equals(other.pattern))
return false;
return true;
}

public String toString(){
return pattern;
}

}
-------------------------------------

Dictionary.java
---------------------------------

package hangman;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Dictionary {
   ArrayList<String> words;
   int size;

   public Dictionary()
   {
       words = new ArrayList<String>();
       size = 0;
   }

   public void create(File d, int length)
   {
       Set<String> tempSet = new HashSet<String>();
       String tempStr;
       try {
           Scanner s = new Scanner(new BufferedReader(new FileReader(d)));
           while(s.hasNext())
           {
               tempStr = s.next();
               if(tempStr.length() == length)
               {
                   tempStr = tempStr.toLowerCase();
                   tempSet.add(tempStr);
                
               }
           }
           size = tempSet.size();
           words = new ArrayList<String>(tempSet);
           s.close();
       } catch (FileNotFoundException e) {
           System.out.println("Error: File Not Found");
       }
   }

   public String get(int i)
   {
       return words.get(i);
   }

   public String toString()
   {
       String out = "";
       for(int i = 0; i < words.size(); i++)
       {
           out = out + words.get(i) + ' ';
       }
       return out;
   }
}


--------------------------------------

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote