0

I've been trying to search for the bug, but I couldn't find it. Already spent an hour trying to resolve what's wrong. The error begins when the code enters the isPlayerSet method while (!player.isPlayerSet()) {. I already set the used properties to "" but I am still getting this nullpointerexeption error. Please understand that I am fairly new in programming, especially in Java.

Here's the main class

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        String playerName = "";
        int chosenPokemon = 0;
        boolean isANumber = false;;
        Player player;

        /*
         * Initialize Players
         */
        Player[] players = new Player[2];

        for (int counter = 0; counter < players.length; counter++) {
            player = new Player();
        }

        /*
         * Get details of trainers
         */
        for (int counter = 0; counter <= players.length-1; counter++) {
            player = players[counter];
            while (!player.isPlayerSet()) {
                /*
                 * Input player name
                 */
                if(player.getPlayerName() == "") {
                    System.out.println("Enter a valid name for Player " + (counter+1) + ":");
                    player.setPlayerName(playerName);
                }
                /*
                 * Choose Pokemon
                 */
                if(player.getChosenPokemon() == ""){
                    System.out.println("Choose a starting pokemon for Player " + (counter+1) + ":");
                    System.out.println("[1] Charmander");
                    System.out.println("[2] Bulbasaur");
                    System.out.println("[3] Squirtle");

                    do {
                        if(!scanner.hasNextInt()) 
                        {
                            System.out.println("Input must be a valid integer. Try Again.");
                            scanner.next();
                        }
                        else if(!(chosenPokemon >= 1) && !(chosenPokemon <= 3))
                        {
                            System.out.println("Input must be a number from 1-3. Try Again.");
                            scanner.next();
                        }
                        else {
                            chosenPokemon = scanner.nextInt();
                            isANumber = true;
                        }
                    } while(!isANumber);
                    player.setChosenPokemon(chosenPokemon);
                }
            } // End of while loop
        } // End of for loop
    }
}

And here's the player class

public class Player {
    Scanner scanner = new Scanner(System.in);

    private String playerName = "";
    private String chosenPokemon = "";

    public String getPlayerName() {
        return this.playerName;
    }

    public void setPlayerName(String playerName) {
        do {
            playerName = scanner.nextLine();
            if(!isAlpha(playerName)) {
                System.out.println("Invalid input. Try again");
            }

            if(playerName.isEmpty()) {
                System.out.println("Player name cannot be blank! Try again");
            }
        } while(!isAlpha(playerName) || playerName.isEmpty()); 

        this.playerName = playerName;
        System.out.println("Welcome " + this.playerName);
    }

    public String getChosenPokemon() {
        return chosenPokemon;
    }

    public void setChosenPokemon(int chosenPokemon) {
        if(chosenPokemon == 1) {
            this.chosenPokemon = "Charmander";
        } else if(chosenPokemon == 2) {
            this.chosenPokemon = "Bulbasaur";
        } else {
            this.chosenPokemon = "Squirtle";
        }
    }

    public boolean isPlayerSet() {
        if (this.playerName.isEmpty() && this.chosenPokemon.isEmpty()) {
            return false;
        }

        return true;
    }

    public static boolean isAlpha(String name) {
        char[] chars = name.toCharArray();

        for (char c : chars) {
            if (!Character.isLetter(c)) {
                return false;
            }
        }

        return true;
    }
}

I also have another question, is it advisable to replace players[counter] with Player player?

Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
Wax
  • 323
  • 2
  • 19
  • what is your intention to add "Player player" instead "players[counter]" ? – Supun Wijerathne Jul 17 '16 at 07:41
  • I declared a player variable with Player class as it's object data type. I wanted to place it in a variable. So instead of typing player[counter].someMethod, I'll just do player.someMethod. If that makes sense. I was wondering if it affects the performance of the program. I'm trying to learn how to simplify my code. – Wax Jul 17 '16 at 07:44
  • then what is the intention of array "players" ? – Supun Wijerathne Jul 17 '16 at 07:47
  • Its very hard to answer your question without knowing what you are trying to do? :) – Supun Wijerathne Jul 17 '16 at 07:59
  • array players is where I store 2 players, who are suppose to battle. – Wax Jul 17 '16 at 08:35

4 Answers4

3

You are creating new Player objects here:

for (int counter = 0; counter < players.length; counter++) {
  player = new Player();
}

But: you are not storing those players in the array that you defined above. Thus: the array elements stay at its initial value - meaning that all players in the player array ... are null.

So your loop should say

players[counter] = new Player();

And of course, you really want to read this here.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Ohh man, I declared a variable called `Player player;` to replace all the `player[counter]`. And it was working fine, maybe I pressed some key that created the bug by messing with that line of code. Anyway, is it advisable to put `player[counter]` inside the `Player player` variable? Thanks! – Wax Jul 17 '16 at 07:15
  • Sorry about that, I focused too much on the error message instead of scanning my code. – Wax Jul 17 '16 at 07:40
  • One comment there: try to avoid that. A) dont write a lot of code, to then compile and run it. Instead, try to compile/run as soon as you pulled together something "meaningful". B) When changing a running program, better create a complete new file; so you can go back and check the changes you made; if things are "broken" ... "all of a sudden". – GhostCat Jul 17 '16 at 11:01
2

You're clobbering the same variable within this loop.

for (int counter = 0; counter < players.length; counter++) {
    player = new Player();
}

Option 1:

   for (int counter = 0; counter < players.length; counter++) {
        players[counter] = new Player();
    }

Option 2 (Slightly more concise and elegant):

for (Player p: players) p = new Player();
Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
Mursaleen Ahmad
  • 313
  • 2
  • 10
2

In the loop

for (int counter = 0; counter < players.length; counter++) {
    player = new Player();
}

You initialize the local variable player, so in while (!player.isPlayerSet()) player is null. You need to initialize the instance in the players array

for (int counter = 0; counter < players.length; counter++) {
    players[counter] = new Player();
}
Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
Guy
  • 46,488
  • 10
  • 44
  • 88
1

This

for (int counter = 0; counter < players.length; counter++) {
  player = new Player();
}

should be this.

for (int counter = 0; counter < players.length; counter++) {
  players[counter] = new Player();
}
Supun Wijerathne
  • 11,964
  • 10
  • 61
  • 87
  • The idea the is that you do more than post "this is the working code". You always explain **why** your answer will work. – GhostCat Jul 17 '16 at 11:00
  • @Jägermeister 100% agree with you. And in this case, more than not knowing the logic(pretty straight forward), the reason for wrong was just a little carelessness (confusing between player and players). So the answer should probably be good enough to find out what went wrong. :) – Supun Wijerathne Jul 17 '16 at 11:18