Deck of cards index/array error - java

I'm trying to create a deck of cards that shuffles itself and then outputs the cards in random order. I am running into the error ArrayIndexOutOfBoundsException for the lines
return ranks[rank] + " of " + suits[suit];
and
System.out.println( C.toString() );
What am I doing wrong? It outputs the deck size, and then occasionally outputs a card or two before showing the error code. Thanks in advance.
import java.util.Random;
import java.util.ArrayList;
public class Deck
{
private ArrayList<Card> cards;
Deck()
{
cards = new ArrayList<Card>();
for (int a=0; a<=3; a++)
{
for (int b=0; b<=12; b++)
{
cards.add( new Card(a,b) );
}
}
}
public static void main(String[] args)
{
Deck deck = new Deck();
Card C;
System.out.println( deck.getTotalCards() );
while (deck.getTotalCards() != 0)
{
C = deck.drawFromDeck();
System.out.println( C.toString() );
}
}
public class Card
{
private int rank,
suit;
private String[] suits = {"Hearts", "Spades", "Diamonds", "Clubs"};
private String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
Card(int rank, int suit)
{
this.rank=rank;
this.suit=suit;
}
public #Override String toString()
{
return ranks[rank] + " of " + suits[suit];
}
public int getRank()
{
return rank;
}
public int getSuit()
{
return suit;
}
}
public Card drawFromDeck()
{
Random generator = new Random();
int index = generator.nextInt( cards.size() );
return cards.remove(index);
}
public int getTotalCards()
{
return cards.size();
}
}

Everything there is good but you initialize the cards backwards.
Your Card constructor is (rank, suit) and your Deck constructor is creating them (suit, rank).
Just flip the order of the args in your Deck constructor on line 15
cards.add( new Card(a, b) );
should be
cards.add( new Card(b, a) );
Since a ranges from 0 to 3, a is the suit, and should be the second argument in the constructor.

Related

I made a simple java program to create an array of cards (a deck), and then search a particular card within it [duplicate]

This question already has answers here:
Why this two simple objects are not equal?
(9 answers)
Why do I need to override the equals and hashCode methods in Java?
(31 answers)
Closed 1 year ago.
Here, "cards" is the array of objects, and tcard (a jack of Diamonds), which should exist in the array, is the card I need to search. However the function always returns a value of -1.
public class Card
{
private int rank;
private int suit;
public static Card[] cards;
public Card(int rank, int suit)
{
this.rank = rank;
this.suit = suit;
}
public String toString() {
String[] ranks = {null, "Ace", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "Jack", "Queen", "King"};
String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
String s = ranks[this.rank] + " of " + suits[this.suit];
return s;
}
public static void createDeck()
{
cards=new Card[52];
int in1=0;
for (int s1 = 0; s1<= 3; s1++) {
for (int r1 = 1; r1<= 13; r1++) {
cards[in1] = new Card(r1, s1);
in1++;
}
}
}
public static int search(Card[] scards, Card target) {
for (int i = 0; i < scards.length; i++) {
if (scards[i].equals(target)) {
return i;
}
}
return -1;
}
public static void main(String args[])
{
createDeck();
Card tcard=new Card(11,1);
int n1=search(cards,tcard);
System.out.println(n1);
}
}

deck of cards using methods and multiple classes

I'm getting no output and not sure where to go from here.
Design and implement a class called Card, which represents a standard playing card. Each card has a suit and a face value. Then, create a driver class that stores 52 objects of the Card class into an array. Include methods to shuffle the deck, deal a card and report the number of cards left in the deck. The shuffle method should assume a full deck. Your main method should deal each card from a shuffled deck, printing each card (suit and face value) as it is dealt.
Here's what I have so far:
import java.util.Random;
public class card {
public static void main(String[] args) {}
public class deck {
int[] deck = new int[52];
String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
public void create() {//initialize cards
for (int i = 0; i < deck.length; i++) deck[i] = i;
}
public void shuffle() {//deck shuffle
for (int i = 0; i < deck.length; i++) {
int index = (int) (Math.random() * deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
//display all the cards!
for (int i = 0; i < deck.length; i++)
{
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println("Card number " + deck[i] + ": " + rank + " of " + suit);
}
}
}
}
In java, the method main() is where your code will start running. You have nothing in your main method right now:
public static void main(String[] args) {}
To get it to do something, change it to something like this:
public static void main(String[] args) {
deck myDeck = new deck();
myDeck.create();
myDeck.shuffle();
}
As a note, it is good practice in java to name your classes with capital letters.
Here, I tried to write some code for you, its not complete, but provides a framework for you to continue, all you have to do is implement your own shuffle method and add more variables to ranks:
public class CardDriver {
public static void main(String[] args) {
Deck myDeck = new Deck();
myDeck.shuffle();
System.out.println("Dealt cards are:");
myDeck.dealAllCards();
}
}
class Card {
String suite, faceValue;
Card(String suite, String faceValue) {
this.suite = suite;
this.faceValue = faceValue;
}
void printCard() {
System.out.println(faceValue + " " + suite);
}
}
class Deck {
String[] suits = { "Spades", "Hearts", "Diamonds", "Clubs" };
String[] ranks = { "6", "7" };
int count = ranks.length * suits.length;
Card deck[] = new Card[count];
Deck() { // fills out the deck
int index = 0; // this is for simple deck filling
for (int i = 0; i < ranks.length; i++) { // for ranks
for (int j = 0; j < suits.length; j++) { // for suits
deck[index] = new Card(suits[j], ranks[i]);
index++;
}
}
};
void shuffle() { // shuffles the deck
// your code here
}
Card dealCard() { // gives card from deck
if (returnLeft() > 0) {
count--;
return deck[count];
} else return null;
}
int returnLeft() {
return count;
}
void dealAllCards() {
int counter = count;
for (int i = 0; i < counter; i++) {
Card someCard = dealCard();
someCard.printCard();
}
}
}

How will i invoke the array parameters in java?

public void createDeck() {
k=0;
cards=new Card[52];
for (i=0;i<4;i++) {
for (j=0;j<13;j++){
cards[k]=new Card(i,j);
k++;
}
}
}
public void shuffleDeck(int m){
Random random = new Random();
Card cardTemp;
for(i=0;i<m;i++){
k=random.nextInt(52);
cardTemp=cards[i%52];
cards[i%52]=cards[(i+k)%52];
cards[(i+k)%52]=cardTemp;
}
}
Hello. I want to take i and j which is in
cards[k]=new Card(i,j);
Because i want to show rank an suit by taking this i and j:
public Card(int suit,int rank){
this.rank=rank;
this.suit=suit;
}
private final static String[] suits = { "Hearts", "Spades", "Diamonds", "Clubs" };
private final static String[] ranks = { "Ace", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "Jack", "Queen", "King" };
In another class,
deck=new Deck();
deck.createDeck();
deck.shuffleDeck(111);
Should i use another array? I am really confused. I want to give the screen, for example ace hearts after shuffling.
it is not clear what are you asking, but i can guess that you want is when you draw a card from the shuffled deck you'll be able to see it's rank and suit. right?
then the answer is to add 2 methods to Card class:
public int getSuit()
{
return suit;
}
public int getRank()
{
return rank;
}
and then, when you draw a card:
Card c = cards[k];
int cSuit = c.getSuit();
int cRank = c.getRank();

java simulation of a card dealer - ArrayIndexOutOfBoundsException

I am having trouble executing my code and unable to pinpoint exactly the source of the error or why and maybe someone might be able to take a look and provide me with some feedback if possible.
Error message:
51
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
3 of Clubs, Diamonds, Hearts, Spades
at javacards.Card.toString(Card.java:15)
at javacards.CardRun.main(CardRun.java:15)
CardRun Class:
public class CardRun {
public static void main(String[] args)
{
Deck deck = new Deck();
Card C;
System.out.println(deck.getTotalCards());
while(deck.getTotalCards() != 0)
{
C = deck.drawFromDeck();
System.out.println(C.toString());
}
}
Card Class
public class Card {
private int card, suit;
private static String[] suits = {"Clubs, Diamonds, Hearts, Spades"};
private static String[] cards = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
Card(int suit, int card)
{
this.card = card;
this.suit = suit;
}
public #Override String toString()
{
return cards[card] + " of " + suits[suit];
}
public int getCard()
{
return card;
}
public int getSuit()
{
return suit;
}
}
Deck Class
public class Deck {
private Card[]cards;
int i;
Deck()
{
i = 51;
cards = new Card[52];
int x = 0;
for(int a=0; a<=3; a++)
{
for(int b=0; b<=12; b++)
{
cards[x] = new Card(a,b);
x++;
}
}
}
public Card drawFromDeck()
{
Random generator = new Random();
int index = 0;
index = generator.nextInt(i);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = null;
i--;
return temp;
}
public int getTotalCards()
{
return i;
}
}
This array:
private static String[] suits = {"Clubs, Diamonds, Hearts, Spades"};
only contains one item - you probably meant:
private static String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};

How to deal 4 hands of 10 cards with a deck?

So I have the code for a deck, but I dont know how to make another class to deal 4 hands of 10 cards each. The other class should print on the screen, in text, 4 hands of 10 random cards. Can someone show me the code on how to accomplish this? Im using blueJ aswell.
Below is my code for the deck:
public class Card
{
public static void main(String[] args)
{
String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
String[] rank = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace" };
int SUITS = suit.length;
int RANKS = rank.length;
int N = SUITS * RANKS;
// initialize deck
String[] deck = new String[N];
for (int i = 0; i < RANKS; i++) {
for (int j = 0; j < SUITS; j++) {
deck[SUITS*i + j] = rank[i] + " of " + suit[j];
}
}
// shuffle the deck
for (int i = 0; i < N; i++) {
int r = i + (int) (Math.random() * (N-i));
String t = deck[r];
deck[r] = deck[i];
deck[i] = t;
}
for (int i = 0; i < N; i++) {
System.out.println(deck[i]);
}
}
}
In the spirit of the game, let's create a hierarchy for handling could work. The largest scope will be the Game, which will delegate the actions to the other classes. We will also have 3 classes: Deck, Dealer, Player.
A Game will have a Dealer, and an ArrayList of Player
A Dealer will have a Deck
A Player will have an ArrayList of String indicating your cards
A Game can then tell a dealer to create and shuffle a deck. You can call a dealCards passing the Players as a param to the dealer who can, based on the number of players, give them the next element in the Deck, and remove that element from the deck.
Once you have dealt all the cards, the game can then tell the players to show their hands, printing the results.
public Dealer{
private Deck deck;
....
public void shuffleDeck(){...}
public void dealCards(List<Player> players){ ...}
}
public Player{
private List<String> hand;
....
public void addToHand(String card){....}
}
Your Card / Deck class should be broken up into two classes.
A Card class would describe a card.
public class Card {
private String rank;
private String suit;
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
public String getRank() {
return rank;
}
public String getSuit() {
return suit;
}
#Override
public String toString() {
return rank + " of " + suit;
}
}
A Deck class describes a deck of cards.
public class Deck {
private String[] rank = { "2", "3", "4", "5", "6", "7", "8", "9",
"10", "Jack", "Queen", "King", "Ace" };
private String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
private Card[] cards;
public Deck() {
cards = new Card[suit.length * rank.length];
for (int i = 0; i < rank.length; i++) {
for (int j = 0; j < suit.length; j++) {
cards[suit.length * i + j] = new Card(rank[i], suit[j]);
}
}
}
public Card[] shuffleDeck() {
for (int i = 0; i < cards.length; i++) {
int r = (int) (Math.random() * (cards.length - 1));
Card t = cards[r];
cards[r] = cards[i];
cards[i] = t;
}
return cards;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cards.length; i++) {
builder.append(cards[i].toString());
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
}
}
Until you understand how these two classes work together, there's no point introducing other classes.
The point of Java, or any object oriented computer language, is to break up your problem into smaller classes that each do one thing and do it well.

Categories

Resources