0

Here is the Deck.java file, I know for sure the error is here.

import java.util.List;
import java.util.ArrayList;

/**
 * The Deck class represents a shuffled deck of cards.
 * It provides several operations including
 *      initialize, shuffle, deal, and check if empty.
 */
public class Deck {

    /**
     * cards contains all the cards in the deck.
     */
    private List<Card> cards;

    /**
     * size is the number of not-yet-dealt cards.
     * Cards are dealt from the top (highest index) down.
     * The next card to be dealt is at size - 1.
     */
    private int size;


    /**
     * Creates a new <code>Deck</code> instance.<BR>
     * It pairs each element of ranks with each element of suits,
     * and produces one of the corresponding card.
     * @param ranks is an array containing all of the card ranks.
     * @param suits is an array containing all of the card suits.
     * @param values is an array containing all of the card point values.
     */
    public Deck(String[] ranks, String[] suits, int[] values) {
        cards = new ArrayList<Card>();
        for (int j = 1; j < ranks.length; j++) {
            for (String suitString : suits) {
                cards.add(new Card(ranks[j], suitString, values[j]));
            }
        }
        shuffle();
    }


    /**
     * Determines if this deck is empty (no undealt cards).
     * @return true if this deck is empty, false otherwise.
     */
    public boolean isEmpty() {
        return size < 0;
    }

    /**
     * Accesses the number of undealt cards in this deck.
     * @return the number of undealt cards in this deck.
     */
    public int size() {
        return size;
    }

    /**
     * Randomly permute the given collection of cards
     * and reset the size to represent the entire deck.
     */
    public void shuffle() {
        for (int k = cards.size() - 1; k >= 0; k--) {
            int howMany = k + 1;
            int start = 0;
            int randPos = (int) (Math.random() * howMany) + start;
            Card temp = cards.get(k);
            cards.set(k, cards.get(randPos));
            cards.set(randPos, temp);
        }
        size = cards.size();
    }

    /**
     * Deals a card from this deck.
     * @return the card just dealt, or null if all the cards have been
     *         previously dealt.
     */
    public Card deal() {
        size--;
        if (isEmpty()) {
            return null;
        }

        Card c = cards.get(size);
        return c;
    }

    /**
     * Generates and returns a string representation of this deck.
     * @return a string representation of this deck.
     */
    @Override
    public String toString() {
        String rtn = "size = " + size + "\nUndealt cards: \n";

        for (int k = size - 1; k >= 0; k--) {
            rtn = rtn + cards.get(k);
            if (k != 0) {
                rtn = rtn + ", ";
            }
            if ((size - k) % 2 == 0) {
                // Insert carriage returns so entire deck is visible on console.
                rtn = rtn + "\n";
            }
        }

        rtn = rtn + "\nDealt cards: \n";
        for (int k = cards.size() - 1; k >= size; k--) {
            rtn = rtn + cards.get(k);
            if (k != size) {
                rtn = rtn + ", ";
            }
            if ((k - cards.size()) % 2 == 0) {
                // Insert carriage returns so entire deck is visible on console.
                rtn = rtn + "\n";
            }
        }

        rtn = rtn + "\n";
        return rtn;
    }
}

Here is the runner code. This is where I get the error: "Exception in thread "main" java.lang.NullPointerException at DeckTester.testShuffle(DeckTester.java:137) at DeckTester.main(DeckTester.java:15)" Ill comment the line number next to the lines affected.

 * This is a class that tests the Deck class using assert statements.
 */
public class DeckTester {

    /**
     * The main method in this class checks the Deck operations for consistency
     * using assert statements.
     *  @param args is not used.
     */
   public static void main(String[] args) {
   test2CardDeck();
      test1CardDeck();

      testShuffle(); //Line 15
      System.out.println("All tests passed!");
   }


    /**
     * Create a 1-card Deck and test the Deck methods with it.
     */
   private static void test1CardDeck() {
      String[] r1 = {"ace"};
      String[] s1 = {"spades"};
      int[] v1 = {1};
      Deck d = new Deck(r1, s1, v1);
      testOneCard(d, new Card("ace", "spades", 1));
      testEmpty(d);

      d.shuffle();
      testOneCard(d, new Card("ace", "spades", 1));
      testEmpty(d);
   }

    /**
     * Create a 2-card Deck and test the Deck methods with it.
     */
   private static void test2CardDeck() {
      String[] r2 = {"ace", "2"};
      String[] s2 = {"hearts"};
      int[] v2 = {1, 2};
      Deck d = new Deck(r2, s2, v2);
      assert d.size() == 2 : "Initial size is " + d.size()
         + ". It should be 2.";
      assert !d.isEmpty() : "Initial deck is empty.";
      boolean aceIsFirst, twoIsFirst;
      Card c = d.deal();
      assert c != null : "1st card dealt is null.";
      aceIsFirst = c.matches(new Card("ace", "hearts", 1));
      twoIsFirst = c.matches(new Card("2", "hearts", 2));
      assert (aceIsFirst || twoIsFirst) : "1st card dealt is " + c
         + ".  It is not the one of the two correct cards.";
      assert d.size() == 1 : "Size after one deal is " + d.size()
         + ". It should be 1.";
      assert !d.isEmpty() : "Deck is empty after one deal.";
      c = d.deal();
      assert c != null : "2nd card dealt is null.";
      if (aceIsFirst) {
         assert c.matches(new Card("2", "hearts", 2))   : "2nd card dealt is "
            + c + ". It is not one of the two correct cards.";
      } else {
         assert c.matches(new Card("ace", "hearts", 1)) : "2nd card dealt is "
            + c + ". It is not one of the two correct cards.";
      }
      testEmpty(d);

      d.shuffle();
      c = d.deal();
      assert c != null : "1st card dealt after shuffle is null.";
      aceIsFirst = c.matches(new Card("ace", "hearts", 1));
      twoIsFirst = c.matches(new Card("2", "hearts", 2));
      assert (aceIsFirst || twoIsFirst) : "1st card dealt after shuffle is "
         + c + ".  It is not the one of the two correct cards.";
      assert d.size() == 1 : "Size is " + d.size()
         + "after shuffle and one deal. It should be 1.";
      assert !d.isEmpty() : "Deck is empty after shuffle and one deal.";
      c = d.deal();
      assert c != null : "2nd card dealt after shuffle is null.";
      if (aceIsFirst) {
         assert c.matches(new Card("2", "hearts", 2))
            : "2nd card dealt after shuffle is " + c
            + ". It is not the one of the two correct cards.";
      } else {
         assert c.matches(new Card("ace", "hearts", 1))
            : "2nd card dealt after shuffle is " + c
            + ". It is not the one of the two correct cards.";
      }
      testEmpty(d);
   }

    /**
     * Check that the given deck is empty.
     * @param d is a deck that should be empty.
     */
   private static void testEmpty(Deck d) {
      assert d.size() == 0 :  "Size for an empty deck is " + d.size()
         + ". It should be 0.";
      assert d.isEmpty() : "isEmpty is false for an empty deck.";
      Card c = d.deal();
      assert c == null : "Dealt card is " + c
         + ". It should be null for an empty deck.";
   }

    /**
     * Check that the given deck contains the given card and nothing else.
     * @param d is a deck that should contain a single card.
     * @param intended is the card that the one-card deck should contain.
     */
   private static void testOneCard(Deck d, Card intended) {
      assert d.size() == 1 : "Size is " + d.size()
         + ". It should be 1 for a 1-card deck.";
      assert !d.isEmpty() : "isEmpty true for a 1-card deck.";
      Card c = d.deal();
      assert c != null : "1st dealt card is null for a 1-card deck.";
      assert c.matches(intended) : "1st card dealt for a 1-card deck is "
         + c + ". It should be " + intended + ".";
   }

    /**
     * Check that two decks constructed in succession aren't the same.
     */
   private static void testShuffle() {
      String[] r = {"ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king"};
      String[] s = {"spades", "hearts", "diamonds", "clubs"};
      int[] v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
      Deck d1 = new Deck(r, s, v);
      Deck d2 = new Deck(r, s, v);
      assert d1 != d2 : "Decks d1 and d2 are the same physical object.";
      assert d1.size() == d2.size() : "Deck d1 size of " + d1.size()
         + " does not match deck d2 size of " + d2.size() + ".";

      boolean allMatch = true;
      while (!d1.isEmpty()) {
         Card c1 = d1.deal();
         Card c2 = d2.deal();
         if (c1.matches(c2)) { //Line 137
            allMatch = false;
         }
      }
      assert !allMatch : "The sequence of cards in d1 and d2 are identical.";
   }
}``` 


  • Please don´t post your entire codebase - just the least amount of code that is needed to reproduce that problem. Anyway for an NPE you should definitly use your debugger, which can give you the answer even faster. – MakePeaceGreatAgain Jan 29 '20 at 21:01
  • `return size < 0;`, that should most likely be `return size == 0;`. The deck is empty when there are no cards anymore, not when the deck reach inside the table to show it has `-1` card. – Progman Jan 29 '20 at 21:02
  • The problem is with your `isEmpty()` method. It's `return size < 0`, which means that a deck of size zero is not considered to be empty. Change that to `return size <= 0`. – Jordan Jan 29 '20 at 21:03
  • `c1.matches(c2)` — `c1` is probably `null`. So you need to figure out why it is `null`, and how you should either avoid it or handle it. – MC Emperor Jan 29 '20 at 21:08
  • There is no code for the Card class. But returning null from Deck.deal() is a really bad style. Why don't you return a Card object representing an empty hand, instead null? – Victor Polo De Gyves Montero Jan 29 '20 at 21:11

0 Answers0