I'm making a game with cards, characters cards.
I first create the cards chosen by the user, then add them to a List
, shuffle it and then display 'em one by one, with their players name (chosen in a previous activity by the user).
The fact is, when I try to get the a Card class from the List, and invoking its methods getPlayer() & getCharacter (which return the player's name and the characters' name of the specific card) I get the nullPointer Exception.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.leonardo.lupusintabula.characters.Card.getCharacter()' on a null object reference
randomButton.setText(characters.get(0).getCharacter() + " / " + characters.get(0).getPlayer());
The onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_assignment);
//Retrieving
...
//Done retrieving
initializeVariables();
createCharacters();
run();
}
As the issue is probably in characters, I'm listing you all the code it's in:
// Where the characters are stored
private ArrayList<Card> characters;
public void initDeck() {
addCharacter(demoniac, demoniacAmount, characters);
addCharacter(guard, guardAmount, characters);
addCharacter(medium, mediumAmount, characters);
addCharacter(mythomaniac, mythomaniacAmount, characters);
addCharacter(owl, owlAmount, characters);
addCharacter(werehamster, werehamsterAmount, characters);
addCharacter(getVillagerBundle(), villagerAmount, characters);
addCharacter(masonOne, 1, characters);
addCharacter(masonTwo, 1, characters);
}
public void addCharacter(Card card, int amount, List<Card> cards) {
if (amount < 0) {
throw new IllegalArgumentException("Must add a non-negative number of characters for " + card.getCharacter() );
}
for (int i = 0; i < amount; i++) {
cards.add(card);
}
}
//Pick a random one and display it
public void pick(View view){
if(characters != null) {
if (i < characters.size()) {
randomButton.setText(characters.get(i).getCharacter() + " / " + characters.get(i).getPlayer());
i++;
} else {
randomButton.setText(R.string.play);
}
}
}
void run() {
// initialize the characters
initDeck();
// shuffle them
Collections.shuffle(characters);
//Display the 1st card
if(characters != null) {
randomButton.setText(characters.get(0).getCharacter() + " / " + characters.get(0).getPlayer());
}
}
private void initializeVariables() {
...
...
characters = new ArrayList<Card>();
}
}
What am I doing wrong? If you need other part of the code feel free to ask, I'll provide it to you as soon as possible!
This may drive you crazy but it's the only way I found to achieve the creation of the characters (each character extends the Card class!):
public void createCharacters() {
if (demoniacAmount != 0) {
demoniac = new Demoniac(nameList.get(listIndex));
listIndex++;
} else if (guardAmount != 0) {
guard = new Guard(nameList.get(listIndex));
listIndex++;
} else if (mediumAmount != 0) {
medium = new Medium(nameList.get(listIndex));
listIndex++;
} else if (mythomaniacAmount != 0) {
mythomaniac = new Mythomaniac(nameList.get(listIndex));
listIndex++;
} else if (owlAmount != 0) {
owl = new Owl(nameList.get(listIndex));
listIndex++;
} else if (werehamsterAmount != 0) {
werehamster = new Werehamster(nameList.get(listIndex));
listIndex++;
} else if (masonsAmount != 0) {
masonOne = new Masons(nameList.get(listIndex));
masonTwo = new Masons(nameList.get(listIndex));
listIndex += masonsAmount;
} else if (villagerAmount > 5) {
villagerSix = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerSix);
if (villagerAmount > 6) {
villagerSeven = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerSeven);
if (villagerAmount > 7) {
villagerEight = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerEight);
if (villagerAmount > 8) {
villagerNine = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerNine);
if (villagerAmount > 9) {
villagerTen = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerTen);
if (villagerAmount > 10) {
villagerEleven = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerEleven);
if (villagerAmount > 11) {
villagerTwelve = new Villager(nameList.get(listIndex));
villagerBundle.add(villagerTwelve);
Toast.makeText(RandomAssignment.this, "works", Toast.LENGTH_SHORT).show();
}
}
}
}
}
}
}
listIndex += villagerAmount;
}
From my other answer, from which you took my code. The initDeck
method actually reads like this
public void initDeck() {
if (characters == null)
characters = new ArrayList<String>();
// addCharacter...
That will at least avoid a null pointer on the list...
You need to add more code to your question, but the problem starts in this block
addCharacter(demoniac, demoniacAmount, characters);
addCharacter(guard, guardAmount, characters);
addCharacter(medium, mediumAmount, characters);
addCharacter(mythomaniac, mythomaniacAmount, characters);
addCharacter(owl, owlAmount, characters);
addCharacter(werehamster, werehamsterAmount, characters);
addCharacter(getVillagerBundle(), villagerAmount, characters);
addCharacter(masonOne, 1, characters);
addCharacter(masonTwo, 1, characters);
which (roughly) calls this code
public void addCharacter(Card card, int amount, List<Card> cards) {
for (int i = 0; i < amount; i++) {
cards.add(card);
}
}
The issue is that somewhere ANY of these variables are null and they are being added to the list as such
demoniac
guard
medium
mythomaniac
owl
werehamster
getVillagerBundle()
masonOne
masonTwo
You could either fix that by assigning all those variables to a new Card()
, or avoid the problem like so
public void addCharacter(Card card, int amount, List<Card> cards) {
for (int i = 0; i < amount; i++) {
if (card != null) {
cards.add(card);
} else {
Log.e("addCharacter", "Hey! Are you sure you meant to add a null card?");
}
}
}
Now what you have shown more of the code, the error starts here
if (demoniacAmount != 0) {
demoniac = new Demoniac(nameList.get(listIndex));
listIndex++;
} else if (guardAmount != 0) {
guard = new Guard(nameList.get(listIndex));
listIndex++;
}
What if demoniacAmount
and guardAmount
are both not zero, hmm? Only that first if condition will be entered. And guard
will end up being null because it was never initialized. It makes no sense to do an else-if
for completely different variables!
Properly perform your if-checking like so for all those conditions. (And I will leave the messy code as much as it bothers me)
if (demoniacAmount != 0) {
demoniac = new Demoniac(nameList.get(listIndex));
listIndex++;
}
if (guardAmount != 0) {
guard = new Guard(nameList.get(listIndex));
listIndex++;
}