我正在设计一款扑克游戏。 PokerHand课程将为用户提供卡片(总是5张卡片)。 PokerHand有不同的类别,例如Straight,Flush,Full House等。
现在我希望所有PokerHand都具有可比性。类别之间有一个明确的顺序:直接冲洗&gt; <4种>满屋子&gt; ...对于每个类别,都有一个不同的比较规则。例如。对于Straights,高牌决定。对于“4种类型”,4张相同的牌决定。
class PokerHand {
public:
int CompareTo(const PokerHand* another) = 0;
Category GetCagegory();
...
}
使用RTTI,我可以将CompareTo实现为
class Straight : public PokerHand {
...
}
int Straight::CompareTo(const PokerHand& another) OVERRIDE {
const Straight* s = dynamic_cast<const Straight*>(another);
if (s == NULL) {
// Not a straight. Compare category.
...
} else {
// compare high card
...
}
}
现在我的问题是,考虑到RTTI主要被视为“不建议使用”,有没有一种很好的方法来实现比较而不使用RTTI?
答案 0 :(得分:2)
我很确定你这样做的方式是错误的。
PokerHand
是PokerHand
,无论是持有满屋,同花顺还是一套完全无用的牌。 [你可能会发现你需要有几种,如果你玩扑克牌有五张牌,七张牌,或者显示或不显示你的牌等等 - 但是为了评估你的牌“值得”,你需要一个类]。
您需要的是一个可以告诉您实际拥有的功能。为此,我假设你有struct Card
,其中包含以下内容:
struct Card
{
int suite; (1..4)
int value; (2..14)
};
然后我假设我们正在玩5张牌,如果你正在玩可变数量的牌,那么你可能想要使用矢量。
class PokerHand
{
...
Card cards[5];
}
int PokerHand::value()
// return 0 for "useless, nothing", otherwise how good -> better is higher
{
int ret = 0;
... check if they are the same suite (flush)
... if so, are they in sequence (straight flush)
... if so, is the highest a king - (royal straight flush)
return ret;
else
... here we write code to check how many cards have the same value
(2, 3, 4 of a kind or full house)
if at least two same value:
return ret;
return ret;
}
如果您按照套件或按值分别对这两个步骤进行排序,您可能会发现编写此函数更容易。您需要考虑卡的价值,例如3 aces beats 3 kings beats 3 queens等。你还必须处理“等值,更好套件”类型的情况,例如: 3个国王,并使用其余卡的值(例如,3种类型有两个“未使用的卡”)来确定最高值。
答案 1 :(得分:1)
您可以为每种手型和子权重分配颜色和卡片顺序的权重。然后,您可以使用虚拟函数来计算权重和子权重,并比较结果。这对你有用吗?
答案 2 :(得分:1)
尽管它很明显,但是如果明确的是 - 冲洗,直线等等和扑克手之间的关系,我实际上根本不会使用继承,至少不是手工类型。例如,在任何抽奖扑克游戏中,手牌的类型可以改变,而在其他游戏中,例如Texas Hold-em,它只会逐渐显露出来。但当然,初始化后无法更改类类型。
相反只是存储卡片,并有一个基本或朋友功能,它返回类型(枚举的成员)和另一个用于订购卡片(因此你可以获得高卡等)然后定义一个简单的比较器功能,再次基类或全球朋友,比较两只手。
struct Card
{
int suit, rank;
};
bool operator<(const Card& a, const Card& b) { ... }
class PokerHand
{
public:
// ... constructor
enum HandType
{
NOTHING = 0,
PAIR,
TWO_PAIR,
...
}
HandType GetHandType() { ... }
private:
std::vector<Card> _hand;
};
bool operator<(const PokerHand& a, const PokerHand& b) { ... }
没有那么难以填补空白。
如果您确定您想要派生类,那么我将使用RTTI上的类型字段,这可以通过例如如上所述的枚举。
答案 3 :(得分:0)
这应该很简单。你可以添加一些重量:
class PokerHand {
public:
//...
virtual int GetHandWeights() const = 0;
};
bool operator<( const PokerHand & lh, const PokerHand & rh )
{
return lh.GetHandWeights() < rh.GetHandWeights();
}
然后,您只需要使用operator<
。