0

So I know where the the Null Point exception is happening (Eclipse is helpful that way)

I have the following classes:

/**
 * Card class - a typical playing card.
 * 
 * @author Colleen 
 * @version 2010.03.09
 */
public class Card
{
    private String suit;
    private int value;
    private String description;
    private static final String[] SUITS = {"Hearts", "Diamonds", "Spades", "Clubs"};
    private static final String[] DESCRIPTIONS = {
            "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
            "Jack", "Queen", "King"};

    public Card(){
        suit = "Spades";
        value = 0;
        description = "Joker";
    }

    public Card(String description, String suit){
        setSuit(suit);
        setValue(description);
        setDescription(description);
    }

    /**
     * @return the suit
     */
    public String getSuit() {
        return suit;
    }

    /**
     * @param suit the suit to set
     */
     public void setSuit(String suit) {
        int count = 0;
        boolean check = false;
        while(count < SUITS.length){
            if(suit == SUITS[count]){
                check = true;
            }
            count ++;
        }
        if(check == true){
            this.suit = suit;
        } else {
            suit = "Spades";
        }
     }

    /**
     * @return the value
     */
    public int getValue() {
        return value;
    }

    /**
    * @param value the value to set
    */
    public void setValue(String description) {
        if(description == "Two"){
            value = 2;
        } else if(description == "Three"){
            value = 3;
        } else if(description == "Four"){
            value = 4;
        } else if(description == "Five"){
            value = 5;
        } else if(description == "Six"){
            value = 6;
        } else if(description == "Sever"){
            value = 7;
        } else if(description == "Eight"){
            value = 8;
        }else if(description == "Nine"){
            value = 9;
        } else if(description == "Ten" || description == "Jack" || description == "Queen" ||  description == "King"){
            value = 10;
        } else if(description == "Ace"){
            value = 11;
        } else {
            description = "Joker";
            value = 0;
        }
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        int count = 0;
        boolean check = false;
        while(count < DESCRIPTIONS.length){
            if(description == DESCRIPTIONS[count]){
                check = true;
            } 
            count ++;
        }
        if(check == true){
            this.description = description;
        } else {
            description = "Joker";
        }
     }
 }

Next Class:

 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Random;

 /**
  * Deck of cards.
  * 
  * @author Bullwinkle J. Moose
  * @version (June 11, 2012)
  */
 public class Deck
 {
     private ArrayList<Card> deck;
     private static final int TIMES_TO_SHUFFLE = 5;
     private static final String[] SUITS = {"Hearts", "Diamonds", "Spades", "Clubs"};
     private static final String[] DESCRIPTIONS = {
             "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten",
             "Jack", "Queen", "King"};

     /**
      * Constructor for objects of class Deck
      * Creates a new container for Card objects
      */
     public Deck()
     {
         deck = new ArrayList<Card>();
     }

     /**
      * Add a card to the deck.
      * @param Card to be added
      */
     public void addCard(Card cardToAdd)
     {
         deck.add(cardToAdd);
     }

     /**
      * Take the first card from the deck.
      * @return Card or null
      */
     public Card takeCard()
     {
         if(deck.isEmpty()) {
             return null; 
         }
         else {  // get the top card
            return deck.remove(0);
         }
     }

     public int deckSize(){
        int deckSize = deck.size();
        return deckSize;
     }

     /**
      * Show the contents of the deck.
      */
     public void showDeck(){
         for(Card eachCard : deck) {
             System.out.println(eachCard.getDescription() + " of " + eachCard.getSuit());
         }
     }

     /**
      * Method that switch the index position in the deck of the two cards.
      */
     public void swap(int firstNumber, int secondNumber){        
         if (firstNumber >= 0 && firstNumber < deck.size()) {
             if (secondNumber >= 0 && secondNumber < deck.size()) {
                 Collections.swap(deck,firstNumber,secondNumber);
             } else {
                 System.out.println("Invalid index entry ...");
             }
         } else {
             System.out.println("Invalid index entry ...");
         }
     }

     /**
     * Method that randomly selects two numbers between 0 (inclusive) and the size of the deck (exclusive),
      * and passes those numbers as parameters to swap(). This must be within a loop, so that the 
      * swap() method is called TIMES_TO_SHUFFLE times.
      */    
     public void shuffle(){
         Random randomGenerator = new Random();
         int counter = 0;
         int firstNumber, secondNumber = 0;
         while (counter++ < TIMES_TO_SHUFFLE){
             firstNumber = randomGenerator.nextInt(deck.size());
             secondNumber = randomGenerator.nextInt(deck.size());
             swap(firstNumber,secondNumber);
        }    
     }

     public void loadDeck() {
         for (int suit = 0; suit < SUITS.length; suit++) {
             for (int description = 0; description < DESCRIPTIONS.length; description++) {
                 Card card = new Card(DESCRIPTIONS[description], SUITS[suit]);
                 deck.add(card);
             }
         }
     }
 }

And final class:

 import java.util.ArrayList;

 /**
  * @author jaimefenton
  *
  */
 public class Game {

     private Deck aDeck;
     private InputReader reader;
     private ArrayList<Card> hand;
     private String commandChoice;

     /**
      * Method to run the game. 
      * First while loop will run until the player chooses "no" for another round.
      * Second while look will keep running until the player chooses to stand, has 21 or busts.
      * the last while loop is to make sure that the player chooses either "Hit" or "Stand". If neither is choosen, it will keep requesting it.
      */
     public void Play(){
        int playerPoints = 0;
        int totalRounds = 0;

        intro();
        aDeck = new Deck();
        aDeck.loadDeck();
        while(anotherRound() == false){
            dealCard();
            dealCard();
            showHand();
            report();
            while(isStanding() == false){
                if(hasBlackjack() == true){
                        hasBlackjack();
                System.out.println("BlackJack!");
                }else if (isBusted() == true){
                    isBusted();
                    System.out.println("You have Busted!");
                }else {
                    dealCard();
                    report();
                    System.out.println("Your choice: Hit or Stand? ");
                    String inputChoice = reader.getInput();
                    while(inputChoice != "Hit" || inputChoice != "Stand"){
                        System.out.println("That is not a correct choice.");
                    }
                    isStanding();
                }

         } totalRounds ++;
        }
        System.out.println("Player Points: " + playerPoints);
         System.out.println("Total Rounds: " + totalRounds);
     }

     /**
      * intro message to player
      */
     public void intro(){
        System.out.println("Welcome to 1451 Blackjack!");
        System.out.println("You will start with two cards.");
        System.out.println("You will be prompted to 'hit' or 'stand' 'hit' means you want another card, 'stand' not.");
        System.out.println("");
        System.out.println("You are trying to get Blackjack with exactly 21 points.");

     }
     /**
      * deals a card to the player
      */
     public void dealCard(){
        int deckSize = aDeck.deckSize();
        if(deckSize == 0){
            System.out.println("Time for some more cards");
            aDeck.loadDeck();
            aDeck.shuffle();
         } else {
         Card tempCard = aDeck.takeCard();
         hand.add(tempCard);
         }
     }

     /**
      * calculates the hand value of the player
      * @return handValue
      */
     public int getHandValue(){
        int handValue = 0;
        for(Card eachCard : hand) {
             int tempValue = eachCard.getValue();
             handValue = handValue + tempValue;
         }
        return handValue;
     }

     /**
      * displays contents of players hand
      */
    public void showHand(){
        System.out.println("Your cards:"); 
         for(Card eachCard : hand) {
                 System.out.println(eachCard.getDescription()+ 
                                 " of " + eachCard.getSuit());
             }
     }

     /**
      * displays contents of hand
      * @return true or false
      */
    public boolean hasBlackjack(){
        int bjValue = getHandValue(); 
        if(bjValue == 21){
            return true;
        } else {
            return false;
        }
     }

     /**
      * is hand value above 21?
      */

     public boolean isBusted(){
        int bjValue = getHandValue(); 
        if(bjValue > 21){
            return true;
         } else {
            return false;
         }
     }

     /**
      * has player chosen to "stand"?
      * @return true or false
      */
     public boolean isStanding(){
        if(commandChoice == "Hit"){
            return true;
        } else {
            return false;
        }
     }

     public boolean anotherRound(){
        if(commandChoice == "no"){
            return true;
        } else {
            return false;
        }
     }

     /**
      * final report of points
      */
     public void report(){
        showHand();
        System.out.println("Hand Value: " + getHandValue());
        System.out.println(""); 
     }
 }

I've not included the InputReader as it's not important for this question.

I'm using a driver class that's tested both Deck and Card thoroughly and all returned positive results. Bear in mind, I'm aware the play() is probably messed up, but until I resolve the methods it's calling, I won't be able to fix it.

The first error I hit is with "public void dealCard()". It's pulling a null point exception error relating to "if(deckSize == 0)". I can't tell why it's not working, because when I run it directly from deck, it works perfectly. Once that issues resolved, I'm fairly certain I can work out the rest.

Thanks for checking this out.

jwodder
  • 54,758
  • 12
  • 108
  • 124
Wulf
  • 19
  • 1
  • 6
  • 1
    `if(deckSize == 0)` can't throw an NPE so you'll have to check the line number again for us. (It could if `deckSize` was a null Integer being unboxed but it's not. `deckSize` is int.) – Radiodef Oct 14 '14 at 02:19
  • That line can **NOT** throw a NPE. It's impossible. – jahroy Oct 14 '14 at 02:26
  • Where do you initialize `hand`? I can't find any code that leads me to believe that `hand` is anything other than null... Sounds like a recipe for a NPE. – jahroy Oct 14 '14 at 02:34

2 Answers2

1

I am pretty sure hand is null. reader may also be null. I don't see them assigned anything (an expression like hand = or reader =) and they are private.

This is why you should either initialize your member variables or use constructors unless there is some reason you can't:

public class Game {

    private Deck aDeck = new Deck();
    private InputReader reader = /* ??? */;
    private ArrayList<Card> hand = new ArrayList<Card>();

    private String commandChoice;

    /*
     */

In general the lifetime of an object's members should be the same as the object, in other words you should always be instantiating the members once at creation. Doing it in some method like Play that may be invoked multiple times increases the likelihood the object will end up in some invalid state. (Or in this case, begins in an invalid state.)

I also noticed you are doing this:

String inputChoice = reader.getInput();
while(inputChoice != "Hit" || inputChoice != "Stand"){

And this is almost certainly incorrect.

Community
  • 1
  • 1
Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • Oh man, that was an amateur mistake! I did initialize the Deck, but not the Hand. Thanks for pointing that out! Yeah, I am using the reader incorrectly, I think I should be able to fix that, the fact that the code is actually giving me an answer along the lines that I would expect is promising. – Wulf Oct 14 '14 at 03:26
0

You never initialize hand, which is a member variable of your Game class.

ArrayLists must be initialized before you can invoke their methods.

The following line from dealCard() will always throw a NullPointerException:

  hand.add(tempCard);

Modify the line where hand is declared to look like this:

  private ArrayList<Card> hand = new ArrayList<Card>();

As Radiodef mentions, it would be even better to use a standard constructor.

jahroy
  • 22,322
  • 9
  • 59
  • 108
  • I would use a standard constructor however assignment guidelines requested not to use one. Thanks for the thought though :) – Wulf Oct 14 '14 at 03:30