基于Qt的德州扑克03:牌型

牌型

德州扑克最后会使用5张牌作为玩家最后的牌进行比大小。这也是上一篇文章一次生成五张牌的原因。

这5张牌可以组成10种牌型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//牌型 5张牌组成一种牌型
enum BrandType{
None=-1,//无状态
HighCard=0,//高牌 无以下任意情况,取牌中最大数
OnePair,//一对
TwoPair,//两对
ThreeOfaKind,//三条 三张同数
Straight,//顺子
Flush,//同花 数字不做要求
FullHouse,//葫芦 3带2
FourOfaKind,//四条 四张同数
StraightFlush,//同花顺 同色顺子
RoyalFlush,//皇家同花顺 同色的10JQKA
};

任意有效5张牌只会出现10种牌型,最低是高牌。

判断

排序

捋顺5张牌,以便后续开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//////////////////////////////////////
/// 捋顺5张牌顺序 从大到小
/// \brief straightCards
/// \param cards
///
inline void straightCards(Cards &cards){
for(int i=0;i<4;i++){
for(int j=i+1;j<5;j++){
if(cards.card[i].CardNum<cards.card[j].CardNum){
Number t = cards.card[j].CardNum;
cards.card[j].CardNum = cards.card[i].CardNum;
cards.card[i].CardNum = t;
}//if
}//for j
}//for i
}

五条

理论上一副牌中不会出现5个相同的数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
////////////////////////////
/// 判断5张牌的数字是否一样
/// \brief is5
/// \param cards
/// \return
///
inline bool is5(Cards cards){
if((cards.card[0].CardNum == cards.card[1].CardNum) &&
(cards.card[0].CardNum == cards.card[2].CardNum) &&
(cards.card[0].CardNum == cards.card[3].CardNum) &&
(cards.card[0].CardNum == cards.card[4].CardNum)){
return true;//5张牌数字一样,这个理论上一副牌中是不可能的
}//if
return false;//5张牌数字不一样
}

包含A

在皇家同花顺中会用到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
////////////////////////////////
/// 判断5张牌中是否包含A
/// \brief isHighA
/// \param cards
/// \return
///
inline bool isHighA(Cards cards){
for(int i=0;i<5;i++){
if(cards.card[i].CardNum==Num_A){
//检测到A就可以了
return true;
}//if
}//for
return false;
}

同花

直接判断结构体中的花色是否相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
////////////////////////////////
/// \brief isFlush 判断5张牌是否是同花
/// \param cards
/// \return
///
inline bool isFlush(Cards cards){
for(int i=1;i<5;i++){
if(cards.card[i].CardDecor!=cards.card[i-1].CardDecor){
//有一个不同色就不是同花
return false;
}//if
}//for
return true;
}

顺子

两两差一。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
///////////////////////////////////
/// \brief isStraight 判断是否是顺子
/// \param cards
/// \return
///
inline bool isStraight(Cards &cards){
//排序
straightCards(cards);

for(int i=1;i<5;i++){
if((cards.card[i-1].CardNum-cards.card[i].CardNum) != 1){
//有一个不是就退出
return false;
}//if
}//for
return true;
}

葫芦

检测三条和一对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
////////////////////////////////////
/// 是否是葫芦/三带二
/// \brief isFullHouse
/// \param cards
/// \return
///
inline bool isFullHouse(Cards &cards){
//先检测三条
Number three = Num_None;//三条对应的数
for(int w=0;w<3;w++){
for(int x=w+1;x<4;x++){
for(int y=x+1;y<5;y++){
if((cards.card[w].CardNum == cards.card[x].CardNum) &&
(cards.card[w].CardNum == cards.card[y].CardNum)){
three=cards.card[w].CardNum;//有一个就行
break;
}
}//y
}//x
}//w

if(three == Num_None) return false;

//再检测与三条数值不同的一对
for(int i=0;i<4;i++){
for(int j=i+1;j<5;j++){
if((cards.card[i].CardNum == cards.card[j].CardNum) &&
(cards.card[i].CardNum != three)){
return true;//有一个就行
}
}//j
}//i

return false;
}

两对

判断两次一对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//////////////////////////////////
/// 判断是否是两对
/// \brief isTwoPair
/// \param cards
/// \return
///
inline bool isTwoPair(Cards &cards){
//先判断第一对
Number pair1 = Num_None;
for(int i=0;i<4;i++){
for(int j=i+1;j<5;j++){
if(cards.card[i].CardNum == cards.card[j].CardNum){
pair1=cards.card[i].CardNum;//有一个就行
break;
}
}//j
}//i

if(pair1 == Num_None) return false;

//在判断第二对
for(int i=0;i<4;i++){
for(int j=i+1;j<5;j++){
if((cards.card[i].CardNum == cards.card[j].CardNum) &&
(cards.card[i].CardNum != pair1)){
return true;//有一个就行
}
}//j
}//i

//不可能有第3对
return false;
}

牌型检测

上面是各自独立判断,但是会有重复的部分,比如葫芦里面可以检测出三条和一对,四条中包含三条,两对中包含两个一对。

综合判断采用由大到小,层层叠加的方式。

  • 如果检测到包含A+顺子+同花,就是皇家同花顺
  • 如果检测到四条+同花,则判断为四条,因为四条比同花大
  • 如果检测到三条并且没有对子就是三条,如果检测到三条+对子就是葫芦

效果

牌型检测


基于Qt的德州扑克03:牌型
https://blog.jackeylea.com/qt/brand-type-of-texas-holdem-poker/
作者
JackeyLea
发布于
2020年12月30日
许可协议