I have a project for my programming class at school where we are supposed to make an evil hangman game, which is where the computer doesn't pick a word until it has to. In order to fool the user into thinking it is playing fairly, the computer only considers words with the same letter pattern.
I got something that I think should work but after just guessing the letters "a" and "e" my array has an ArrayIndexOutOfBoundsException and I've been trying to figure it out for the past few hours using a debugger but I still don't see the problem and I mean the whole class works for the first letter but it just breaks on the second. It happens when I return the patternArr[indexOfMax] at the end of the HangmanManager class. Why isn't it working like I expect it to?
This is a link to the dictionary file I have been using (you have to use a text file with a bunch of words in it for the game to work): http://www-personal.umich.edu/~jlawler/wordlist.html
Now here is my program:
HangmanManager Class
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class HangmanManager {
private SortedSet<String> wordset;
private SortedSet<Character> guessSet;
private String wordPattern;
private int guessesLeft;
public HangmanManager(List<String> dictionary, int length, int max){
if(length < 1 || max < 0) {
throw new IllegalArgumentException();
}
wordset = new TreeSet<String>();
for(String words: dictionary) {
if(words.length() == length) {
wordset.add(words);
}
}
wordPattern = "";
for (int i = 0; i < length; i++) {
wordPattern += "- ";
}
guessesLeft = max;
guessSet = new TreeSet<Character>();
}
//Returns the managers words
public Set<String> words() {
return wordset;
}
//Returns the number of guesses left
public int guessesLeft() {
return guessesLeft - guessSet.size();
}
//Returns the guessed letters
public SortedSet<Character> guesses() {
return guessSet;
}
//Returns String pattern
public String pattern() {
return wordPattern;
}
public int record(char guess) {
guessSet.add(guess);
return comparePatterns(wordset, guess);
}
private String makePattern(char guess, String word) {
String position = "";
char[] letters = word.toCharArray();
for (int i = 0; i < word.length(); i ++) {
if (letters[i] == guess) {
position = position + guess + " ";
} else {
position = position + "- ";
}
}
return position;
}
//This method is supposed to take out all the patterns that don't match
// the String commonPattern
private int comparePatterns(SortedSet<String> mySet, char guess) {
String[] wordArray = new String[mySet.size()];
wordArray = (String[]) mySet.toArray(wordArray);
String[] patternArray = new String[wordArray.length];
List<String> tempList = new ArrayList<String>();
for(int i = 0; i < wordArray.length; i++) {
patternArray[i] = makePattern(guess, wordArray[i]);
}
String commonPattern = getMostCommonPattern(guess, patternArray);
int rightGuess = 0;
for(int i = 0; i > commonPattern.length(); i ++) {
if(commonPattern.charAt(i) == guess) {
rightGuess++;
}
}
for(int j = 0; j < patternArray.length; j++) {
if(commonPattern.equals(patternArray[j])) {
tempList.add(wordArray[j]);
}
}
wordset.removeAll(wordset);
wordset.addAll(tempList);
return rightGuess;
}
//This method gets the most common pattern
//THIS METHOD BREAKS
private String getMostCommonPattern(char guess, String[] patternArr) {
List<String> patternList = Arrays.asList(patternArr);
int[] countArray = new int[patternArr.length];
for(int i = 0; i < patternArr.length; i++) {
countArray[i] = Collections.frequency(patternList, patternArr[i]);
}
int max = 0;
int indexOfMax = 0;
for (int j = 0; j < countArray.length; j++) {
if(max < countArray[j]) {
max = countArray[j];
indexOfMax = j;
} else if (max > countArray[j]) {
}else if (max == countArray[j]) {
}
}
return patternArr[indexOfMax];
}
}
HangmanMain class
import java.util.*;
import java.io.*;
public class HangmanMain {
public static final String DICTIONARY_FILE = "C:\\Users\\Zoratu\\Desktop\\EvilHangman\\dictionary.txt";
public static final boolean DEBUG = false; // 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 (DEBUG) {
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");
}
}
And thanks for taking the time to help a beginner like me.