Search code examples
javapokernosuchelementexception

NoSuchElementException for my poker game Java


I could really use your help!

I fixed most of the errors but im stuck on this one at the moment.

Sorry for the long code and please let me know if you see any additional errors or mistakes i might have missed. I really appreciate your help <3

I keep receiving this Error and I cant seem to figure out why:

Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at mypokergame1.MyPokerGame.play(MyPokerGame.java:338)

my Card class:

import java.util.*;
import java.util.Scanner;

 /** class PlayingCardException: It is used for errors related to Card and Deck objects
  *  Do not modify this class!
 */
 class PlayingCardException extends Exception {

/* Constructor to create a PlayingCardException object */
PlayingCardException (){
    super ();
}

PlayingCardException ( String reason ){
    super ( reason );
}
  }


/** class Card : for creating playing card objects
 *  it is an immutable class.
 *  Rank - valid values are 1 to 13
 *  Suit - valid values are 0 to 3
 *  Do not modify this class!
 */
class Card {

/* constant suits and ranks */
static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades" };
static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};

/* Data field of a card: rank and suit */
private int cardRank;  /* values: 1-13 (see Rank[] above) */
private int cardSuit;  /* values: 0-3  (see Suit[] above) */

/* Constructor to create a card */
/* throw PlayingCardException if rank or suit is invalid */
public Card(int rank, int suit) throws PlayingCardException { 
if ((rank < 1) || (rank > 13))
    throw new PlayingCardException("Invalid rank:"+rank);
else
        cardRank = rank;
if ((suit < 0) || (suit > 3))
    throw new PlayingCardException("Invalid suit:"+suit);
else
        cardSuit = suit;
}

/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() { return cardRank; }
public int getSuit() { return cardSuit; }
public String toString() { return Rank[cardRank] + " " + Suit[cardSuit]; }


/* Few quick tests here */
public static void main(String args[])
{
try {
    Card c1 = new Card(1,3);    // A Spades
    System.out.println(c1);
    c1 = new Card(10,0);    // 10 Clubs
    System.out.println(c1);
    c1 = new Card(10,5);        // generate exception here
}
catch (PlayingCardException e)
{
    System.out.println("PlayingCardException: "+e.getMessage());
}
}
}


/** class Decks represents : n decks of 52 playing cards
 *  Use class Card to construct n * 52 playing cards!
 *
 *  Do not add new data fields!
 *  Do not modify any methods
 *  You may add private methods 
 */

class Decks {

    /* this is used to keep track of original n*52 cards */
private List<Card> originalDecks;   

/* this starts with n*52 cards deck from original deck   */
/* it is used to keep track of remaining cards to deal */
/* see reset(): it resets dealDecks to a full deck      */
private List<Card> dealDecks;

/* number of decks in this object */
private int numberDecks;


/**
 * Constructor: Creates default one deck of 52 playing cards in originalDecks and
 *          copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 */
public Decks()
{
    // implement this method!
    originalDecks = new ArrayList<Card>();  
    numberDecks=1;
    for (int i = 0; i < numberDecks; i++) {

        for (int j = 0; j <= 3; j++) {
            for (int k = 1; k <= 13; k++) {
                try {
                    originalDecks.add(new Card(k, j));
                } catch (PlayingCardException e) {
                    System.out.println("PlayingCardException: " + e.getMessage());
                }
            }
        }
    }
    dealDecks = new ArrayList<Card>(originalDecks);

}


/**
 * Constructor: Creates n decks (52 cards each deck) of playing cards in
 *              originalDecks and copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 */
public Decks(int n)
{
    // implement this method!
    originalDecks = new ArrayList<Card>();        
    numberDecks = n;
    for (int i = 0; i < numberDecks; i++) {

        for (int j = 0; j <= 3; j++) {
            for (int k = 1; k <= 13; k++) {
                try {
                    originalDecks.add(new Card(k, j));
                } catch (PlayingCardException e) {
                    System.out.println("PlayingCardException: " + e.getMessage());
                }
            }
        }
    }
    dealDecks = new ArrayList<Card>(originalDecks);

}


/**
 * Task: Shuffles cards in deal deck.
 * Hint: Look at java.util.Collections
 */
public void shuffle()
{
    // implement this method!
    java.util.Collections.shuffle(dealDecks);
}

/**
 * Task: Deals cards from the deal deck.
 *
 * @param numberCards number of cards to deal
 * @return a list containing cards that were dealt
 * @throw PlayingCardException if numberCard > number of remaining cards
 *
 * Note: You need to create ArrayList to stored dealt cards
 *       and should removed dealt cards from dealDecks
 *
 */
public List<Card> deal(int numberCards) throws PlayingCardException
{
    // implement this method!
    List dealtCards = new ArrayList<Card>();
    if (numberCards > dealDecks.size()) {
            throw new PlayingCardException("Not enough cards to deal");
        }
    for (int i = 0; i < numberCards; i++) {
        dealtCards.add(dealDecks.remove(0));
    }
    return dealtCards;
}

/**
 * Task: Resets deal deck by getting all cards from the original deck.
 */
public void reset()
{
    // implement this method!
     dealDecks = new ArrayList<Card>();
  for(Card card : originalDecks) {
      dealDecks.add(card);
  } 
}

/**
 * Task: Return number of remaining cards in deal deck.
 */
public int remain()
{
return dealDecks.size();
}

/**
 * Task: Returns a string representing cards in the deal deck 
 */
public String toString()
{
return ""+dealDecks;
}


/* Quick test                   */
/*                              */
/* Do not modify these tests    */
/* Generate 2 decks of cards    */
/* Loop 2 times:                */
/*   Deal 30 cards for 4 times  */
/*   Expect exception last time */
/*   reset()                    */

public static void main(String args[]) {

    System.out.println("*******    Create 2 decks of cards      *********\n\n");
    Decks decks  = new Decks(2);

for (int j=0; j < 2; j++)
{
        System.out.println("\n************************************************\n");
        System.out.println("Loop # " + j + "\n");
    System.out.println("Before shuffle:"+decks.remain()+" cards");
    System.out.println("\n\t"+decks);
        System.out.println("\n==============================================\n");

            int numHands = 4;
            int cardsPerHand = 30;

        for (int i=0; i < numHands; i++)
    {
            decks.shuffle();
            System.out.println("After shuffle:"+decks.remain()+" cards");
            System.out.println("\n\t"+decks);
        try {
                    System.out.println("\n\nHand "+i+":"+cardsPerHand+" cards");
                    System.out.println("\n\t"+decks.deal(cardsPerHand));
                    System.out.println("\n\nRemain:"+decks.remain()+" cards");
                System.out.println("\n\t"+decks);
                    System.out.println("\n==============================================\n");
        }
        catch (PlayingCardException e) 
        {
                System.out.println("*** In catch block : PlayingCardException : msg : "+e.getMessage());
        }
    }


    decks.reset();
}
}

}

my Card Class:

package mypokergame1;

import java.util.*;
import java.util.Scanner;

/** class PlayingCardException: It is used for errors related to Card and Deck objects
 *  Do not modify this class!
 */
class PlayingCardException extends Exception {

/* Constructor to create a PlayingCardException object */
PlayingCardException (){
    super ();
}

PlayingCardException ( String reason ){
    super ( reason );
}
}


/** class Card : for creating playing card objects
 *  it is an immutable class.
 *  Rank - valid values are 1 to 13
 *  Suit - valid values are 0 to 3
 *  Do not modify this class!
 */
class Card {

/* constant suits and ranks */
static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades" };
static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};

/* Data field of a card: rank and suit */
private int cardRank;  /* values: 1-13 (see Rank[] above) */
private int cardSuit;  /* values: 0-3  (see Suit[] above) */

/* Constructor to create a card */
/* throw PlayingCardException if rank or suit is invalid */
public Card(int rank, int suit) throws PlayingCardException { 
if ((rank < 1) || (rank > 13))
    throw new PlayingCardException("Invalid rank:"+rank);
else
        cardRank = rank;
if ((suit < 0) || (suit > 3))
    throw new PlayingCardException("Invalid suit:"+suit);
else
        cardSuit = suit;
}

/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() { return cardRank; }
public int getSuit() { return cardSuit; }
public String toString() { return Rank[cardRank] + " " + Suit[cardSuit]; }


/* Few quick tests here */
public static void main(String args[])
{
try {
    Card c1 = new Card(1,3);    // A Spades
    System.out.println(c1);
    c1 = new Card(10,0);    // 10 Clubs
    System.out.println(c1);
    c1 = new Card(10,5);        // generate exception here
}
catch (PlayingCardException e)
{
    System.out.println("PlayingCardException: "+e.getMessage());
}
}
}


/** class Decks represents : n decks of 52 playing cards
 *  Use class Card to construct n * 52 playing cards!
 *
 *  Do not add new data fields!
 *  Do not modify any methods
 *  You may add private methods 
 */

class Decks {

/* this is used to keep track of original n*52 cards */
private List<Card> originalDecks;   

/* this starts with n*52 cards deck from original deck   */
/* it is used to keep track of remaining cards to deal */
/* see reset(): it resets dealDecks to a full deck      */
private List<Card> dealDecks;

/* number of decks in this object */
private int numberDecks;


/**
 * Constructor: Creates default one deck of 52 playing cards in originalDecks and
 *          copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 */
public Decks()
{
    // implement this method!
    originalDecks = new ArrayList<Card>();  
    numberDecks=1;
    for (int i = 0; i < numberDecks; i++) {

        for (int j = 0; j <= 3; j++) {
            for (int k = 1; k <= 13; k++) {
                try {
                    originalDecks.add(new Card(k, j));
                } catch (PlayingCardException e) {
                    System.out.println("PlayingCardException: " + e.getMessage());
                }
            }
        }
    }
    dealDecks = new ArrayList<Card>(originalDecks);

}


/**
 * Constructor: Creates n decks (52 cards each deck) of playing cards in
 *              originalDecks and copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 */
public Decks(int n)
{
    // implement this method!
    originalDecks = new ArrayList<Card>();        
    numberDecks = n;
    for (int i = 0; i < numberDecks; i++) {

        for (int j = 0; j <= 3; j++) {
            for (int k = 1; k <= 13; k++) {
                try {
                    originalDecks.add(new Card(k, j));
                } catch (PlayingCardException e) {
                    System.out.println("PlayingCardException: " + e.getMessage());
                }
            }
        }
    }
    dealDecks = new ArrayList<Card>(originalDecks);

}


/**
 * Task: Shuffles cards in deal deck.
 * Hint: Look at java.util.Collections
 */
public void shuffle()
{
    // implement this method!
    java.util.Collections.shuffle(dealDecks);
}

/**
 * Task: Deals cards from the deal deck.
 *
 * @param numberCards number of cards to deal
 * @return a list containing cards that were dealt
 * @throw PlayingCardException if numberCard > number of remaining cards
 *
 * Note: You need to create ArrayList to stored dealt cards
 *       and should removed dealt cards from dealDecks
 *
 */
public List<Card> deal(int numberCards) throws PlayingCardException
{
    // implement this method!
    List dealtCards = new ArrayList<Card>();
    if (numberCards > dealDecks.size()) {
            throw new PlayingCardException("Not enough cards to deal");
        }
    for (int i = 0; i < numberCards; i++) {
        dealtCards.add(dealDecks.remove(0));
    }
    return dealtCards;
}

/**
 * Task: Resets deal deck by getting all cards from the original deck.
 */
public void reset()
{
    // implement this method!
     dealDecks = new ArrayList<Card>();
  for(Card card : originalDecks) {
      dealDecks.add(card);
  } 
}

/**
 * Task: Return number of remaining cards in deal deck.
 */
public int remain()
{
return dealDecks.size();
}

/**
 * Task: Returns a string representing cards in the deal deck 
 */
public String toString()
{
return ""+dealDecks;
}


/* Quick test                   */
/*                              */
/* Do not modify these tests    */
/* Generate 2 decks of cards    */
/* Loop 2 times:                */
/*   Deal 30 cards for 4 times  */
/*   Expect exception last time */
/*   reset()                    */

public static void main(String args[]) {

    System.out.println("*******    Create 2 decks of cards      *********\n\n");
    Decks decks  = new Decks(2);

for (int j=0; j < 2; j++)
{
        System.out.println("\n************************************************\n");
        System.out.println("Loop # " + j + "\n");
    System.out.println("Before shuffle:"+decks.remain()+" cards");
    System.out.println("\n\t"+decks);
        System.out.println("\n==============================================\n");

            int numHands = 4;
            int cardsPerHand = 30;

        for (int i=0; i < numHands; i++)
    {
            decks.shuffle();
            System.out.println("After shuffle:"+decks.remain()+" cards");
            System.out.println("\n\t"+decks);
        try {
                    System.out.println("\n\nHand "+i+":"+cardsPerHand+" cards");
                    System.out.println("\n\t"+decks.deal(cardsPerHand));
                    System.out.println("\n\nRemain:"+decks.remain()+" cards");
                System.out.println("\n\t"+decks);
                        System.out.println("\n==============================================\n");
        }
        catch (PlayingCardException e) 
        {
                System.out.println("*** In catch block : PlayingCardException : msg : "+e.getMessage());
        }
    }


    decks.reset();
}
}

}

Solution

  • The exception you have received is quite informative... learning to read exceptions and trace them is an important process!

    It looks to me as if at line 338 of MyPokerGame.java you are calling scanner.nextLine without first double-checking that scanner.hasNextLine()

    calling nextLine() when the scanner doesn't have a next line will throw this exception.

    the idiomatic way to use the Scanner class is:

    while(scanner.hasNextLine()){
        str=scanner.nextLine();
        //...
    }
    

    If you ever get an exception check the source of the exception and refer to the docs for the Exception type (or just paste the execption into google and you'll probably find a link to the answer right here on StackOVerflow!)