Я создал класс под названием HangmanManager
, который управляет «злой» версией Hangman, где программа не выбирает слово в начале игры. Вместо этого он ждет, пока пользователь угадает символ, с помощью которого затем сужает список слов, содержащих буквы, которые угадывает пользователь.
HangmanMain. java
import java.util.*;
import java.io.*;
public class HangmanMain {
public static final String DICTIONARY_FILE = "dictionary2.txt";
public static final boolean SHOW_COUNT = true; // show # of choices 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<>();
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("words : " + hangman.words().size());
}
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");
}
}
}
HangmanManager
import java.util.*;
public class HangmanManager {
private Set<String> words;
private Set<Character> guesses;
private int guessesLeft;
private String currentPattern;
// Pre: Throws IllegalArgumentException if length of word is less than 1 or
// if the maximum number of guesses is less than 0
// Post: Initializes state of the hangman game by taking in the set of all words
// from the given dictionary, length of words, and max number of guesses
public HangmanManager(Collection<String> dictionary, int length, int max) {
if (length < 1 || max < 0) {
throw new IllegalArgumentException();
}
currentPattern = "";
guessesLeft = max;
words = new TreeSet<String>();
guesses = new TreeSet<Character>();
for (String str : dictionary) {
if (str.length() == length) {
words.add(str);
}
}
for (int i = 0; i < length; i++) {
currentPattern += "- ";
}
}
// Returns the current set of words being used by the manager
public Set<String> words() {
return words;
}
// Returns the number of guesses left
public int guessesLeft() {
return guessesLeft;
}
// Returns the set of characters already guessed by user
public Set<Character> guesses() {
return guesses;
}
// Pre: Throws IllegalStateException if the set of words is empty
// Post: Returns the current pattern
public String pattern() {
if (words.isEmpty()) {
throw new IllegalStateException();
}
return currentPattern;
}
// Pre: Throws IllegalStateException if there are no guesses left or if set of words is empty
// Pre: Throws IllegalArgumentException if the user guess was already guessed before
// Post: Updates the dictionary by determining which set of words from it to choose from in
// response to user guesses. Returns occurrences of guessed letters in the new pattern.
public int record(char guess) {
if(guessesLeft < 1 || words.isEmpty()) {
throw new IllegalStateException();
}
if (guesses.contains(guess)) {
throw new IllegalArgumentException();
}
int count = 0;
Map<String, Set<String>> mapPattern = new TreeMap<String, Set<String>>();
for (String mapWords : words) {
String newPattern = constructPattern(guess, mapWords);
if (mapPattern.containsKey(newPattern)) {
mapPattern.get(newPattern).add(mapWords);
} else {
Set<String> setPattern = new TreeSet<String>();
setPattern.add(mapWords);
mapPattern.put(newPattern, setPattern);
}
}
String key = getLargestSet(mapPattern);
if (currentPattern.equals(key)) {
guessesLeft--;
} else {
count = updateCount(key, currentPattern);
}
currentPattern = key;
words = mapPattern.get(key);
guesses.add(guess);
return count;
}
private String getLargestSet(Map<String, Set<String>> map) {
int max = 0;
String pattern = "";
for (String key : map.keySet()) {
if (map.get(key).size() > max) {
max = map.get(key).size();
pattern = key;
}
}
return pattern;
}
private int updateCount(String wordOne, String wordTwo) {
int newCount = 0;
for (int i = 0; i < wordOne.length(); i++) {
if (wordOne.charAt(i) != wordTwo.charAt(i)) {
newCount++;
}
}
return newCount;
}
private String constructPattern(char guess, String word) {
String pattern = "";
for (int i = 0; i < word.length(); i++) {
if (guess == word.charAt(i)) {
pattern += Character.toString(guess);
} else {
pattern += currentPattern.substring(i, i + 1);
}
}
return pattern;
}
}
Это один пример вывода того, что я хочу отобразить
Welcome to the cse143 hangman game.
What length word do you want to use? 4
How many wrong answers allowed? 7
guesses : 7
words : 9
guessed : []
current : - - - -
Your guess? e
Sorry, there are no e's
guesses : 6
words : 3
guessed : [e]
current : - - - -
Your guess? o
Yes, there are 2 o's
guesses : 6
words : 2
guessed : [e, o]
current : - o o -
Your guess? t
Sorry, there are no t's
guesses : 5
words : 2
guessed : [e, o, t]
current : - o o -
Your guess? f
Sorry, there are no f's
guesses : 4
words : 2
guessed : [e, f, o, t]
current : - o o -
Your guess? c
Sorry, there are no c's
guesses : 3
words : 1
guessed : [c, e, f, o, t]
current : - o o -
Your guess? n
Sorry, there are no n's
guesses : 2
words : 1
guessed : [c, e, f, n, o, t]
current : - o o -
Your guess? d
Yes, there is one d
guesses : 2
words : 1
guessed : [c, d, e, f, n, o, t]
current : - o o d
Your guess? h
Sorry, there are no h's
guesses : 1
words : 1
guessed : [c, d, e, f, h, n, o, t]
current : - o o d
Your guess? g
Yes, there is one g
answer = good
You beat me
Это мой текущий вывод из моей программы при запуске HangmanMain
Welcome to the cse143 hangman game.
What length word do you want to use? 4
How many wrong answers allowed? 7
guesses : 7
words : 9
guessed : []
current : - - - -
Your guess? e
Sorry, there are no e's
guesses : 7
words : 3
guessed : [e]
current : - -
Your guess? o
Yes, there are 2 o's
guesses : 7
words : 2
guessed : [e, o]
current : -oo
Your guess? t
Sorry, there are no t's
guesses : 6
words : 2
guessed : [e, o, t]
current : -oo
Your guess? f
Sorry, there are no f's
guesses : 5
words : 2
guessed : [e, f, o, t]
current : -oo
Your guess? c
Sorry, there are no c's
guesses : 4
words : 1
guessed : [c, e, f, o, t]
current : -oo
Your guess? n
Sorry, there are no n's
guesses : 3
words : 1
guessed : [c, e, f, n, o, t]
current : -oo
Your guess? d
Yes, there is one d
guesses : 3
words : 1
guessed : [c, d, e, f, n, o, t]
current : -ood
Your guess? h
Sorry, there are no h's
guesses : 2
words : 1
guessed : [c, d, e, f, h, n, o, t]
current : -ood
Your guess? g
Yes, there is one g
answer = good
You beat me
Первоначально я получил пробелы между тире, добавив пробел в строке currentPattern += "- ";
в моем конструкторе public HangmanManager(Collection<String> dictionary, int length, int max)
. Если я удаляю пробел, моя программа работает и возвращает намеченный результат, но только без пробелов между тире.