【问题标题】:Deck of cards JAVA扑克牌 JAVA
【发布时间】:2013-04-11 06:26:28
【问题描述】:

我已经创建了我的牌组,可以处理每张牌和一套花色,直到没有剩余牌为止。对于我的项目,我需要将它分成 3 个类,其中包括一个驱动程序类。我首先创建了一个包含所有内容的类,所以我知道如何让它全部工作。

public class DeckOfCards2 {
  public static void main(String[] args) {
    int[] deck = new int[52];
    String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
    String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};

    // Initialize cards
    for (int i = 0; i < deck.length; i++) {
      deck[i] = i;
    }

    // Shuffle the cards
    for (int i = 0; i < deck.length; i++) {
      int index = (int)(Math.random() * deck.length);
      int temp = deck[i];
      deck[i] = deck[index];
      deck[index] = temp;
    }

    // Display the all the cards
    for (int i = 0; i < 52; i++) {
      String suit = suits[deck[i] / 13];
      String rank = ranks[deck[i] % 13];
      System.out.println( rank + " of " + suit);
    }
  }
}

现在尝试将其分成 3 个类。我的 DeckOfCards 类的所有套牌/西装变量上都出现了红色的波浪线。我不知道如何解决它。

public class DeckOfCards {
  private Card theCard;
  private int remainingCards = 52;

  DeckOfCards() {
    theCard = new Card();   
  }

  public void shuffle(){
    for (int i = 0; i < deck.length; i++) {
       int index = (int)(Math.random() deck.length);
       int temp = deck[i];
       deck[i] = deck[index];
       deck[index] = temp;
       remainingCards--;
     }
  }

  public void deal(){
    for (int i = 0; i < 52; i++) {
       String suit = suits[deck[i] / 13];
       String rank = ranks[deck[i] % 13];
       System.out.println( rank + " of " + suit);
       System.out.println("Remaining cards: " + remainingCards);
     }
   }
}

卡类:

public class Card {
  int[] deck = new int[52];
  String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
  String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};

  Card() {
    for (int i = 0; i < deck.length; i++) {
      deck[i] = i;
    }
  }
}

经销商类

public class Dealer {
  public static void main(String[]args){
    System.out.println("The deck will randomly print out a card from a full deck each time");

    DeckOfCards player = new DeckOfCards();
    player.deal();
  }
}

【问题讨论】:

  • 你能包括你得到的错误吗?
  • DeckOfCards 中没有任何数组,这对于修复那些讨厌的红色曲线可能是一个好的开始。在您的卡片实例化中也没有任何逻辑可以保证我得到一张独特的卡片(或实际花色和等级的卡片),但这不会引起曲线。
  • 我没有收到错误。我的 DeckOfCards 课程中的套牌和套装下面都有红色的波浪线。当我将鼠标悬停在它上面时,它说“甲板无法解析为变量”
  • @Makoto 我如何让这些数组出现在我的班级中,因为它们在 Card 班级中?
  • 将它们移出...?无论如何,它们不属于Card - 为什么卡片要关心它的牌组?

标签: java


【解决方案1】:

正如其他人已经说过的,您的设计不是很清晰且面向对象。

最明显的错误是在你的设计中一张卡片知道一副卡片。 Deck 应该知道卡片并在其构造函数中实例化对象。例如:

public class DeckOfCards {
    private Card cards[];

    public DeckOfCards() {
        this.cards = new Card[52];
        for (int i = 0; i < ; i++) {
            Card card = new Card(...); //Instantiate a Card
            this.cards[i] = card; //Adding card to the Deck
        }
     }

之后,如果您愿意,您还可以扩展 Deck 以构建不同的卡片组(例如超过 52 张卡片、Jolly 等)。例如:

public class SpecialDeck extends DeckOfCards {
   ....

我要改变的另一件事是使用字符串数组来表示花色和等级。从 Java 1.5 开始,该语言支持枚举,非常适合此类问题。例如:

public enum Suits {
    SPADES, 
    HEARTS, 
    DIAMONDS,
    CLUBS;  
}

使用 Enum,您可以获得一些好处,例如:

1) Enum 是类型安全的,除了预定义的 Enum 常量之外,您不能将任何其他内容分配给 Enum 变量。例如,您可以编写 Card 的构造函数如下:

public class Card {

   private Suits suit;
   private Ranks rank;

public Card(Suits suit, Ranks rank) {
    this.suit = suit;
    this.rank = rank;
}

通过这种方式,您可以确保构建只接受枚举值的一致卡片。

2) 您可以在 Java 中的 Switch 语句中使用 Enum,如 int 或 char 原始数据类型(这里我们不得不说,因为 Java 1.7 也允许在 String 上使用 switch 语句)

3) 在 Java 中的 Enum 上添加新常量很容易,您可以在不破坏现有代码的情况下添加新常量。

4) 您可以遍历枚举,这在实例化卡片时非常有用。例如:

/* Creating all possible cards... */
for (Suits s : Suits.values()) {
    for (Ranks r : Ranks.values()) {
         Card c = new Card(s,r);
    }  
}

为了不再次发明轮子,我还将更改将卡片从数组保存为 Java 集合的方式,这样您就可以在您的牌组上使用许多强大的方法,但最重要的是您可以使用Java Collection's shuffle function 洗牌。例如:

private List<Card> cards = new ArrayList<Card>();

//Building the Deck...

//...

public void shuffle() {
    Collections.shuffle(this.cards); 
}

【讨论】:

    【解决方案2】:

    这是我的实现:

    public class CardsDeck {
        private ArrayList<Card> mCards;
        private ArrayList<Card> mPulledCards;
        private Random mRandom;
    
    public enum Suit {
        SPADES,
        HEARTS,
        DIAMONDS,
        CLUBS;
    }
    
    public 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();
    }
    }
    

    【讨论】:

      【解决方案3】:

      这是一些代码。它使用 2 个类(Card.java 和 Deck.java)来完成这个问题,最重要的是,它会在您创建卡片组对象时自动为您排序。 :)

      import java.util.*;
      
      public class deck2 {
          ArrayList<Card> cards = new ArrayList<Card>();
      
          String[] values = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
          String[] suit = {"Club", "Spade", "Diamond", "Heart"};
      
          static boolean firstThread = true;
          public deck2(){
              for (int i = 0; i<suit.length; i++) {
                  for(int j=0; j<values.length; j++){
                      this.cards.add(new Card(suit[i],values[j]));
                  }
              }
              //shuffle the deck when its created
              Collections.shuffle(this.cards);
      
          }
      
          public ArrayList<Card> getDeck(){
              return cards;
          }
      
          public static void main(String[] args){
              deck2 deck = new deck2();
      
              //print out the deck.
              System.out.println(deck.getDeck());
          }
      
      }
      
      
      //separate class
      
      public class Card {
      
      
          private String suit;
          private String value;
      
      
          public Card(String suit, String value){
              this.suit = suit;
              this.value = value;
          }
          public Card(){}
          public String getSuit(){
              return suit;
          }
          public void setSuit(String suit){
              this.suit = suit;
          }
          public String getValue(){
              return value;
          }
          public void setValue(String value){
              this.value = value;
          }
      
          public String toString(){
              return "\n"+value + " of "+ suit;
          }
      }
      

      【讨论】:

        【解决方案4】:

        生成卡片的非常简单的代码:

        class Card{
                
            private final String suit;
            private final String rank;
            
            
            public Card(String suit, String rank){
                this.suit = suit;
                this.rank = rank;
            }       
            
            @Override
            public String toString() {
                return "Card [suit=" + suit + ", rank=" + rank + "]";
            }
            
        }
        
        class DeckOfCard{
            
            private static final String suits[] = {"club", "diamond", "heart", "spade"};
            private static final String ranks[] = {null,"ace", "deuce", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "jack", "queen", "king"};
            private final ArrayList<Card> cards;
            
            public DeckOfCard(){
                cards = new ArrayList<Card>();
                for (int i = 0; i<suits.length; i++) {
                    for(int j=0; j<ranks.length; j++){
                        this.cards.add(new Card(suits[i],ranks[j]));
                    }
                }   
                //Shuffle after the creation
                Collections.shuffle(this.cards);
                
            }
        
            public ArrayList<Card> getCards() {
                return cards;
            }
        
        
        }
        public class CardPuzzle {
        
            public static void main(String[] args) {
        
                DeckOfCard deck = new DeckOfCard();     
                ArrayList<Card> cards = deck.getCards();        
                for(Card card:cards){
                    System.out.println(card);
                }
                
            }
        
        }
        

        【讨论】:

          【解决方案5】:

          您的设计有问题。试着让你的课程代表真实世界的事物。例如:

          • 类卡应该代表一张卡,这是“卡”的性质。 Card 类不需要了解 Decks。
          • Deck 类应该包含 52 个 Card 对象(加上小丑?)。

          【讨论】:

          • 我明白你的意思。如果我要将 Deck[] 移动到 DeckOfCards 类,我将如何将其放入其中以制作 52 张卡片?
          • @Chris A DeckOfCards 应该制作 52 张卡片。卡片不应该知道 DeckOfCards 是什么。
          • @Chris:Luigi 写了一个清晰的例子来说明如何将卡片放入牌组。
          【解决方案6】:

          首先,您的课程存在架构问题。您将属性 deck 移动到班级 Card 中。但当然,它是卡片组的属性,因此必须在 DeckOfCards 类内。初始化循环不应该在Card 的构造函数中,而是在你的甲板类中。此外,当前牌组是int 的数组,但应该是Cards 的数组。

          其次,在方法@​​987654327@ 内部,您应该将suits 引用为Card.suits 并使该成员静态最终。 ranks 也一样。

          最后,请遵守命名约定。方法名称总是以小写字母开头,即shuffle 而不是Shuffle

          【讨论】:

          • 我会在我的卡片类中放什么?
          • 你不必这样做,但是一旦你的类 Card 代表一张特定的卡片,你就可以在这个类中移动用于命名卡片的代码。
          • 这就是我正在努力解决的问题,我不知道如何在我的 Card 类中分配特定的卡。我将 for 循环从 Card() 移到了 DeckOfCards()
          【解决方案7】:

          您的代码中有很多错误,例如,您并没有真正通过在Shuffle 方法中键入deck 来调用您的套牌。你只能通过输入theCard.deck来调用它

          我改变了你的随机播放方法:

          public void Shuffle(){
              for (int i = 0; i < theCard.deck.length; i++) {
                  int index = (int)(Math.random()*theCard.deck.length );
                  int temp = theCard.deck[i];
                  theCard.deck[i] = theCard.deck[index];
                  theCard.deck[index] = temp;
                  remainingCards--;
              }
          }
          

          另外,据说你有结构问题。你应该按照你在现实生活中的理解来命名类,例如,当你说卡片时,它只是一张卡片,当你说甲板时,它应该是 52+2 卡片。这样你的代码会更容易理解。

          【讨论】:

            【解决方案8】:

            你的程序有很多错误。

            1. 指数计算。我觉得应该是Math.random()%deck.length

            2. 在卡片显示中。根据我的说法,您应该制作一个具有等级套装的卡片类别并制作该类别类型的数组

            如果你愿意,我可以给你完整的结构,但你自己做会更好

            【讨论】:

              【解决方案9】:

              我认为解决方案就这么简单:

              Card temp = deck[cardAindex];
              deck[cardAIndex]=deck[cardBIndex]; 
              deck[cardBIndex]=temp;
              

              【讨论】:

                【解决方案10】:
                public class shuffleCards{
                
                    public static void main(String[] args) {
                
                        String[] cardsType ={"club","spade","heart","diamond"};
                        String [] cardValue = {"Ace","2","3","4","5","6","7","8","9","10","King", "Queen", "Jack" };
                
                        List<String> cards = new ArrayList<String>();
                        for(int i=0;i<=(cardsType.length)-1;i++){
                            for(int j=0;j<=(cardValue.length)-1;j++){
                                cards.add(cardsType[i] + " " + "of" + " " + cardValue[j]) ;
                            }
                        }
                
                        Collections.shuffle(cards);
                        System.out.print("Enter the number of cards within:" + cards.size() + " = ");
                
                        Scanner data = new Scanner(System.in);
                        Integer inputString = data.nextInt();
                        for(int l=0;l<= inputString -1;l++){
                            System.out.print( cards.get(l)) ;
                        }    
                    }
                }
                

                【讨论】:

                  【解决方案11】:
                  import java.util.List;
                  import java.util.ArrayList;
                  import static java.lang.System.out;
                  import lombok.Setter;
                  import lombok.Getter;
                  import java.awt.Color;
                  
                  
                  public class Deck {
                  
                  private static @Getter List<Card> deck = null;
                  
                  final int SUIT_COUNT = 4;
                  final int VALUE_COUNT = 13;
                  
                  public Deck() {
                      deck = new ArrayList<>();
                      Card card = null;
                      int suitIndex = 0, valueIndex = 0;
                      while (suitIndex < SUIT_COUNT) {
                          while (valueIndex < VALUE_COUNT) {
                              card = new Card(Suit.values()[suitIndex], FaceValue.values()[valueIndex]);
                              valueIndex++;
                              deck.add(card);
                          }
                          valueIndex = 0;
                          suitIndex++;
                      }
                  }
                  
                  private enum Suit{CLUBS("Clubs", Color.BLACK), DIAMONDS("Diamonds", Color.RED),HEARTS("Hearts", Color.RED), SPADES("Spades", Color.BLACK);
                  
                      private @Getter String name = null;
                      private @Getter Color color = null;
                  
                      Suit(String name) {
                          this.name = name;
                      }
                  
                      Suit(String name, Color color) {
                          this.name = name;
                          this.color = color;
                      }
                  }
                  
                  private enum FaceValue{ACE(1), TWO(2), THREE(3),
                      FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT (8), NINE(9), TEN(10),
                      JACK(11), QUEEN(12), KING(13);
                  
                      private @Getter int cardValue = 0;
                  
                      FaceValue(int value) {
                          this.cardValue = value;
                      }
                  }
                  
                  private class Card {
                  
                      private @Getter @Setter Suit suit = null;
                  
                      private @Getter @Setter FaceValue faceValue = null;
                  
                      Card(Suit suit, FaceValue value) {
                          this.suit = suit;
                          this.faceValue = value;
                      }
                  
                      public String toString() {
                          return getSuit() + " " + getFaceValue();
                      }
                  
                      public String properties() {
                          return getSuit().getName() + " " + getFaceValue().getCardValue();
                      }
                  
                  }
                  
                  public static void main(String...inputs) {
                      Deck deck = new Deck();
                      List<Card> cards = deck.getDeck();
                      cards.stream().filter(card -> card.getSuit().getColor() != Color.RED && card.getFaceValue().getCardValue() > 4).map(card -> card.toString() + " " + card.properties()).forEach(out::println);   
                  }
                  

                  }

                  【讨论】:

                  • 这是纸牌本身的类。任何处理套牌的方法都将由 Dealer 类完成。例如,洗牌、发牌给玩家等等。前段时间我和公司谈过。这是“白板”练习之一,即有人给我看了一副纸牌,然后说用 Java 代码用它做点什么。会议上我的大脑或多或少有些空白,但我大约一天前又想了一遍,然后想出了这个作为解决方案。
                  猜你喜欢
                  • 2011-07-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-04-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-02-23
                  • 1970-01-01
                  相关资源
                  最近更新 更多