编辑:我在尝试将卡添加到我的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);
}
}
}
答案 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)
你走在正确的轨道上,但是你要尽可能地保持面向对象更容易。
每张扑克牌都有Suit
和Rank
,它们是一系列预定义值。让它们像每个枚举值一样有意义:
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
和Suit
的{{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集合的精美包装,其中包含Card
和shuffle()
等方法。它是自己的类而不是数组,你可以从内部封装所有管理,而不必担心跟踪“剩下哪些卡”。它使用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();
}
}