制作多副卡片Java

时间:2013-12-12 05:27:24

标签: java arraylist poker

编辑:我在尝试将卡添加到我的originalDecks和dealDecks时收到错误。

我想我已经想出了如何创建一副卡片[在方法Decks()中显示],但我的问题是我必须创建多副卡片[n层数= n * 52数的卡]。我无法弄清楚如何利用n来制作同一张卡的倍数。在创建了多个套牌后,我想我可以找出shuffle()和reset(),但是获得多个套牌现在给我带来了问题。

注意:我正在考虑创建一个n层甲板阵列,但我甚至不知道如何启动它。

卡类

/** class Card : for creating playing card objects
 *  it is an immutable class.
 *  Rank - valid values are 1 to 13
 *  Suit - valid values are 0 to 3
 *  Do not modify this class!
 */
class Card {

/* constant suits and ranks */
static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades" };
static final String[] Rank = {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};

/* Data field of a card: rank and suit */
private int cardRank;  /* values: 1-13 (see Rank[] above) */
private int cardSuit;  /* values: 0-3  (see Suit[] above) */

/* Constructor to create a card */
/* throw PlayingCardException if rank or suit is invalid */
public Card(int rank, int suit) throws PlayingCardException { 
if ((rank < 1) || (rank > 13))
    throw new PlayingCardException("Invalid rank:"+rank);
else
        cardRank = rank;
if ((suit < 0) || (suit > 3))
    throw new PlayingCardException("Invalid suit:"+suit);
else
        cardSuit = suit;
}

/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() { return cardRank; }
public int getSuit() { return cardSuit; }
public String toString() { return Rank[cardRank] + " " + Suit[cardSuit]; }


/* Few quick tests here */
public static void main(String args[])
{
try 
        {
        Card c1 = new Card(1,3);    // A Spades
        System.out.println(c1);
        c1 = new Card(10,0);    // 10 Clubs
        System.out.println(c1);
        //c1 = new Card(10,5);        // generate exception here
    }
catch (PlayingCardException e)
    {
        System.out.println("PlayingCardException: "+e.getMessage());
    }
    }
}

Decks Class

/** class Decks represents : n decks of playing cards
 *  Use class Card to construct n * 52 playing cards!
 *
 *  Do not add new data fields!
 *  Do not modify any methods
 *  You may add private methods 
 */

class Decks {

/* this is used to keep track of original n*52 cards */
private List<Card> originalDecks;   

/* this starts with n*52 cards deck from original deck   */
/* it is used to keep track of remaining cards to deal */
/* see reset(): it resets dealDecks to a full deck      */
private List<Card> dealDecks;

/* number of decks in this object */
private int numberDecks;


/**
 * Constructor: Creates default one deck of 52 playing cards in originalDecks and
 *          copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 * @throws PlayingCardException 
 */
public Decks() throws PlayingCardException
{
    // implement this method!
    int i, j;
    for (i=0;i<4;i++) 
    {
        for(j=1;j<14;j++) 
        {
            Card orcard = new Card(i,j);
            originalDecks.add(orcard);
            dealDecks.add(orcard);
        }
    }

}


/**
 * Constructor: Creates n decks (52 cards each deck) of playing cards in
 *              originalDecks and copy them to dealDecks.
 *              initialize numberDecks=n
 * Note: You need to catch PlayingCardException from Card constructor
 *       Use ArrayList for both originalDecks & dealDecks
 * @throws PlayingCardException 
 */
public Decks(int n) throws PlayingCardException
{
    // implement this method!
    int i, j;
    for (i=0;i<4;i++) 
    {
        for(j=1;j<14;j++) 
        {
            Card orcard = new Card(i,j);
            originalDecks.add(orcard);
            dealDecks.add(orcard);
        }
    }
}

4 个答案:

答案 0 :(得分:2)

您应该能够循环完成多次创建卡片组的步骤。在for循环之前或之中添加另一个循环。

public Decks(int n) throws PlayingCardException
{
    // implement this method!
    int i, j;
    for (i=0;i<4;i++) 
    {
        for(j=1;j<14;j++) 
        {
            for(k=0;k<n;k++){
                Card orcard = new Card(i,j);
                originalDecks.add(orcard);
                dealDecks.add(orcard);
             }
        }
    }
}

OR

public Decks(int n) throws PlayingCardException
{
    // implement this method!
    int i, j;
    for(int k=0;k<n;k++){
        for (i=0;i<4;i++) 
        {
            for(j=1;j<14;j++) 
            {
                Card orcard = new Card(i,j);
                originalDecks.add(orcard);
                dealDecks.add(orcard);
            }
        }
    }
}

答案 1 :(得分:1)

你走在正确的轨道上,但是你要尽可能地保持面向对象更容易。

每张扑克牌都有SuitRank,它们是一系列预定义值。让它们像每个枚举值一样有意义:

public enum PlayingCardSuit
{
    None(0),
    Spades(1),
    Diamonds(2),
    Hearts(3),
    Clubs(4);

    private int suit;

    private PlayingCardSuit(int suit)
    {
        this.suit = suit;
    }
}

public enum PlayingCardRank
{
    None(0),
    Ace(1),
    Two(2),
    Three(3),
    Four(4),
    Five(5),
    Size(6),
    Seven(7),
    Eight(8),
    Nine(9),
    Ten(10),
    Jack(11),
    Queen(12),
    King(13);

    private int rank;

    private PlayingCardRank(int rank)
    {
        this.rank = rank;
    }
}

现在,您可以拥有一个代表CardSuit的{​​{1}}类。我还使用Rank为每张卡分配一个随机的唯一ID值。这使得通过对UUID进行排序而不是进行一些复杂的排序来更容易地对它们进行洗牌。

这是UUID类:

PlayingCard

现在,import java.util.*; public final class PlayingCard { private UUID id; private PlayingCardSuit suit; private PlayingCardRank rank; public PlayingCard(PlayingCardSuit suit, PlayingCardRank rank) { this.id = UUID.randomUUID(); this.suit = suit; this.rank = rank; } public UUID id() { return this.id; } public void setId(UUID id) { this.id = id; } public PlayingCardSuit suit() { return this.suit; } public PlayingCardRank rank() { return this.rank; } public String toString() { return String.format("%s of %s", this.rank, this.suit); } } 仅仅是Deck s集合的精美包装,其中包含Cardshuffle()等方法。它是自己的类而不是数组,你可以从内部封装所有管理,而不必担心跟踪“剩下哪些卡”。它使用drawCard()集合完成所有这些。

Stack

创建时,它将生成每个套装的所有52张牌和等级。它也会将它们洗牌(之后可以再次洗牌)。当您通过import java.util.*; public final class PlayingCardDeck { private Stack<PlayingCard> deck; public PlayingCardDeck() { initializeDeck(); shuffle(); } private void initializeDeck() { deck = new Stack<PlayingCard>(); for(final PlayingCardSuit suit : EnumSet.allOf(PlayingCardSuit.class)) { // Skip the 'None' suit. if(suit == PlayingCardSuit.None) continue; for(final PlayingCardRank rank : EnumSet.allOf(PlayingCardRank.class)) { // Skip the 'None' rank card. if(rank == PlayingCardRank.None) continue; PlayingCard card = new PlayingCard(suit, rank); deck.push(card); } } } public int size() { return deck.size(); } public void shuffle() { // Generate new UUIDs to randomize. for(final PlayingCard card : deck) card.setId(UUID.randomUUID()); // Sort the deck based on the card UUID for randomization. Collections.sort(deck, new Comparator<PlayingCard>() { public int compare(PlayingCard a, PlayingCard b) { UUID aID = a.id(); UUID bID = b.id(); return aID.compareTo(bID); } }); } public PlayingCard drawCard() { return deck.pop(); } } 绘制卡片时,它会从卡片顶部取出卡片。

这可能看起来有点矫枉过正,但它是一种非常有组织的方法,当多个套牌发挥作用时,它会让你的生活变得更轻松。

这是我测试的小驱动程序类:

drawCard()

输出(随机):

public static void main(String[] args) 
{
    Untitled program = new Untitled();
    program.run();  
}

public void run()
{
    PlayingCardDeck deck = new PlayingCardDeck();

    System.out.println(String.format("Deck has %d cards in it.", deck.size()));

    int i = 0;
    while(deck.size() > 0)
    {
        PlayingCard card = deck.drawCard();
        System.out.println(String.format("[Card %2d]: Drew the %s card.", (++i), card.toString()));
    }

    System.out.println("Deck is empty.");
}

答案 2 :(得分:0)

如果您只想要一副牌,您知道每张牌都有52张牌。那么为什么不在Deck类中创建一个多达52个的卡数组呢?

public class Deck {
    private Card[] cards;
    private int dealIndex; // position of next card to deal

    public Deck(int n) { // n number of decks
        cards = new Card[52*n];
        dealIndex = 0;
        // Initialize cards here by creating instances of cards.
        // Maybe write a function to initialize 1 deck of cards and call this n times with appropriate index to cards array.
    }
}

要考虑的另一件事是使用您的类卡中的Enumeration来表示SUIT和RANK。

最后,实施Comparable以便能够比较卡片。您可能希望创建类Hand并同时实现Comparable以便能够比较扑克手。

答案 3 :(得分:0)

这是我的实施:

public class CardsDeck {
    private ArrayList<Card> mCards;
    private ArrayList<Card> mPulledCards;
    private Random mRandom;

public static enum Suit {
    SPADES,
    HEARTS,
    DIAMONDS,
    CLUBS;
}

public static enum Rank {
    TWO,
    THREE,
    FOUR,
    FIVE,
    SIX,
    SEVEN,
    EIGHT,
    NINE,
    TEN,
    JACK,
    QUEEN,
    KING,
    ACE;
}

public CardsDeck() {
    mRandom = new Random();
    mPulledCards = new ArrayList<Card>();
    mCards = new ArrayList<Card>(Suit.values().length * Rank.values().length);
    reset();
}

public void reset() {
    mPulledCards.clear();
    mCards.clear();
    /* Creating all possible cards... */
    for (Suit s : Suit.values()) {
        for (Rank r : Rank.values()) {
            Card c = new Card(s, r);
            mCards.add(c);
        }
    }
}


public static class Card {

    private Suit mSuit;
    private Rank mRank;

    public Card(Suit suit, Rank rank) {
        this.mSuit = suit;
        this.mRank = rank;
    }

    public Suit getSuit() {
        return mSuit;
    }

    public Rank getRank() {
        return mRank;
    }

    public int getValue() {
        return mRank.ordinal() + 2;
    }

    @Override
    public boolean equals(Object o) {
        return (o != null && o instanceof Card && ((Card) o).mRank == mRank && ((Card) o).mSuit == mSuit);
    }


}

/**
 * get a random card, removing it from the pack
 * @return
 */
public Card pullRandom() {
    if (mCards.isEmpty())
        return null;

    Card res = mCards.remove(randInt(0, mCards.size() - 1));
    if (res != null)
        mPulledCards.add(res);
    return res;
}

/**
 * Get a random cards, leaves it inside the pack 
 * @return
 */
public Card getRandom() {
    if (mCards.isEmpty())
        return null;

    Card res = mCards.get(randInt(0, mCards.size() - 1));
    return res;
}

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public int randInt(int min, int max) {
    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = mRandom.nextInt((max - min) + 1) + min;
    return randomNum;
}


public boolean isEmpty(){
    return mCards.isEmpty();
}
}