概念难度c++牌组

Conceptual Difficulty c++ Deck of Cards

本文关键字:c++ 牌组      更新时间:2023-10-16

我知道关于这个永恒的实现有很多问题,但是作为一个新的OOP程序员,我正在努力掌握必要的概念来取得任何基础。

我是否在一个数组中构建一个实际的随机牌组,作为任何纸牌游戏的纸牌牌组?或者我是否通过创造4种花色和13种不同的花色来"复制"随机纸牌组?我见过很多实现,但我不太明白它们在说什么。int deck[];是我打算存放卡片的地方。当deck of cards类的实例被创建时,我要填充这个deck数组吗?

我的main函数只调用了print函数(我还没有写)

//Texas holdem build
//Will attempt using Classes and inheritance
//Full build for up to 6 players
#include <iostream>
#include "deckOfCards.h"
int main()
{
    DeckOfCards deck;
    deck.printDeck();
    return(0);
}

* deckOfCards.h
 *
 *  Created on: Jun 28, 2016
 *      Author: TAmend
 */
#ifndef DECKOFCARDS_H_
#define DECKOFCARDS_H_
class DeckOfCards
{
    public:
        DeckOfCards();
        void printDeck() const;
        void shuffle();
    private:
        int currentCard;
        int deck[];
};
#endif /* DECKOFCARDS_H_ */

嗯,有一个Card classstruct和一个DeckOfCards类,作为一个专门的容器是正确的方式去(正如在@托马斯的回答中提到的):

struct Card
{
  enum Suit_Type {
      Diamonds,
      Hearts,
      Spades,
      Clubs,
  } suit;
  enum Value_Type {
      Two = 2, // <<<<<<<<< Note starts at 2
      Three ,
      // Four, Five, Six, aso. ...
      Ten ,
      Jack ,
      Queen ,
      King ,
      Ace , // <<<<<<<<< Note has the highest value here
  } value;
  void printCard();
};

 void Card::printCard() {
      switch(suit) {
      case Hearts:
          std::cout << "♥";
          break;
      case Diamonds:
          std::cout << "♦";
          break;
      case Clubs:
          std::cout << "♣";
          break;
      case Spades:
          std::cout << "♠";
          break;
      }
      if(value < Jack) {
         std::cout << (int)value;
      }
      else {
          switch(value) {
          case Jack:
              std::cout << 'J';
              break;
          case Queen:
              std::cout << 'Q';
              break;
          case King:
              std::cout << 'K';
              break;
          case Ace:
              std::cout << 'A';
              break;
          }
      }
  }

也提到过,应该有一些比较运算符在Card上实现,使游戏玩法的实现更容易:

  bool operator<(const Card& lhs, const Card& rhs) {
       return (lhs.suite < rhs.suite) &&
              (lhs.value < rhs.value);
  }
  bool operator>(const Card& lhs, const Card& rhs) {
       return (lhs.suite > rhs.suite) &&
              (lhs.value > rhs.value);
  }

请注意,从语义的角度来看,实现相等性测试没有多大意义,除非您想同时使用多个DeckOfCards

Cards在特定游戏中的表现,可能完全委托给策略模式类。


DeckOfCards可以从适当的初始化列表中初始化:

class DeckOfCards {
     DeckOfCards() : cards_({
         { Diamonds, Two } ,
         // ...
         { Diamonds, Ace } ,
         { Hearts, Two } ,
         // ...
         { Hearts, Ace } ,
         { Spades, Two } ,
         // ...
{黑桃,a},//!!非常重要!!之前
         { Clubs, Two } ,
         // ...
         { Clubs, Ace } ,
     }) {}
     void printDeck();
     void shuffle();
private:
     std::array<Card,52> cards_;
};

其他函数可以很容易地实现:

void DeckOfCards::printDeck() {
    bool first = true;
    for(auto card : cards_) {
         if(!first) {
             std::cout << ", ";
         }
         card.printCard();
         first = false;
    }
    std::cout << std::endl;
}
void DeckOfCards::shuffle() {
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(cards_.begin(), cards_.end(), g);
};

我不是100%确定你想在DeckOfCards中使用currentCard成员实现什么,但我假设你不想从DeckOfCards中得到下一个Card的偏移量,所以你可以简单地将它用作cards_数组的索引,分发对底层Card实例的引用,并在之后增加它:

 const Card& getNextCard(bool& cardsAvailable) {
      cardsAvailable = true;
      if(currentCard < 52) {
          return cards_[currentCard++];
      }
      // Reset the deck
      cardsAvailable = false;
      currentCard = 0;
      shuffle();
 }

去找彩蛋

我以前已经回答过这些问题,所以我将再次回答。

恕我直言,这里有两个对象:一个卡片容器和一张卡片。不要把它们混在一起。

让我们从一张卡片开始。一张牌有花色和值:

struct Card
{
  Suit_Type suit;
  Value_Type value;
};

容器可以是任何东西,比如std::vector, std::list,或者我最喜欢的std::deque。: -)

typedef std::vector<Card> Deck_Of_Cards;

您可以创建自己的容器,但对于大多数使用卡片的赋值,没有必要这样做。首选现有的容器数据结构。

Card结构体内部的类型而言,这是一个首选问题。您可以使用enum, string或任何Suit_Type。与Value_Type类似。

为了使Cards更易于使用,您应该在Card结构体中实现以下方法:

    构造函数、赋值操作符、析构函数。
  1. 相等和排序操作符(例如==和<)
  2. 流插入和提取(例如>>和<<)

还要看函数std::random_shuffle

好了,为了让它非常清楚,你的deck类将作为一个'container'类。这意味着它将持有一堆card类型的纸牌;不是int。

最后,用来存储卡片的数组看起来像这样卡片组[];而不是int deck[];这将允许您为每个单独的卡添加任何属性。

您可以在构建时或之前随机化Card类的每个属性,并将随机值传入。

为了帮助你理解:

class Card
{
public:
    Card(int value): value(value) {}
    int Getvalue(){ return value; }
private:
    int value;
};

class DeckOfCards
{
public:
 //   DeckOfCards();
 //   void printDeck() const;
  //  void shuffle();
    void createDeck()
    {
        for(int i = 0; i < deck_size; i++)    //Implementation of createDeck
            deck[i] = new Card(rand()%10-1);//whatever val you want to generate
    }
private:
 //   int currentCard;
  //  Card deck[];
};

通过这种方式,你可以随时抓取卡片,并添加任何你想要的属性,例如suit。

注意:vector比原始数组更可取,但不要删除DeckOfCards类,因为如果你这样做,那么你的shuffledeck函数或printdeck函数存储在哪里?等等……相反,只需将成员数组替换为vector即可。

这真的取决于你想用你的牌来达到什么目的,你想如何使用它。在某些情况下,简单的int[]将完全满足您的需求。在其他情况下,您将需要完整的卡牌和牌组类以及其他助手类。其他答案中给出的卡片和牌组实现(无意中)是专门针对某些卡片游戏的,而对于其他游戏则完全不可用。不要问你能拥有什么,问问你自己需要什么。做最简单可行的事。

(真的这个问题太广泛了/基于意见,可能更适合在programmers.stackexchange.com上)