Java Issue calculating value of player hands in BlackJack program

2.8k views Asked by At

I want to make a BlackJack game in Java. I'm using arrays to represent the cards. I'm having a problem of getting the card value and using the card values each player has to calculate the hand of each player. I have four classes, Card, Player, Dealer, and BlackJackGame - the driver. I'll post Card with its relevant Value method, Player, and BlackJackGame as dealer is pretty identical to Player.

// Card.Java

public class Card
{
    private String suit, rank; 
    private int value;


    public Card(String suit, String rank)
    {
        this.suit = suit;
        this.rank = rank;
    }

    public String getRank()
    {
        return rank;
    }

    public int Value()
    {
        if(rank.equals("2"))
        {
            value=2;
        }
        else if(rank.equals("3"))
        {
            value=3;
        }
        else if(rank.equals("4"))
        {
            value=4;
        }
        else if(rank.equals("5"))
        {
            value=5;
        }
        else if(rank.equals("6"))
        {
            value=6;
        }
        else if(rank.equals("7"))
        {
            value=7;
        }
        else if(rank.equals("8"))
        {
            value=8;
        }
        else if(rank.equals("9"))
        {
            value=9;
        }
        else if(rank.equals("10"))
        {
            value=10;
        }
        else if(rank.equals("A"))
        {
            value=11;
        }
        else if(rank.equals("Q"))
        {
            value=10;
        }
        else if(rank.equals("J"))
        {
            value=10;
        }
        else if(rank.equals("K"))
        {
            value=10;
        }

        return value;
    }



    public String toString()
    {
        return(rank + " of " + suit);
    }

}

// Player.java

//Player.java

public class Player
{
    private int cValue; // [Card Value] I use this in a method to equal what deck[int] produces and try to use in the getValue method to no avail
    private int cCount; //Card count used to count how many 'cards' added
    Card[] deck= new Card[52]; // 52 card objects
    private int sum; A temporary int I add the cValues into and assign the value to cValue and return it

    public Player()
    {
        cCount=0;

    }

    public void addCard(Card a) //Everytime addCard is executed so I know how many cards are drawn at this point in the program everyone( 3 players and a dealer) has two cards
    {
        deck[cCount] = a;
        cCount++;

    }

    public int getcCount()  //Get the card count from the void method
    {
        return cCount;
    }

    public Card getCard(int a) //Return the deck integer each player has
    {
        return deck[a];
    }

    public int getCardValue(int a) // This works and it produces the value of the card I give the int of the method too however if I use more than two of these in succession, I get a null pointer exception, can't figure it out.  
    {
        cValue = deck[a].Value();
        return cValue;
    }

   public void getValue(int a) //The method I can't get to work, trying to calculate the hand of the player( 
   {
        for(int i =0; i<deck.length; i++)
        {
            sum += cValue;
        }


   }

   public int getValue() // I want to make this the method where the values are summed and return but for some reason no matter what I do I get 0 returned, tried everything.. I really need help with this method.
   {
        cValue = sum;
        return cValue;
   }



}

//BlackJackGame.java

public class BlackJackGame
{



    public static void main(String []   args)
    {
        Card[] deck = new Card[52];
        Player[] player = new Player[3];
        int loopcount=0;

        String[] suit = {"Hearts", "Clubs", "Spades", "Diamonds"};
        String[] rank = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};

        for(int i=0; i<13; i++)
        {
            for(int x=0; x<4;x++)
            {
                deck[loopcount] = new Card(suit[x], rank[i]);
                loopcount++;
            }
        }

        System.out.println("Shuffling...");

        for(int i=0; i< deck.length; i++) //Shuffle
        {
            int count= (int)(Math.random()* deck.length);
            deck[i] = deck[count];

        }

        Player player1 = new Player();
        Player player2 = new Player();
        Player player3 = new Player();

        System.out.println("Welcome to our BlackJackGame!");

        System.out.println("Welcome Dealer!");

        Dealer dealer = new Dealer();

        System.out.println("Let's deal the cards!");

        player1.addCard(deck[0]);

        player2.addCard(deck[1]);

        player3.addCard(deck[2]);

    //  System.out.println("Player 1 has: " +deck[0]);

    //  System.out.println("Player 2 has: " +deck[1]);

    //  System.out.println("Player 3 has : " +deck[2]);

    System.out.println("And now the Dealer gets his card...");

        dealer.addCard(deck[3]);

    //  System.out.println("The Dealer has: " +deck[3]);

    System.out.println("Now we get our second cards!");

    System.out.println("Okay Dealer, deal out the cards!");

        player1.addCard(deck[4]);

        player2.addCard(deck[5]);

        player3.addCard(deck[6]);

        dealer.addCard(deck[7]);

        System.out.println("These are the cards player1 has: " +deck[0]+ " "+deck[4]);

        System.out.println("These are the cards player2 has: " +deck[1]+ " "+deck[5]);

        System.out.println("These are the cards player3 has: " +deck[2]+ " "+deck[6]);

        int p1 = player1.getCardValue(0); 
        int p2 = player2.getCardValue(1);
        int p3 = player3.getCardValue(2); // This points to null, why?!

        System.out.println(p1);
        System.out.println(p2);

Output

Shuffling...
*Some print lines of stuff I wrote*
These are the cards this player has: ...  ... 
Exception in thread "main" java.lang.NullPointerException
at Player.getCardValue(Player:java:39)
at BlackJackGame.main(BlackJackGame.java:85)
1

There are 1 answers

4
Jonny Henly On BEST ANSWER

You've only added two cards to player3's deck[], so when you call public int getCardValue(2) it goes to the 3rd index of player3's deck, which is null.

    Player player3 = new Player();
    ...
    player3.addCard(deck[2]);
    // deck[0]
    ...
    player3.addCard(deck[6]);
    // deck[1]
    ...
    int p3 = player3.getCardValue(2);
    // get value at deck[2]

    // this goes to ->
    public int getCardValue(int a)  
    {
        // try to access deck[2], but deck only has 
        // 2 valid entries deck[0] and deck[1]
        cValue = deck[a].Value();
        return cValue;
    }

Other Things...

Instead of each player having an array called deck perhaps rename it to hand and use an ArrayList instead of an array, the ArrayList would allow you to add elements dynamically.

I would use a switch statement in your Card.Value() method. Like so:

public int Value()
{
    switch(rank) {
    case "A":
        return 11;
    case "K":
    case "Q":
    case "J":
        return 10;
    default:
        return Integer.parseInt(rank);
}

Your shuffling algorithm is almost correct.

    for(int i=0; i< deck.length; i++) //Shuffle
    {
        // this line chooses a random card in the deck
        int count= (int)(Math.random()* deck.length); 
        // this line sets the card at index 'i' to the randomly chosen card
        deck[i] = deck[count];
        // however your creating multiple instance of one card in the deck
        // instead of switching the cards around, this will lead to your deck
        // having more than one of the same card.
    }

It should look like this:

    for(int i=0; i< deck.length; i++) //Shuffle
    {
        // create a temporary card to hold the value of the card to switch
        Card tmp = deck[i];
        // now choose a random card in the deck
        int count= (int)(Math.random()* deck.length); 
        // now set the card at index 'i' to the randomly chosen card
        deck[i] = deck[count];
        // and set the randomly chosen card to deck[i]
        deck[count] = tmp;
    }

What could I do for the getValue method to calculate the hand? Using the array you have with cCount you could have a method to calculate the hand total:

  public int calcHandTotal() {
      int total = 0;

      for(int i = 0; i < cCount; i++) {
          total += deck[i].Value();
      }

      return total;
  }