Right, I wasn't sure whether to put this here or in the java forum (since I'm trying this in java)
but in the end I figured it is probably a general coding question.
Hope I got it right :)

So, about object names :)
I'm trying to do the c++ forum coding exercise (in java) where you are supposed to model playing cards.
The thing is, I'd like the program to just create new card objects when needed,
instead of hardcoding every card.

How would I go around this?
(also I'm a rookie, so feel very free to comment on any kind of bad code I might have made)

Here is what I've got (which will hardcode the object names):

public enum Suit
{
    HEARTS, CLUBS, SPADES, DIAMONDS
}
public enum Value
{
    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
}
public class card
{

       // instance variables - replace the example below with your own
    private Suit suit;
    private Value value;

    /**
     * Constructor for objects of class card
     */
    public card(Value value, Suit suit)
    {
        this.value = value;
        this.suit = suit;
    }
    
    public void print()
    {
        System.out.println(this.value + "\tof " + this.suit);

    }
}
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
/**
 * Write a description of class CardDeck here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class CardDeck
{
    // instance variables - replace the example below with your own
    private int cardsDealt;
    private List<card> cardList;
    private Random randGen = new Random();

    /**
     * Constructor for objects of class CardDeck
     */
    public CardDeck()
    {
        // initialise instance variables
        cardsDealt=0;
        cardList = new ArrayList<card>();
    }
    
    public CardDeck(int cardsDealt)
    {
        this.cardsDealt = cardsDealt;
        cardList = new ArrayList<card>();
    }
    
    public card draw()
    {
        int randomValue = randGen.nextInt(13) +1;
        int randomSuit = randGen.nextInt(4);
        Value value = null;
        Suit suit = null;
        
        switch(randomValue)
        {
            case 1:     value = Value.ACE;      break;
            case 2:     value = Value.TWO;      break;
            case 3:     value = Value.THREE;    break;
            case 4:     value = Value.FOUR;     break;
            case 5:     value = Value.FIVE;     break;
            case 6:     value = Value.SIX;      break;
            case 7:     value = Value.SEVEN;    break;
            case 8:     value = Value.EIGHT;    break;
            case 9:     value = Value.NINE;     break;
            case 10:    value = Value.TEN;      break;
            case 11:    value = Value.JACK;     break;
            case 12:    value = Value.QUEEN;    break;
            case 13:    value = Value.KING;     break;
        }
        
        switch(randomSuit)
        {
            case 0:     suit = Suit.HEARTS;     break;
            case 1:     suit = Suit.DIAMONDS;   break;
            case 2:     suit = Suit.SPADES;     break;
            case 3:     suit = Suit.CLUBS;      break;
        }
        
        card card1 = new card(value, suit);
        cardList.add(card1);
        this.cardsDealt++;
        return(card1);
    }
    
    public void print()
    {
        for (card c : cardList)
        {
            c.print();
        }
    }
}

Recommended Answers

All 9 Replies

Sorry about the code tag, don't know what happened.

I suppose I could change the draw method like this:

//changed here
    public void draw()
    {
        int randomValue = randGen.nextInt(13) +1;
        int randomSuit = randGen.nextInt(4);
        Value value = null;
        Suit suit = null;
        
        switch(randomValue)
        {
            case 1:     value = Value.ACE;      break;
            case 2:     value = Value.TWO;      break;
            case 3:     value = Value.THREE;    break;
            case 4:     value = Value.FOUR;     break;
            case 5:     value = Value.FIVE;     break;
            case 6:     value = Value.SIX;      break;
            case 7:     value = Value.SEVEN;    break;
            case 8:     value = Value.EIGHT;    break;
            case 9:     value = Value.NINE;     break;
            case 10:    value = Value.TEN;      break;
            case 11:    value = Value.JACK;     break;
            case 12:    value = Value.QUEEN;    break;
            case 13:    value = Value.KING;     break;
        }
        
        switch(randomSuit)
        {
            case 0:     suit = Suit.HEARTS;     break;
            case 1:     suit = Suit.DIAMONDS;   break;
            case 2:     suit = Suit.SPADES;     break;
            case 3:     suit = Suit.CLUBS;      break;
        }
        //and changed here
        cardList.add(new card(value, suit);
        this.cardsDealt++;
    }

And then handle the cards via the cardList list.
It just seems like a cheap work around? :)

Instead of a switch statement you could use arrays to hold the values.

In real life card games, cards are drawn from one or more shuffled packs, so a more realistic code design would be to create a new "pack(s) of cards" which was a collection (eg ArrayList) of n*52 Cards (n of each), then the draw method just takes a random card from the pack, until there are none left (via a random int, 0 .. (size of deck -1)).

So both of you would throw away the enums, and use arrays instead? :)

JamesCherrill: wouldn't I then have then have to create the 104 cards (assuming 2 decks are used),
and give them each a unique number to be selected by random int.... ?
Or have I got it all wrong? :)

EDIT: also, It seems a bit stupid that I've made a card class, only containing the suit and value.
Should I replace it by an array or something?

No, the enums are great - try something like:

ArrayList<Card> pack = new ArrayList<Card>(52);
for (Suit s : Suit.values())
  for (Value v : Value.values())
    pack.add(new Card(v, s);

now you can draw a card realistically with something like

pack.remove(rand.nextInt(pack.size() - 1));
commented: Solved my problem :) +3

Keep the enums. Replace the switch with an array since the in/out for using the switch is the same as for an array.

Value[] values = {Value.TWO, Value.THREE};
Value aVal = values[1];

Yo Norm.
You don't need to do that by hand - to quote the Java Lang Ref

each enum type has a static values method that returns an array containing all of the values of the enum type in the order they are declared.

so all you need is: Value aVal = Value.values()[1];

Thanks.
When in doubt read the doc.
I don't use enum very often and haven't read the docs in a long time

Well Thanks a bunch to both of you :)
This did the trick, and I don't have to worry about the object names anymore, awesome :)

EDIT:I went with

pack.remove(rand.nextInt(totalCards - cardsDealt);

So that the random number keeps up with the number of cards that are actually left in the deck,
regardless of how many decks are in the pack :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.