1

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.

  • 4
    Read the stacktrace. On which line do you get the Exception? What Index do you use and what size does your array have? – Simulant May 03 '17 at 16:52
  • an `ArrayIndexOutOfBoundsException` is just you trying to access an index that doesn't exist on your array. Simple as that. E.g. you have `array {"A", "B", "C"}` this is an array with length 3 which means that you can only access indexes 0, 1 and 2. If for that array you try to access index 3 you will get this error. So you have to figure out where are you trying to access an nonexistent index on the array. Follow the advice given by @Simulant and you will find out. – Jorge Campos May 03 '17 at 16:56
  • 1
    Also in `for(int i = 0; i > commonPattern.length(); i ++)` loop will never execute. – Rajeev Singh May 03 '17 at 16:57
  • Welcome to Stack Overflow! [What does your step debugger tell you?](http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) –  May 03 '17 at 17:02
  • @Rajeev Singh Wow thanks man that was actually pretty much the whole problem haha, I can't believe I missed that. – Chris Goodburn May 03 '17 at 18:17

1 Answers1

-1

Output lines to the console or debug file, so you can track exactly where in the code the dimensions of an array are being violated, or handle the exception (read up on try catch).

The reason one would want to do this is because it allows debugging without the developer tools, since it's part of the program, and allows end-users to file bug reports. Recognizing these kinds of problems also means you can add code to resolve it internally without the user ever being aware of it. Although this is just a relative simple problem which requires an internal solution, some problems may arise in the future that are system, environment or user specific, so it's better to get used to it early on.

These are annoying bugs to encounter, but real easy to resolve when you find them. It's almost like forgetting a bracket; Simple to overlook, a [censored] to track, and you'll slap yourself when you find it, or at least, that's my experience ;-)

https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html

RolanDecoy
  • 39
  • 5
  • Welcome to Stack Overflow! Please read [How do I write a good answer?](http://stackoverflow.com/help/how-to-answer) before attempting to answer more questions. –  May 05 '17 at 17:54