我在设计一个扑克游戏。对于用户拥有的卡(始终为5张卡),将有一个PokerHand类。PokerHand有不同的类别,如直,同花顺,全屋等。
现在我希望所有的PokerHand都是可比较的。类别之间有一个定义的顺序:同花顺>4种>满屋> ...对于每个类别,都有一个不同的比较规则。例如,对于直道,高牌决定。对于"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?
发布于 2013-04-15 15:04:17
我很确定你的做法是错误的。
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张王牌击败3张王牌击败3张王后,等等。你还必须处理“等值,更好的组合”类型的情况,例如3张王牌,并使用剩余牌的值(例如,3张牌有两张“未使用的牌”)来确定最高值。
这里列出了一些规则:http://en.wikipedia.org/wiki/List_of_poker_hands
发布于 2013-04-15 14:51:19
您可以将权重分配给每个手牌类型,并将子权重分配给颜色和卡片顺序。然后,您可以使用一个虚拟函数来计算权重和子权重,并比较结果。这对你有用吗?
发布于 2013-04-15 14:52:02
虽然这很诱人,但鉴于清楚的是-同花顺、直等和扑克牌之间的关系,我实际上根本不会在这里使用继承,至少不会对手型使用继承。在任何抽牌扑克游戏中,例如,的手牌类型可以改变,而在其他游戏中,如德克萨斯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上的类型字段,这可以通过上面的枚举来实现。
https://stackoverflow.com/questions/16009175
复制相似问题