1

I'm writing a poker game, and have all of the cards stored in an arraylist created in the class Deck:

public class Deck {

ArrayList<Card> deck = new ArrayList<Card>();

Deck(){  //Build the deck in order.

    for(int suit = 1; suit <= 4; suit++){
        for(int rank = 1; rank <= 13; rank++){
            Card card = new Card(rank, suit);
            deck.add(card);
        }
    }
}

. . .

I want to have another class--Hand--draw the first five elements from the arraylist and put them into a new arraylist called myHand:

public class Hand {

ArrayList<Card> myHand = new ArrayList<Card>();
Deck deckObject = new Deck();

public void Draw(){ //Draws the top 5 cards of the deck and puts them in your hand ArrayList.
for(int i = 0; i <= 4; i++){
    myHand.add(deckObject.deck.get(0));
    deckObject.deck.remove(0);
    }
}

. . . So far so good. When I display the hand ArrayList from the main class I get the first five cards in the deck. However, when I display the deck from the Deck class (after invoking the Draw() method) all 52 cards are still there.

If I create a getDeck() method in the Hand class and call it, the first five cards are removed as expected...

So it seems like I have one-way communication between these two classes; when I modify the ArrayList from the Hand class, the Deck class doesn't know about it, and it seems that each class is keeping a separate version of the ArrayList. What's going on here?

1
  • Because you are creating a new instance of a Deck object. You don't want to do that. Pass the Deck object into the Draw method, or make a singleton Deck object. You don't show your main class that orchestrates the application, but you should create one Deck object in there, then pass it around as needed. Commented Dec 16, 2013 at 3:31

3 Answers 3

3

Each Hand has its own Deck. You want to share one Deck among many hands.

I think you want something like this:

public class Hand {

    Deck deck;
    ArrayList<Card> myHand = new ArrayList<Card>();

    Hand(Deck deck) {
        this.deck = deck;
    }

    public void removeCard(Card card) {
        deckObject.deck.remove(card);
    }

    public void Draw() {
        for(int i = 0; i <= 4; i++) {
            myHand.add(deckObject.deck.get(0));
            deckObject.deck.remove(0);
        }
    }
}

and then

Deck deck = new Deck();
Hand hand1 = new Hand(deck);
Hand hand2 = new Hand(deck);
hand1.Draw();
hand2.Draw();

FYI

  1. Java convention is to lowercase methods (e.g. Draw).
  2. Initializing variables inside the constructor is often clearer.
  3. Declaring List<Card> myHand is usually preferred since it has a higher level of abstraction.
Sign up to request clarification or add additional context in comments.

Comments

0

I would try this in your Hand method Draw() which should really be named draw().

    if (deckObject.deck.size() > 0) {        // Are there cards in the deck?
      myHand.add(deckObject.deck.remove(0)); // add the card removed from 
                                             // the deck to the Hand.
    } else {
      break;                                 // No cards.
    }
    // deckObject.deck.remove(0);            // Already taken care of.

Comments

0

Generally speaking, you don't want anybody else messing with the internal state of you objects. Instead, you want to provide methods which allow other objects to interact with it, for example...

public class Deck {

    private ArrayList<Card> deck = new ArrayList<Card>();

    Deck(){  //Build the deck in order.

        for(int suit = 1; suit <= 4; suit++){
            for(int rank = 1; rank <= 13; rank++){
                Card card = new Card(rank, suit);
                deck.add(card);
            }
        }
    }

    public Card[] draw(int count) {
        Card[] cards = new Card[count];
        if (count < deck.size()) {
            for(int i = 0; i < count; i++){
                cards[i] = deckObject.deck.remove(0);
            }        
        } else {
            throw new IllegalStateException("Can not with draw " + (count + 1) + " from deck that only has " + deck.size() + " cards");
        }
        return cards;
    }

In this way, you protect the internal state of the Cards while providing the ability of other objects to interact with your Deck

This also deals with the management and logic within a single place, so that it always the same...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.