【问题标题】:Making Multiple Decks of Cards Java用Java制作多副牌
【发布时间】:2013-12-30 09:43:05
【问题描述】:

编辑:我在尝试将卡添加到我的 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());
    }
    }
}

套牌类

/** 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);
        }
    }
}

【问题讨论】:

  • 我没有时间给出一个长的答案,但是创建一个 Deck 类。您可能根本不需要 Decks 类,您可以使用 List 的一个实例。

标签: java arraylist poker


【解决方案1】:

您应该能够多次循环创建卡片组的步骤。在 n 之前或在 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);
             }
        }
    }
}

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);
            }
        }
    }
}

【讨论】:

  • 只是为了澄清一下,当我这样做时,originalDecks 和 dealDecks 在每个牌组的 n 倍数内是否会有每张牌的 n 倍数?我担心这样做会导致每张卡由于某种原因被覆盖。
  • 两副牌中的每一副牌都有 n 个副本。因此,如果 n=3,则有 2H、2H、2H。
  • 在尝试将 orcard 添加到我的牌组时出现错误是否有明显的原因?
  • 错误是什么?有一件事,如果这是所有代码,那么您需要实例化卡片组。类似于:this.originalDecks = new ArrayList();
  • "ERROR: Invalid Rank: 0" 指向 'throw new PlayingCardException("Invalid rank:"+rank);'和'卡或卡 = 新卡(i,j);'和'甲板甲板=新甲板(2);'
【解决方案2】:

你走在正确的轨道上,但如果你尽可能保持面向对象,那会容易得多。

每张扑克牌都有一个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;
    }
}

现在,您可以拥有一个 Card 类,它同时代表 SuitRank。我还使用UUID 为每张卡分配一个随机的唯一 ID 值。这使得通过在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 只是Cards 集合的精美包装器,具有shuffle()drawCard() 等方法。它是自己的类而不是数组,您可以从内部封装所有管理,而不必担心跟踪“剩下哪些卡”。它使用Stack 集合来完成所有这些工作。

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();
    }
}

它会在创建时生成每种花色和等级的所有 52 张牌。它还会对它们进行洗牌(以后可以再次洗牌)。当你通过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.");
}

以及输出(随机):

Deck has 52 cards in it.
[Card  1]: Drew the Queen of Diamonds card.
[Card  2]: Drew the Eight of Clubs card.
[Card  3]: Drew the King of Clubs card.
[Card  4]: Drew the Queen of Hearts card.
[Card  5]: Drew the Four of Clubs card.
[Card  6]: Drew the Three of Diamonds card.
[Card  7]: Drew the Nine of Diamonds card.
[Card  8]: Drew the Ace of Diamonds card.
[Card  9]: Drew the Seven of Spades card.
[Card 10]: Drew the Two of Hearts card.
[Card 11]: Drew the Nine of Hearts card.
[Card 12]: Drew the Size of Clubs card.
[Card 13]: Drew the Jack of Diamonds card.
[Card 14]: Drew the Size of Hearts card.
[Card 15]: Drew the Three of Clubs card.
[Card 16]: Drew the Three of Spades card.
[Card 17]: Drew the Ten of Spades card.
[Card 18]: Drew the Jack of Hearts card.
[Card 19]: Drew the Five of Clubs card.
[Card 20]: Drew the Seven of Clubs card.
[Card 21]: Drew the Size of Diamonds card.
[Card 22]: Drew the Ten of Hearts card.
[Card 23]: Drew the Three of Hearts card.
[Card 24]: Drew the Ace of Spades card.
[Card 25]: Drew the Four of Hearts card.
[Card 26]: Drew the Eight of Diamonds card.
[Card 27]: Drew the Ace of Clubs card.
[Card 28]: Drew the Two of Clubs card.
[Card 29]: Drew the Nine of Spades card.
[Card 30]: Drew the Jack of Spades card.
[Card 31]: Drew the Ace of Hearts card.
[Card 32]: Drew the Seven of Hearts card.
[Card 33]: Drew the Five of Hearts card.
[Card 34]: Drew the Eight of Spades card.
[Card 35]: Drew the King of Hearts card.
[Card 36]: Drew the Jack of Clubs card.
[Card 37]: Drew the Size of Spades card.
[Card 38]: Drew the Five of Spades card.
[Card 39]: Drew the Five of Diamonds card.
[Card 40]: Drew the King of Diamonds card.
[Card 41]: Drew the Ten of Clubs card.
[Card 42]: Drew the Queen of Spades card.
[Card 43]: Drew the King of Spades card.
[Card 44]: Drew the Seven of Diamonds card.
[Card 45]: Drew the Four of Spades card.
[Card 46]: Drew the Queen of Clubs card.
[Card 47]: Drew the Ten of Diamonds card.
[Card 48]: Drew the Eight of Hearts card.
[Card 49]: Drew the Four of Diamonds card.
[Card 50]: Drew the Two of Diamonds card.
[Card 51]: Drew the Nine of Clubs card.
[Card 52]: Drew the Two of Spades card.
Deck is empty.

【讨论】:

    【解决方案3】:

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

    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.
        }
    }
    

    要考虑的另一件事是在您的班级卡片中使用枚举来表示 SUIT 和 RANK。

    最后,实现 Comparable 以便能够比较卡片。您可能想要创建类 Hand 并实现 Comparable 以便能够比较扑克牌。

    【讨论】:

      【解决方案4】:

      这是我的实现:

      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();
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-30
        • 1970-01-01
        • 1970-01-01
        • 2014-02-27
        • 2012-10-31
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        相关资源
        最近更新 更多