Search code examples
javaindexoutofboundsexceptionplaying-cards

Java - How to create a deck of cards (with a focus on static arrays)? - AP Computer Science Project


this is my first question ever. Just to clarify, I did check to see if there were any questions that could have helped me before asking this. Apologies in advance if I do anything incorrectly, I'm new.

Anyways, for my AP CS class I must make a deck a cards and print it out in the text window. I believe I am very close to being finished. As the title says, in general how do I create a deck of cards with a focus on static arrays? But furthermore (After the error I ask about below is solved), when looking at the code I have produced so far, is that the correct way to do it?

Here is the given code (meaning this can not be changed):

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

   public Card(String s, String r, int v)
   {
      suit = s;
      rank = r;
      value = v;
   }

   public String getSuit()       { return suit; }
   public String getRank()       { return rank; }
   public int getValue()         { return value; }

   public void setSuit(String s) { suit = s; }
   public void setRank(String r) { rank = r; }
   public void setValue(int v)   { value = v; } 

   public String toString()
   {
      return "[" + suit + ", " + rank + ", " + value + "]";
   }
}

And here is the what I have coded so far:

public class Lab11bst
{
    public static void main(String[] args)
    {
      Deck deck = new Deck();
      System.out.println(deck);
    }
}


class Deck
{
   private int numberOfCards;
   private Card [] cards;
   private String [] suits = {"Clubs","Diamonds","Hearts","Spades"};
   private String rank;
   private int value;


   public Deck() // This creates a deck of 52 playing cards.
   {
      numberOfCards = 52;
      cards = new Card[52];
      for ( int suit = 0; suit <= 3; suit++ )
      {
         String [] ranks = {"Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"};
         for ( int rank = 1; rank <= 13; rank++ )
         {
            if (rank == 1)
            {
               this.rank = "Ace";
            }
            else if (rank == 11)
            {
               this.rank = "Jack";
            }
            else if (rank == 12)
            {
               this.rank = "Queen";
            }
            else if (rank == 13)
            {
               this.rank = "King";
            }
            else
            {
               this.rank = "" + ranks[rank];
            }
            for ( int value = 1; value <= 10; value++ )
            {
               if (this.rank == "Ace")
               {
                  value = 1;
               }
               else if (this.rank == "Jack")
               {
                  value = 10;
               }
               else if (this.rank == "Queen")
               {
                  value = 10;
               }
               else if (this.rank == "King")
               {
                  value = 10;
               }
               else
               {
                  this.value = value;
               }
               cards [numberOfCards] = new Card(suits[suit],this.rank,value);
               numberOfCards ++;
            }
         }
      }
   }
}

Looking at my code, I'm pretty sure there is a better way to get rid of all those if statements and make it all more short and concise. My sort-of third question (which may be necessary/might help to solve before answering the main two questions) is how do I fix this error when I run the program?:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 52
    at Deck.<init>(Lab11bst.java:89)
    at Lab11bst.main(Lab11bst.java:5)

Thank you very much in advance.


Solution

  • I sadly found few logical errors, especially with the numberOfCards int that you used as the index for the cards array. As a result, I have optimized and fixed your class Deck, it works with the main method and class Card you have created:

    class Deck {
        private int numberOfCards = 52;
        private Card[] cards;
    
        private String[] suits = { "Clubs", "Diamonds", "Hearts", "Spades" };
        String[] ranks = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen",
                "King" };
        int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10 };
    
        private String rank;
        private int value;
    
        public Deck() // This creates a deck of 52 playing cards.
        {
            cards = new Card[numberOfCards];
            int currentCardId = 0;
            for (int suit = 0; suit <= 3; suit++) {
                for (int rank = 0; rank <= 12; rank++) {
                    this.rank = "" + ranks[rank];
                    this.value = values[rank];
    
                    cards[currentCardId] = new Card(suits[suit], this.rank, value);
                    System.out.println(cards[currentCardId].toString()); //print out the cards .toString() as it was added to the array
                    currentCardId++;
                }
            }
        }
    }
    

    It fills up the Card[] cards, feel free to test it out by using a getter and systemout. It is very adaptive to cardnaming and valuesetting, as you can fill the according arrays with whatever information you want. If you want further explanation, let me know.