Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deck of cards JAVA

Tags:

java

I have created my deck of cards that deals every card and a suit until there is no card remaining. For my project, I need to split it up into 3 classes which includes a driver class. I first created one class with everything so I knew how to make it all work.

public class DeckOfCards2 {
  public static void main(String[] args) {
    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"};

    // Initialize cards
    for (int i = 0; i < deck.length; i++) {
      deck[i] = i;
    }

    // Shuffle the cards
    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 the all the cards
    for (int i = 0; i < 52; i++) {
      String suit = suits[deck[i] / 13];
      String rank = ranks[deck[i] % 13];
      System.out.println( rank + " of " + suit);
    }
  }
}

Now trying to split it up into 3 classes. I am getting red sqiggle lines on ALL my deck/suit variables on my DeckOfCards class. I dont know how to fix it.

public class DeckOfCards {
  private Card theCard;
  private int remainingCards = 52;

  DeckOfCards() {
    theCard = new Card();   
  }

  public void 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;
       remainingCards--;
     }
  }

  public void deal(){
    for (int i = 0; i < 52; i++) {
       String suit = suits[deck[i] / 13];
       String rank = ranks[deck[i] % 13];
       System.out.println( rank + " of " + suit);
       System.out.println("Remaining cards: " + remainingCards);
     }
   }
}

Card class:

public class Card {
  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"};

  Card() {
    for (int i = 0; i < deck.length; i++) {
      deck[i] = i;
    }
  }
}

Dealer class

public class Dealer {
  public static void main(String[]args){
    System.out.println("The deck will randomly print out a card from a full deck each time");

    DeckOfCards player = new DeckOfCards();
    player.deal();
  }
}
like image 771
Chris Avatar asked Apr 11 '13 06:04

Chris


People also ask

How do you represent a deck of cards in Java?

Just as you can create an array of String objects, you can create an array of Card objects. The following statement creates an array of 52 cards: Card[] cards = new Card[52];


1 Answers

As somebody else already said, your design is not very clear and Object Oriented.

The most obvious error is that in your design a Card knows about a Deck of Cards. The Deck should know about cards and instantiate objects in its constructor. For Example:

public class DeckOfCards {
    private Card cards[];

    public DeckOfCards() {
        this.cards = new Card[52];
        for (int i = 0; i < ; i++) {
            Card card = new Card(...); //Instantiate a Card
            this.cards[i] = card; //Adding card to the Deck
        }
     }

Afterwards, if you want you can also extend Deck in order to build different Deck of Cards (for example with more than 52 cards, Jolly etc.). For Example:

public class SpecialDeck extends DeckOfCards {
   ....

Another thing that I'd change is the use of String arrays to represent suits and ranks. Since Java 1.5, the language supports Enumeration, which are perfect for this kind of problems. For Example:

public enum Suits {
    SPADES, 
    HEARTS, 
    DIAMONDS,
    CLUBS;  
}

With Enum you get some benefits, for example:

1) Enum is type-safe you can not assign anything else other than predefined Enum constants to an Enum variable. For Example, you could write your Card's constructor as following:

public class Card {

   private Suits suit;
   private Ranks rank;

public Card(Suits suit, Ranks rank) {
    this.suit = suit;
    this.rank = rank;
}

This way you are sure to build consistent cards that accept only values ​​of your enumeration.

2) You can use Enum in Java inside Switch statement like int or char primitive data type (here we have to say that since Java 1.7 switch statement is allowed also on String)

3) Adding new constants on Enum in Java is easy and you can add new constants without breaking existing code.

4) You can iterate through Enum, this can be very helpful when instantiating Cards. For Example:

/* Creating all possible cards... */
for (Suits s : Suits.values()) {
    for (Ranks r : Ranks.values()) {
         Card c = new Card(s,r);
    }  
}

In order to not invent again the wheel, I'd also change the way you keep Cards from array to a Java Collection, this way you get a lot of powerful methods to work on your deck, but most important you can use the Java Collection's shuffle function to shuffle your Deck. For example:

private List<Card> cards = new ArrayList<Card>();

//Building the Deck...

//...

public void shuffle() {
    Collections.shuffle(this.cards); 
}
like image 150
Luigi Massa Gallerano Avatar answered Oct 27 '22 01:10

Luigi Massa Gallerano