概念性难度c ++卡片组

时间:2016-06-30 15:44:00

标签: c++ oop

我知道有很多关于这个永恒实现的问题,但作为一个新的OOP程序员,我正努力掌握必要的概念,以便做出任何理由。

我是否在阵列中构建一个实际的随机甲板,可以作为任何纸牌游戏的扑克牌?或者我是"复制"一个随机的纸牌套牌,创造4套西装,然后是13个不同的面孔?我已经看过多次实施,而且我不太了解他们会得到什么。 int deck[];是我计划存储卡片的地方。当创建卡片组类的实例时,我会填充该套牌阵列吗?

我的主要只是调用了打印功能(我还没写过)

//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_ */

4 个答案:

答案 0 :(得分:2)

好吧,拥有Card classstructDeckOfCards类充当专用容器是正确的方法(如{{{ 3}}):

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在特定游戏中的行为方式可能会完全委托给@Thomas' answer类。

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

class DeckOfCards {
     DeckOfCards() : cards_({
         { Diamonds, Two } ,
         // ...
         { Diamonds, Ace } ,
         { Hearts, Two } ,
         // ...
         { Hearts, Ace } ,
         { Spades, Two } ,
         // ...
         { Spades, Ace } , Strategy Pattern
         { 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%确定您希望通过currentCard中的DeckOfCards成员实现目标,但我认为您不会成为偏移到下一个Card分发DeckOfCards,以便您可以简单地将其用作cards_数组的索引,以分发对基础Card的引用实例,然后增加它:

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

去寻找复活节彩蛋

答案 1 :(得分:1)

我之前已经回答了这些问题,所以我会再次这样做。

恕我直言,有两个对象:卡片的容器和卡片。不要混合它们。

让我们从卡片开始。一张卡片有西装和价值:

struct Card
{
  Suit_Type suit;
  Value_Type value;
};

容器可以是任何内容,例如std::vectorstd::list或我最喜欢的std::deque。 ; - )

typedef std::vector<Card> Deck_Of_Cards;

您可以制作自己的容器,但对于大多数使用卡片的作业,没有必要。首选现有的容器数据结构。

Card结构中的类型而言,是一个偏好问题。您可以为Suit_Type使用枚举,字符串或其他内容。与Value_Type类似。

为了使卡更有用,您应该在Card结构中实现以下方法:

  1. 构造函数,赋值运算符,析构函数。
  2. 等同和排序运算符(例如==,和&lt;)
  3. 流插入和提取(例如&gt;&gt;和&lt;&lt;&lt;&lt;&lt;&lt;&lt;)
  4. 另请查看函数std::random_shuffle

答案 2 :(得分:0)

好吧,只是为了让它变得非常清晰,你的甲板课将成为一个容器&#39;类。这意味着它将持有一堆卡片卡;不是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[];

};

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

注意:向量比原始数组更可取,但不要删除DeckOfCards类,因为如果你这样做,那么你在哪里存储shuffledeck函数或printdeck函数?等...而只是用向量替换成员数组。

答案 3 :(得分:0)

这实际上取决于你想要用你的卡片,你想要如何使用它。在某些情况下,简单的int[]将完全满足您的需求。在其他情况下,您将需要完整的卡片组和甲板类以及其他辅助类。在其他答案中给出的卡片和卡片实现(不知不觉地?)专门用于某些纸牌游戏,而对其他人来说完全无法使用。不要问你能拥有什么,问问自己你需要什么。 Do the simplest thing that could possibly work.

(实际上这个问题太广泛/基于意见,可能在programmers.stackexchange.com上有更多内容)