I have just implemented a loop to populate a player’s hand (a queue) with cards (from a stack), but I am encountering a NullPointerException at LinkedStack.pop(). I haven’t altered the provided LinkedStack code and I have checked that the deck is populated with elements, so I cannot immediately see where the NullPointerException is coming from. Below are my code segments and error output. If you require any other code, just let me know.
(SimpleUnoGame.java)
45 LinkedQueue<UnoCard> cardHand = new LinkedQueue<UnoCard>();
46 //draw cards for player
47 for(int j = 0; j < INITIAL_CARDS; j++) {
48 cardHand.enqueue(faceDownCards.pop());
49 }
50 newPlayer.setCards(cardHand);
51 playerCollection.enqueue(newPlayer);
(LinkedStack.pop())
43 T result = top.getElement();
44 top = top.getNext();
45 count--;
46 return result;
(Exception)
Exception in thread "main" java.lang.NullPointerException
at LinkedStack.pop(LinkedStack.java:43)
at SimpleUnoGame.<init>(SimpleUnoGame.java:48)
Here is the complete code, as requested:
(LinkedStack.java)
/**
* Represents a linked implementation of a stack
*/
public class LinkedStack<T> implements StackADT<T> {
//indicates number of elements stored
private int count;
//pointer to top of stack
private LinearNode<T> top;
/**
* Creates an empty stack
*/
public LinkedStack() {
count = 0;
top = null;
}
/**
* Adds the specified element to the top of this stack
* @param element element to be pushed on stack
*/
public void push(T element) {
LinearNode<T> temp = new LinearNode<T>(element);
temp.setNext(top);
top = temp;
count++;
}
/**
* Removes the element at the top of this stack and returns a reference to it
* Throws an EmptyCollectionException if the stack is empty
* @return T element from top of stack
* @throws EmptyCollectionException on pop from empty stack
*/
public T pop() throws EmptyCollectionException {
if (isEmpty()) {
throw new EmptyCollectionException("Stack");
}
T result = top.getElement();
top = top.getNext();
count--;
return result;
}
/**
* Returns a reference to the element at the top of this stack
* Throws an EmptyCollectionException if the stack is empty
* (the element is not removed from the stack)
* @return T element on top of stack
* @throws EmptyCollectionException on peek at empty stack
*/
public T peek() throws EmptyCollectionException {
if (isEmpty()) {
throw new EmptyCollectionException("Stack");
}
return top.getElement();
}
/**
* Returns true if this stack is empty and false otherwise
* @return boolean true if stack is empty
*/
public boolean isEmpty() {
if (count == 0) {
return true;
} else {
return false;
}
}
/**
* Returns the number of elements in this stack
* @return int number of elements in this stack
*/
public int size() {
return count;
}
/**
* Returns a string representation of this stack
* @return String representation of this stack
*/
public String toString() {
String output = "";
T result;
for (int i = 0; i < this.size(); i++) {
result = top.getElement();
output = output + result;
top = top.getNext();
}
return output;
}
}
(SimpleUnoGame.java)
public class SimpleUnoGame {
private final int INITIAL_CARDS = 7;
private LinkedQueue<UnoPlayer> playerCollection = new LinkedQueue<UnoPlayer>();
private LinkedStack<UnoCard> faceUpCards = new LinkedStack<UnoCard>();
private LinkedStack<UnoCard> faceDownCards = new LinkedStack<UnoCard>();
private int cardCount = 0;
public SimpleUnoGame(int numberOfPlayers, int highestRank) {
//create cards and add to faceDownCards
for(int i = 1; i <= highestRank; i++) {
for(int j = 0; j <= 1; j++) {
//blue cards
UnoCard cardB = new UnoCard('B', i);
faceDownCards.push(cardB);
//green cards
UnoCard cardG = new UnoCard('G', i);
faceDownCards.push(cardG);
//red cards
UnoCard cardR = new UnoCard('R', i);
faceDownCards.push(cardR);
//yellow cards
UnoCard cardY = new UnoCard('Y', i);
faceDownCards.push(cardY);
}
}
System.out.println("Cards: " + faceDownCards.toString()); //debug check
//shuffle cards randomly
shuffleCards(faceDownCards);
System.out.println("Cards: " + faceDownCards.toString()); //debug check
//create players and add to playerCollection
for (int i = 0; i < numberOfPlayers; i++) {
//ask for name
String name = "Taylor";
UnoPlayer newPlayer = new UnoPlayer(name);
LinkedQueue<UnoCard> cardHand = new LinkedQueue<UnoCard>();
//draw cards for player
for(int j = 0; j < INITIAL_CARDS; j++) {
cardHand.enqueue(faceDownCards.pop()); //PROBLEM OCCURS HERE
}
newPlayer.setCards(cardHand);
playerCollection.enqueue(newPlayer);
}
System.out.println("There are " + numberOfPlayers + " players in the game.");
System.out.println(playerCollection.toString()); //debug check
//draw one face up card
faceUpCards.push(faceDownCards.pop());
}
Your top variable is null. How do you initialize it?
From your code sample it seems that you set top to null upon construction of your object and then only set it to something non-null when you push an item.
If that’s the case, then it seems that you have not pushed something into the LinkedStack.
Although i must admit i have trouble figuring out the exact problem since you have only supplied bits of your code and it sort of doesn’t make much sense.
EDIT
The method toString() modifies the top field which is supposed to hold the head of your queue. Calling the toString method should have no side-effects. Change it to this :
I don’t know who wrote this class for you but it’s a rookie mistake. By calling toString() you are effectively emptying your queue.