-1

So I'm trying to create a small hangman mini-game. Unfortunately, I keep receiving the same error. I've attempted to re-do the game twice, but still can't seem to get it right. I'm sure it is simply some logic error or something.

I'm still relatively new to Java, so any help would be appreciated.

I've split the program into three classes. One for the Hangman object, one for the array containing said objects, and one for using the array of those objects. The three parts below are a snippet from the game.

Class 1: Hangman

package hangman2;

import java.util.*;
import java.io.*;

public class Hangman {

    private ArrayList<String> words = new ArrayList<>();
    private int diff;

    public Hangman(String fileName, int difficulty) {

        diff = difficulty;
        //easy = 0; medium = 1; hard = 2

        try {
            Scanner scanFile  = new Scanner(new File(fileName));

            while(scanFile.hasNext()) {

                String line = scanFile.nextLine();
                Scanner scanLine = new Scanner(line);
                String tempWord = scanLine.next();

                words.add(tempWord);
            }
        }
        catch (FileNotFoundException e) {
            System.out.println("File not found\n" + e);
        }
    }

    //Gets
    public ArrayList<String> getWords() { return words; }
    public int getDifficulty() { return diff; }

    //Sets
    public void addWord(String word) { words.add(word); }
}

Class 2: HangmanArray

package hangman2;

import java.util.ArrayList;
import javax.swing.JOptionPane;

public class HangmanArray {

    private Hangman easyHangman;
    private Hangman mediumHangman;
    private Hangman hardHangman;

    public HangmanArray() {

        easyHangman = new Hangman("easy.txt", 0);
        mediumHangman = new Hangman("medium.txt", 1);
        hardHangman = new Hangman("hard.txt", 2);
    }

    public String getRandomWord() {

        Hangman workingHangman = chooseDifficulty();
        int max = workingHangman.getWords().size();
        int randIndex = (int) (Math.random() * max);

        return workingHangman.getWords().get(randIndex);
    }

    private Hangman chooseDifficulty() {

        int chosenDifficulty = Integer.parseInt(JOptionPane.showInputDialog("Choose difficulty level\n"
                + "1: Novice\n2: Intermediate\n3: Expert"));
        Hangman retHangman = null;

        switch(chosenDifficulty) {

            case 1: retHangman = easyHangman; break;
            case 2: retHangman = mediumHangman; break;
            case 3: retHangman = mediumHangman; break;
        }

        if (retHangman == null) {

            System.out.println("Chosen difficulty not within range of [1;3]\nexiting");
            System.exit(0);
        }

        return retHangman;
    }
}

Class 3: HangmanUI

package hangman2;

public class HangmanUI {

    public static void main(String[] args) {

        HangmanArray hangmanArray = new HangmanArray();
        System.out.println(hangmanArray.getRandomWord());
    }
}

The error appears to be coming from line 25 of HangmanArray when difficulty 2 or 3 is selected:

return workingHangman.getWords().get(randIndex);

Any help is appreciated.

M.I.G
  • 45
  • 6
  • what is the exact error message? Also: it's nice that you say which line the problem might be on, but there are no linenumbers in SO, so we still don't know which line you are talking about – Stultuske Sep 13 '18 at 10:31
  • Please do not forget to close your Stream in the constructor of the Hangman class using `scanFile.close()` in a `finally` clause or even better a try-with-resources construct. – Ben Sep 13 '18 at 10:35
  • 1
    When you choose difficulty 2 or 3, are there any words at all? Or does `workingHangman.getWords().size()` return `0` in that case, in which index 0 will be chosen which is an invalid index for an empty list? – Jesper Sep 13 '18 at 10:36
  • `case 3: retHangman = mediumHangman; break;` should be `case 3: retHangman = hardHangman; break;` – Adder Sep 13 '18 at 10:38
  • check the size first and than try to fetch the value – SaviNuclear Sep 13 '18 at 10:49

1 Answers1

1

You should check whether max is 0 and, if so, return null or an empty string, then handle this special case.
I used Random.nextInt() instead of int randIndex = (int) (Math.random() * max);

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence. The general contract of nextInt is that one int value in the specified range is pseudorandomly generated and returned. All bound possible int values are produced with (approximately) equal probability

Keep in mind that the index of last element is size()-1

public String getRandomWord() {

    Hangman workingHangman = chooseDifficulty();
    int max = workingHangman.getWords().size();
    if (max == 0) {
         return "";
    }

    int randIndex = new Random().nextInt(max); // returns an integer between 0 and max-1

    return workingHangman.getWords().get(randIndex);
}  

You should also use try-with-resources to ensure that resources you're using are closed once you finisched with them.

public Hangman(String fileName, int difficulty) {

    diff = difficulty;
    //easy = 0; medium = 1; hard = 2

    try (Scanner scanFile  = new Scanner(new File(fileName))) {

        while(scanFile.hasNext()) {

            String line = scanFile.nextLine();
            Scanner scanLine = new Scanner(line);
            String tempWord = scanLine.next();

            words.add(tempWord);
        }
    }
    catch (FileNotFoundException e) {
        System.out.println("File not found\n" + e);
    }
}

Lastly I suggest to use the debugger in order to know what you're putting into every Hangman.

RubenDG
  • 1,365
  • 1
  • 13
  • 18