0
votes

I am writing a code where a player gets to play hangman with a random word chosen from a text file. I keep getting this null pointer exception error, and I am not sure why. Sometimes when I run the program, I have no problems. But sometimes when I run, the program immediately crashes given me the null pointer exception error. Can anyone help me figure out why? Here is my code:

--Edit-- Error occurs in displayGallows method, when trying to set the variable puzzle.

import java.util.Scanner;
import java.util.Random;
import java.io.*;

public class Hangman {

    private Scanner in = new Scanner(System.in);
    private boardPiece[] board = {new boardPiece(0),new boardPiece(0),new boardPiece(3),
            new boardPiece(1),new boardPiece(2),new boardPiece(0)};
    private String puzzle; 
    private String puzzleWord;
    private int puzzleIndex;
    private Random generator = new Random(System.currentTimeMillis());
    private boolean win;
    private boolean over;
    private String correct = "";
    //private String guesses = "";
    private char guesses[] = new char[26];
    private int guessed;
    private int misses;
    private String puzzles[] = new String[5];
    // = {"hello world","java is cool","athena is smelly","zach is awesome","athena is cool"};

    public static void main(String [] args){

        String letter;
        String again = "y";

        Hangman game = new Hangman();

        try{
            BufferedReader in = 
                new BufferedReader(new FileReader("puzzles.txt"));

            int count = 0;
            while (in.ready()) { //while there is another line in the input file
                game.puzzles[count] = in.readLine(); //get line of data
                count++; //Increment CWID counter
            }
            in.close(); 
        }
        catch(IOException e){
            System.out.println("Error during reading/writing");
        }

        /*for(int x=0;x<game.puzzles.length;x++)
        System.out.println("PUZZLE " + x + ": " + game.puzzles[x]);*/

        System.out.println("Welcome to HangMan!");
        System.out.println("To play, guess a letter to try to guess the word.");
        System.out.println("Every time you choose an incorrect letter another");
        System.out.println("body part appears on the gallows. If you guess the");
        System.out.println("word before you're hung, you win");
        System.out.println("If you get hung, you lose");

        System.out.println("Time to guess...");
        while(again.charAt(0) == 'y'){
            game.displayGallows();

            while(!game.over){
                game.printBoard();
                //System.out.println("Guessed: " + game.guesses);
                game.printLettersGuessed();
                System.out.println("The word so far: " + game.puzzle);
                System.out.println("Choose a letter: ");
                letter = game.in.next();

                //game.guesses = game.guesses + " " + letter.charAt(0);
                game.guesses[game.guessed] = letter.charAt(0);
                game.guessed++;
                game.sort();

                if(game.puzzleWord.indexOf(letter.charAt(0)) != -1){
                    game.correct = game.correct + letter.charAt(0);
                    game.puzzle = game.puzzleWord.replaceAll("[^"+game.correct+" ]","-");
                    if(game.puzzleWord.replaceAll("["+game.correct+" ]","").length() == 0){
                        game.win = true;
                        game.over = true;
                    }
                }
                else
                    game.PrintWrongGuesses();
            }
            game.printBoard();
            System.out.println("Solution: " + game.puzzleWord);
            if(game.win)
                System.out.println("Congratulations! You've solved the puzzle!");
            else
                System.out.println("You failed, failer!");

            System.out.println();
            System.out.println("Congratulations, you win!");
            System.out.println("Do you want to play again? (y/n)");
            again = game.in.next();
        }
        System.out.println("Goodbye!");
    }

    public void displayGallows(){

        win = false;
        over = false;

        board[0].piece = "    ______ ";
        board[1].piece = "    |    | ";
        board[2].piece = "         | ";
        board[3].piece = "         | ";
        board[4].piece = "         | ";
        board[5].piece = "  _______| ";

        puzzleIndex = generator.nextInt(puzzles.length);
        puzzleWord = puzzles[puzzleIndex];

        puzzle = puzzleWord.replaceAll("[A-Za-z]","-");
        correct = "";
        //guesses = "";
        for(int x=0;x<26;x++)
            guesses[x] = '~';
        guessed = 0;
        misses = 0;
    }

    public void printBoard(){
        for(int x =0;x<6;x++)
            System.out.println(board[x].piece);
    }

    public void PrintWrongGuesses(){
        misses++;
        System.out.println();
        if(misses == 1){
            board[2].piece = "    0    | ";
            System.out.println("Number of misses: " + misses);
        }
        else if(misses == 2){
            board[2].piece = "   \\0    | ";
            System.out.println("Number of misses: " + misses);
        }
        else if(misses == 3){
            board[2].piece = "   \\0/   | ";
            System.out.println("Number of misses: " + misses);
        }
        else if(misses == 4){
            board[3].piece = "    |    | ";
            System.out.println("Number of misses: " + misses);
        }
        else if(misses == 5){
            board[4].piece = "   /     | ";
            System.out.println("Number of misses: " + misses);
        }
        else if(misses == 6){
            board[4].piece = "   / \\   | ";
            System.out.println("Number of misses: " + misses);
            over = true;
        }

    }

    public void printLettersGuessed(){
        System.out.print("Letters guessed already: ");
        for(int x=0;x<26;x++){
            if(guesses[x] != '~')
                System.out.print(guesses[x] + " ");
        }
        System.out.println();
    }

    public void sort(){
        boolean doMore = true;
        while (doMore) {
            doMore = false;  // assume this is last pass over array
            for (int i=0; i<guesses.length-1; i++) {
                if (guesses[i] > guesses[i+1]) {
                    char temp = guesses[i];  
                    guesses[i] = guesses[i+1];  
                    guesses[i+1] = temp;
                    doMore = true;  // after an exchange, must look again 
                }
            }
        }
    }

    class boardPiece{
        public String piece;
        public int total;
        public int used;

        boardPiece(int x){
            used = 0;
            total = x;
        }
    }   
}

Thank you

4
In which line does the NPE occur? - Smutje
Post the full stacktrace - AJ.
Updated the quesiton. - Shan Solo
What is surprising is that it works sometimes: you never put anything in the puzzles array which only contains null elements.. - assylias
Have you checked puzzleIndex and the resulting puzzleWord when the program crashes? Seems that puzzles[puzzleIndex] results in null. - Smutje

4 Answers

1
votes

Do your puzzles.txt have more than 5 lines? because you declared a private String puzzles[] = new String[5]; the problems seems to happen when puzzleWord = puzzles[puzzleIndex]; is trying to put a null into puzzleWord.

say your puzzle have:

aaaa
bbbb
cccc

when you declare ur puzzles[]= new String[5];

your puzzles memory goes like:

null
null
null
null
null

After that you populate the puzzles array:

aaaa
bbbb
cccc
null
null

when the randomed index is 3 or 4, NPE occurs.

0
votes

can you check on which line null pointer exception occurs. Mostly it will occur when object is not initialized and your trying to do operation. So make sure object is initialized before using it.

0
votes

Okay, here's the EDIT. After debugging it for a while I found that puzzles array is not being set properly when you read "puzzles.txt" file. Something funky is going on here in this piece of code. Make sure the file is read correctly and puzzles array gets what is intends to.

Hopefully, it's a good starting point for you.

try{
        BufferedReader in = 
            new BufferedReader(new FileReader("puzzles.txt"));

        int count = 0;
        while (in.ready()) { //while there is another line in the input file
            game.puzzles[count] = in.readLine(); //get line of data
            count++; //Increment CWID counter
        }
        in.close(); 
    }
    catch(IOException e){
        System.out.println("Error during reading/writing");
    }

Why don't you try to debug it and see the values on puzzles and puzzleWord inside the method. That's the best way possible to see what's really going in.

-1
votes

Please check the path of your file puzzles.txt. It seems the file path is not correct. You must be getting an exception printed "Error during reading/writing". Handle it properly, if you are not able to read the file then don't proceed ahead.

Move the puzzles.txt file to correct path or provide a exact file path.