【问题标题】:C++ - using enums to generate a deck of cardsC++ - 使用枚举生成一副牌
【发布时间】:2019-08-31 15:29:37
【问题描述】:

我刚开始学习 C++,对头文件的概念和类的结构还是很陌生。我学习Java 2 年了,C++ 语法和一些操作有不同的行为。

我正在尝试制作一副纸牌。为了使代码更清晰,我想对卡片的花色和值使用枚举。然而,Deck 类中的问题是我有一种方法可以使用vector 用卡片填充卡片组。

我已经研究过,现在我意识到在 c++ 中你不能迭代枚举。在我看到的任何地方,人们都建议使用枚举,但避免了如果我不能遍历枚举,我怎么可能填充卡片组的问题。

我有一个 Card 头文件和类如下:

#ifndef CARD_H
#define CARD_H

class Card
{
public:
    enum Suit{ HEARTS, CLUBS, SPADES, DIAMONDS };
    enum Value{TWO ,THREE ,FOUR ,FIVE ,SIX ,SEVEN ,
                EIGHT , NINE , TEN ,ACE,KING,QUEEN,JACK};

    Card(Suit suit, Value value);
    ~Card();

    Suit GetSuit();
    void SetSuit(Suit suit);
    Value GetValue();
    void SetValue(Value value);
private:
    Suit m_cardSuit;
    short m_cardValue;
};

#endif 

#include "Card.h"


Card::Card(Suit suit,short value){
    this->m_cardSuit = suit;
    this->m_cardValue = value;
}

void Card::SetSuit(Suit suit){
    this->m_cardSuit = suit;
}

//this is needed to get enum from .h class!!
Card::Suit Card::GetSuit(){
    return m_cardSuit;
}

short Card::GetValue(){
    return m_cardValue;
}

void Card::SetValue(short value){
    this->m_cardValue = value;
}

还有一个Deck头和类如下:

#ifndef DECK_H
#define DECK_H

#include <vector>
#include "Card.h"

using namespace std;
class Deck
{
public:
    Deck();
    Card GetCard(Card& card);
    void addCard(Card& card);
    void shuffleCards();
    vector<Card> drawCards(short cardsToDraw);
    void PopulateDeck();
    ~Deck();

private:
    vector <Card>* m_pCards;
    short m_NumberOfCards;
    short m_MaximumNumberOfCards;
    Card m_card;
};
#endif

#include "Deck.h"


Deck::Deck()
{
    m_MaximumNumberOfCards = 52;
    m_NumberOfCards = 0;
    m_pCards = new vector<Card>(52);    //creates heap space for 52 cards.
    PopulateDeck();
}


Deck::~Deck()
{

}

void Deck::addCard(Card& cardToAdd){
    m_pCards->push_back(cardToAdd); //add a card to the deck. same as (*m_pCards).cardToAdd
}

void Deck::PopulateDeck(){
    for (int i = 0; i < 13; ++i)
        for (int j = 0; j < 4; ++j){
            Card card(Card::Suit.[j],Card::Value.[i]);
            m_pCards->push_back(card);
        }
}

我知道PopulateDeck() 方法中的语法不正确。但这是我要解决的问题。

是否可以创建卡片并以类似的方式将它们添加到套牌中,还是我必须走另一条路线并使用数组来代替?

【问题讨论】:

  • [OT]:直接使用std::vector &lt;Card&gt;,而不是std::vector上的指针。
  • 我不确定卡片的值,但它们是否具有所有连续值,如 JACK = 11、QUEEN = 12、KING = 13、ACE = 14 ...?否则遍历枚举将变得困难。
  • @Jarod42:不幸的是,我想学习一些内存分配,所以我为卡片制作的指针是在堆上制作卡片向量,正如我所说,如果我打算这样做错误的方式请纠正我。但我确实想把卡片放在堆上。
  • @ChirsG 是的,它们都有连续的值,这对我有帮助吗?
  • @ChirsG 抱歉,这是我的代码中的一个错误,我实际上已经删除了值分配,所以我现在的代码是 {TWO,THREE,FOUR ....ect}

标签: c++ enums


【解决方案1】:

你可以直接这样做:

void Deck::PopulateDeck(){
    for (int i = 0; i < 13; ++i) {
        for (int j = 0; j < 4; ++j){
            Card card(j, i);
            // Or Card card(Card::Suit(j), Card::Value(i))
            m_pCards->push_back(card);
        }
    }
}

或者,使用强类型:

enum class Suit{ Begin, HEARTS = Begin, CLUBS, SPADES, DIAMONDS, End };
enum class Value{
    Begin, TWO = Begin, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
    JACK, QUEEN, KING, ACE, End
};

Card::Suit& operator ++(Card::Suit& e)
{
    e = Card::Suit(int(e) + 1);
    return e;
}

Card::Value& operator ++(Card::Value& e)
{
    e = Card::Value(int(e) + 1);
    return e;
}

void Deck::PopulateDeck(){
    for (Card::Value i = Card::Value::Begin; i != Card::Value::End; ++i) {
        for (Card::Suit j = Card::Suit::Begin; j != Card::Suit::End; ++j){
            Card card(j, i);
            m_cards.push_back(card);
        }
    }
}

Demo

【讨论】:

  • 在枚举类中很好地使用了beginends! +1
  • @Jarod42 感谢您的回复!我尝试做第一个推荐,但它不允许我将它添加到向量中。这是说它与参数类型不匹配。至于第二种方法,我不完全了解您在那里做什么。他们都在一个单独的班级里吗?还是它们都存储在 Deck 类中。对不起,我对 c++ 的结构非常陌生,并且来自 java 背景。
  • 对于第一种方法,我认为您当前的代码有问题:new vector&lt;Card&gt;(52) 创建一个带有 52 张默认卡片的向量(需要您没有的卡片的默认构造函数),那不是你想要什么。你想要一个向量,(可能reserve 其大小为 52 以进行优化),然后添加 52 张特定卡片。所以m_pCards = new vector&lt;Card&gt;; 然后m_pCards-&gt;push_back(card);
  • 对于第二种方法,我为您的 enum 强制执行强类型以禁止隐式转换 enum/int(所以我必须为枚举添加 ++,而在隐式转换有帮助之前)。而为Suit 设置强类型是有意义的。对于值(取决于游戏),您可能需要一个隐式转换 int/enum,因为 Jack 可能会被视为具有其他名称的 11(因此排序您的枚举很重要)。我希望它足够清楚。
  • @Jarod42 非常感谢!非常感谢您的回复。我现在更清楚了。更加感谢那些使用 C++ 编写代码的人! Java 从未如此友好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多