In java Cheater’s Hangman? 1 Premise Playing a game relies on trust. We intrinsi
ID: 3707649 • Letter: I
Question
In java
Cheater’s Hangman?
1 Premise
Playing a game relies on trust. We intrinsically assume that if we are playing a game against someone, then the rules will be followed. In other words, people aren’t prepared when someone might be cheating at a game, which makes it anexcellent strategy (if you prepared to accept the consequences).
Your goal is to write a computer program that allows a user to play a game of Hangman, but with a hidden twist. If you don’t know what Hangman is, go look it up on Wikipedia and play a few games on a whiteboard or a piece of paper with your friends.
A core assumption in hangman is that the person who knows the word does not change the hidden word. Our program is going to to that and do it without getting caught. Here’s an example of how this might work.
Suppose the player has made a lot of guesses and has only one wrong guess left. The player’s guesses have revealed:
GOA_
Based on the player’s previous guesses and knowledge of the English lan- guage, there are only two possible words left: “GOAD” and “GOAL.” In a normal game of hangman, where the person with the hidden word is playing according to the rules, this means the player has a 50% of guessing the right word.
In our game, the computer will cheat: if the player guesses the blank letter is “L,” the computer will say something to the effect of “Sorry, you’re out of guesses! You lose! The hidden word was “GOAD.”” If the player guesses “D” instead, the computer pretends that the hidden word “GOAL” the whole time. In other words, the player will always, always, always lose in this scenario because the computer will cheat about what the hidden word was.
1
2 How To Cheat at Hangman for Programmers and Time Travelers
Let’s learn how to cheat with a more thorough example. Pretend you’re playing hangman and have to choose a four letter hidden word for someone else to guess. You also happen to have a dictionary, unlimited time, and a galling, tragic, yet hilarious lack of morals.
Rather than choosing and sticking with a single hidden word like you’re supposed to, you make a list all four letter words. There’s a lot of them and many are inappropriate in an academic setting, so for simplicity’s sake, we’ll pretend English only has the following four letter words:
So you gather all those words into a list and lie to the player, telling him you’ve chosen your hidden word.
The player starts by guessing ‘E,’ a sound strategy, since ‘E’ is the most common letter in the English alphabet! You now have to reveal all the E’s in your word, if any. You haven’t chosen a word yet though, so you have a few options. Let’s underline all the E’s in our list of possible hidden words to see all out options.
We can categorize each of these into what we’ll call word families, which is grouped by what the hidden word would look like to the guesser if we had chosen that word as our hidden word.
The player would see if the hidden word was “THIS,” “LOOK,” or “GOOD.”
The player would see E if the word was “EGGS” or “ECHO.”
The player would see E if the hidden word was “TEAM.”
The player would see E E if the hidden word was “EDGE.”
You have to choose one of those families and that will limit your future choices. For example, if we choose the second word family, that means we’re committing to pretending we choose a hidden word that started with “E,” so we can’t lie about that any more. If we go with the first group, we commit to pretending our hidden word has no “E” in it. We can’t go back later and pretend it has an “E” in it, because the user will be able to remember he guessed that. Remember, we don’t the guesser to figure out we’re cheating.
Which word family should we go with then? There are many, many valid strategies. Maybe you decide to go with the word family with the most obscure words. Maybe you choose the word family that reveals the least letters.
2
I will use a much simpler strategy: choose the word family with the most words. Like any programmer with a propensity for cheating or time traveler, we’re afraid of commitment, so we’ll choose the largest word family to avoid being boxed into a single hidden word for as long as possible. Again, this isn’t necessarily the best strategy, but it is a relatively quick one and works rather well. We tell our guesser their guess is wrong, reveal , and now our list of hidden words is:
Next they guess “O,” so your word families are:• OO containing “LOOK” and “GOOD”
• containing “THIS”
So I’ll choose OO as the word family and reveal the “hidden” O’s.
The game ends when the user guesses all the letters, which is unlikely given all the cheating we’re doing, or if they run out of guesses. If all goes according to plan, the user will never know they’ve been hoodwinked!
3 Cheater’s Hangman
Your goal is to create my Cheater’s Hangman, which plays Hangman, but cheats by avoiding choosing a hidden word according to some strategy. Here’s the flow of the program.
Read the dictionary.txt and store it in your program at runtime. This is the list of words your program will use.
Ask the user to choose the size of the hidden word they want to try to guess. Keep asking them if there are no words of that length.
Ask the user to choose how many wrong guesses they get to have before they lose.
Create an initial list of hidden words using the dictionary and choosing all the words that have the length the using asked for.
Play hangman using our cheating algorithm:
(a) Print out the revealed letters, their wrong guesses, and the remaining number of wrong guesses
(b) Get the user’s new guess and be nice and ask them to reenter their letter if they already guessed it.
(c) Separate your list of hidden words into word families based on the input.
(d) Choose a word family using some strategy (I used the word family with the most words) and make that the new hidden word list. If this reveals letters to the user, reveal letters, otherwise the player loses a wrong guess.
(e) Keep going until:
(f) If all the letters are revealed, the player wins. If they player is out of wrong guesses, randomly pick a hidden word from the hidden word list and reveal it to the user, pretending that was your hidden word all along.
6. Ask if they want to play again.
First and foremost, so long as your program works, there is no right or wrong way to write this program. However, sitting down and thinking about what data structures to use will go a long way towards making your life easier. Plan before programming!
3.1 One last important thing
You’ll want to remove it when you play against your unsuspecting victims, but you should print out the size of you hidden word list at each guess. This will let you know your program is cheating
4 Advice
Since this is coming right after learning about Maps and Sets, that’s probably a good indication that you should use those data structures. The key here is to use a Map to help with word families, as maps are good at grouping things into categories.
*******Here is what I have so far*******
package hangman;
import java.io.*;
import java.util.*;
import java.util.Scanner;
public class Hangman {
public static String findPattern(char guess, String word, Set<Character> guesses) {
String replace = "[^" + guess;
for (char c : guesses) {
replace += c;
}
replace += "]";
return word.replaceAll(replace, "-");
}
public static String getNewUserView(Map<String, List<String>> fams) {
String best = "";
int sizeOfBest = 0;
for (String key : fams.keySet()) {
if (fams.get(key).size() > sizeOfBest) {
sizeOfBest = fams.get(key).size();
best = key;
}
}
return best;
}
public static List<String> createNewWL(String best, Map<String, List<String>> fams) {
return fams.get(best);
}
public static void main(String[] args) throws FileNotFoundException {
List<String> list = new ArrayList();
Scanner input = new Scanner(System.in);
System.out.println("Hey, We're going to play hangman, please choose the length of the word? ");
int length = input.nextInt();
System.out.println("How many times do you want to guess? ");
int numOfGuess = input.nextInt();
String fileName = "dictionary.txt";
Scanner words = new Scanner(new File(fileName));
while (words.hasNext()) {
String current = words.nextLine();
if (current.length() == length) {
list.add(current);
}
}
String userView = "";
for(int i = 0; i < length; i++){
userView += "-";
}
while (numOfGuess != 0) {
System.out.println("Please type in a letter, to see if you guessed correctly: ");
char userGuess = input.next().charAt(0);
Set<Character> storeGuess = new HashSet<>();
Map<String, List<String>> fams = new HashMap<>();
for (String word : list) {
String pattern = findPattern(userGuess, word, storeGuess);
List<String> wordlist;
if (fams.containsKey(pattern)) {
wordlist = fams.get(pattern);
} else {
wordlist = new ArrayList<String>();
}
if (!wordlist.contains(word)) {
wordlist.add(word);
}
fams.put(pattern, wordlist);
}
storeGuess.add(userGuess);
//MAIN PROBLEM **** Running paramteres through the getNewUserView method inorder to store and display the characters that the user chose.
getNewUserView(fams);
createNewWL(getNewUserView(fams), fams);
System.out.println(fams);
numOfGuess -= 1;
}
}
}
Explanation / Answer
import java.util.*;
import java.io.*;
public class HangmanMain {
public static final String DICTIONARY_FILE = "dictionary.txt";
public static final boolean SHOW_COUNT = true; // show words left
public static void main(String[] args) throws FileNotFoundException {
System.out.println("Welcome to the cse143 hangman game.");
System.out.println();
// open the dictionary file and read dictionary into an ArrayList
Scanner input = new Scanner(new File(DICTIONARY_FILE));
List<String> dictionary = new ArrayList<String>();
while (input.hasNext()) {
dictionary.add(input.next().toLowerCase());
}
// set basic parameters
Scanner console = new Scanner(System.in);
System.out.print("What length word do you want to use? ");
int length = console.nextInt();
System.out.print("How many wrong answers allowed? ");
int max = console.nextInt();
System.out.println();
// set up the HangmanManager and start the game
List<String> dictionary2 = Collections.unmodifiableList(dictionary);
HangmanManager hangman = new HangmanManager(dictionary2, length, max);
if (hangman.words().isEmpty()) {
System.out.println("No words of that length in the dictionary.");
} else {
playGame(console, hangman);
showResults(hangman);
}
}
// Plays one game with the user
public static void playGame(Scanner console, HangmanManager hangman) {
while (hangman.guessesLeft() > 0 && hangman.pattern().contains("-")) {
System.out.println("guesses : " + hangman.guessesLeft());
if (SHOW_COUNT) {
System.out.println(hangman.words().size() + " words left: "
+ hangman.words());
}
System.out.println("guessed : " + hangman.guesses());
System.out.println("current : " + hangman.pattern());
System.out.print("Your guess? ");
char ch = console.next().toLowerCase().charAt(0);
if (hangman.guesses().contains(ch)) {
System.out.println("You already guessed that");
} else {
int count = hangman.record(ch);
if (count == 0) {
System.out.println("Sorry, there are no " + ch + "'s");
} else if (count == 1) {
System.out.println("Yes, there is one " + ch);
} else {
System.out.println("Yes, there are " + count + " " + ch
+ "'s");
}
}
System.out.println();
}
}
// reports the results of the game, including showing the answer
public static void showResults(HangmanManager hangman) {
// if the game is over, the answer is the first word in the list
// of words, so we use an iterator to get it
String answer = hangman.words().iterator().next();
System.out.println("answer = " + answer);
if (hangman.guessesLeft() > 0) {
System.out.println("You beat me");
} else {
System.out.println("Sorry, you lose");
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.