Reputation:
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.
Upvotes: 6
Views: 1878
Reputation:
Thank you everyone for providing answers, they really helped enforce some concepts for me. I wish I could accept more than just one answer for my question. Here is the complete program I ended up with (with an added "shuffle" method which I had left out earlier for simplicity).
public class Lab11bst
{
public static void main(String[] args)
{
Deck deck = new Deck();
}
}
class Deck {
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 int numberOfCards = 52; // Variable name "size" was changed to "numberOfCards" to clarify self identifier further for programmer
private Card[] cards;
private String rank;
private int value;
public Deck()
{
cards = new Card[numberOfCards];
for (int suit = 0; suit <= 3; suit++)
{
for (int rank = 0; rank <= 12; rank++)
{
for (int values = 0; values <=12; values++)
this.rank = ranks[rank];
this.value = values[rank];
numberOfCards--;
cards[numberOfCards] = new Card(suits[suit], this.rank, value);
}
}
shuffle(); // Shuffle method call. Comment out to obtain an unshuffled, ordered deck of cards.
for(Card card : cards)
{
System.out.println(card);
}
}
private void shuffle()
{
for (int k = 1; k < 1000; k++)
{
int random1 = (int) (Math.random() * 52);
int random2 = (int) (Math.random() * 52);
Card temp = cards[random1];
cards[random1] = cards[random2];
cards[random2] = temp;
}
}
}
Upvotes: 0
Reputation: 321
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.
Upvotes: 0
Reputation: 11
You have set the 'numberOfCards = 52;' when initial the Deck. After that, when you need to new Card, you call numberOfCards++ as the index of array. But the array just initial with 52. So you meet this problem.
Upvotes: 1
Reputation: 2154
It's quite simple. You got a variable numberOfCards
which is 52 at the start.
If you go through the for-loop you're trying to get the 52 index from the cards
array. So that will throw your ArrayIndexOutOfBoundsException
.
The first element in an array is the 0
index not the 1
index.
Instead of 52 you should start at 51 so you doesn't get this error. There is one more thing if you increment the numberOfCards
variable it will still throw that exception.
To print each card after the creation I would like to do some changes:
...
Card createdCard = new Card(suits[suit], this.rank, value);
System.out.println(createdCard); //you can also do System.out.println(createdCard.toString());
cards[numberOfCards] = createdCard;
...
To print all created cards after they were created you can do this:
for(Card card : cards) {
System.out.println(card);
}
System.out.println()
will call the overriden toString()
method in your Card
class
Upvotes: 0
Reputation: 521
The first problem is as pointed out by CodeMatrix - wrong starting point, you should start array index at 0. On the other hand - you increment the index of 52 item array 4*13*10 (3 loops) times - thats 520 increments. Thats why you will always jump out of range.
Upvotes: 0