C++ 扑克牌组合判断程序:完整代码与详细解析
C++ 扑克牌组合判断程序:完整代码与详细解析
在本挑战中,您需要确定一副五张牌中存在哪种扑克组合。每张牌用一个字符串表示,包括牌值(正面卡片的首字母大写)和花色(小写首字母),例如:
'Ah' ➞ A of 红桃 'Ks' ➞ K of 黑桃 '3d' ➞ 3 of 方块 'Qc' ➞ Q of 梅花
总共有 10 种不同的组合,按重要性降序排列如下:
- Royal Flush:A、K、Q、J、10,都同一套花色。
- Straight Flush:五张牌依次排列,花色相同。
- Four of a Kind:四张相同等级的牌。
- Full House:三对一对。
- Flush:任何五张相同花色的牌,不按顺序。
- Straight:连续五张牌,但花色不同。
- Three of a Kind:三张相同等级的牌。
- Two Pair:两个不同的对。
- Pair:两张相同等级的牌。
- High Card:没有其他有效组合。
给定一个名为 'hand' 的列表,包含五个字符串作为卡片,实现一个函数,根据上面的列表返回一个字符串,表示获得的最高组合名称。
输入输出格式
- 输入格式:第一行有 5 个字符串,表示五个字符串卡片的数组。
- 输出格式:一行输出字符串,表示获得的最高组合名称。
输入输出样例1
- 输入 10h Jh Qh Ah Kh
- 输出 Royal Flush
程序实现
为了解决这个问题,我们需要对五张牌进行分类,并根据题目的十种组合逐一判断。下面我们将逐步实现这个过程。
1. 定义数据结构
首先,我们需要定义一个结构体来表示一张牌,包括它的点数和花色:
struct Card {
char rank; // 点数
char suit; // 花色
};
其中,点数和花色都用一个字符来表示,具体表示方法见题目描述。
2. 读入五张牌
接下来,我们需要读入五张牌,并将它们保存在一个数组中。使用循环依次读入每张牌,并将其对应到我们定义的数据结构中:
Card hand[5]; // 五张牌
for (int i = 0; i < 5; i++) {
string s;
cin >> s;
hand[i].rank = s[0]; // 点数
hand[i].suit = s[1]; // 花色
}
3. 判断最高组合
在读入五张牌之后,我们需要对它们进行分类,判断它们所属的组合。为了方便比较,我们可以给每种组合一个权值,然后将最高组合的权值与其他组合的权值比较,从而得出最高组合的名称。下面我们将逐一介绍如何判断每种组合。
3.1 判断 Royal Flush
Royal Flush 是最高的组合,包括 A、K、Q、J、10,都同一套花色。判断方法如下:
- 判断五张牌的花色是否相同;
- 判断五张牌的点数是否为 A、K、Q、J、10。
int is_royal_flush(Card hand[]) {
char suit = hand[0].suit; // 取出第一张牌的花色
for (int i = 1; i < 5; i++) {
if (hand[i].suit != suit) return 0; // 花色不同,不是 Royal Flush
}
string ranks = "AKQJT";
for (int i = 0; i < 5; i++) {
if (ranks.find(hand[i].rank) == string::npos) return 0; // 点数不符合,不是 Royal Flush
}
return 10; // 是 Royal Flush,返回权值 10
}
3.2 判断 Straight Flush
Straight Flush 是五张牌依次排列,花色相同。判断方法如下:
- 判断五张牌的花色是否相同;
- 将五张牌按点数从小到大排序,判断它们是否连续。
int is_straight_flush(Card hand[]) {
char suit = hand[0].suit; // 取出第一张牌的花色
for (int i = 1; i < 5; i++) {
if (hand[i].suit != suit) return 0; // 花色不同,不是 Straight Flush
}
sort(hand, hand + 5, cmp_rank); // 按点数从小到大排序
for (int i = 1; i < 5; i++) {
if (hand[i].rank != hand[i - 1].rank + 1) return 0; // 不连续,不是 Straight Flush
}
return 9; // 是 Straight Flush,返回权值 9
}
3.3 判断 Four of a Kind
Four of a Kind 是四张相同等级的牌。判断方法如下:
- 对五张牌按点数排序,找到点数相同的四张牌。
int is_four_of_a_kind(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
if (hand[0].rank == hand[3].rank || hand[1].rank == hand[4].rank) {
return 8; // 找到了四张相同等级的牌,返回权值 8
} else {
return 0; // 没有找到,不是 Four of a Kind
}
}
3.4 判断 Full House
Full House 是三对一对。判断方法如下:
- 对五张牌按点数排序,找到点数相同的三张牌;
- 如果找到了这样的三张牌,再找到点数相同的一对牌。
int is_full_house(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
if (hand[0].rank == hand[2].rank && hand[3].rank == hand[4].rank ||
hand[0].rank == hand[1].rank && hand[2].rank == hand[4].rank) {
return 7; // 找到了三对一对,返回权值 7
} else {
return 0; // 没有找到,不是 Full House
}
}
3.5 判断 Flush
Flush 是任何五张相同花色的牌,不按顺序。判断方法如下:
- 判断五张牌的花色是否相同。
int is_flush(Card hand[]) {
char suit = hand[0].suit; // 取出第一张牌的花色
for (int i = 1; i < 5; i++) {
if (hand[i].suit != suit) return 0; // 花色不同,不是 Flush
}
return 6; // 是 Flush,返回权值 6
}
3.6 判断 Straight
Straight 是连续五张牌,但花色不同。判断方法如下:
- 将五张牌按点数从小到大排序,判断它们是否连续。
int is_straight(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
for (int i = 1; i < 5; i++) {
if (hand[i].rank != hand[i - 1].rank + 1) return 0; // 不连续,不是 Straight
}
return 5; // 是 Straight,返回权值 5
}
3.7 判断 Three of a Kind
Three of a Kind 是三张相同等级的牌。判断方法如下:
- 对五张牌按点数排序,找到点数相同的三张牌。
int is_three_of_a_kind(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
for (int i = 0; i < 3; i++) {
if (hand[i].rank == hand[i + 1].rank && hand[i].rank == hand[i + 2].rank) {
return 4; // 找到了三张相同等级的牌,返回权值 4
}
}
return 0; // 没有找到,不是 Three of a Kind
}
3.8 判断 Two Pair
Two Pair 是两个不同的对。判断方法如下:
- 对五张牌按点数排序,找到两个点数相同的对。
int is_two_pair(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
if (hand[0].rank == hand[1].rank && hand[2].rank == hand[3].rank ||
hand[0].rank == hand[1].rank && hand[3].rank == hand[4].rank ||
hand[1].rank == hand[2].rank && hand[3].rank == hand[4].rank) {
return 3; // 找到了两个不同的对,返回权值 3
} else {
return 0; // 没有找到,不是 Two Pair
}
}
3.9 判断 Pair
Pair 是两张相同等级的牌。判断方法如下:
- 对五张牌按点数排序,找到点数相同的两张牌。
int is_pair(Card hand[]) {
sort(hand, hand + 5, cmp_rank); // 按点数排序
for (int i = 0; i < 4; i++) {
if (hand[i].rank == hand[i + 1].rank) {
return 2; // 找到了一对相同等级的牌,返回权值 2
}
}
return 0; // 没有找到,不是 Pair
}
3.10 判断 High Card
High Card 没有其他有效组合。如果前面所有的组合都不符合,则说明是 High Card。
int is_high_card(Card hand[]) {
return 1; // 是 High Card,返回权值 1
}
4. 输出最高组合
最后,我们需要比较所有组合的权值,找到最高的组合,然后输出它的名称。下面是完整的代码:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
struct Card {
char rank; // 点数
char suit; // 花色
};
bool cmp_rank(Card a, Card b) {
return a.rank < b.rank;
}
int is_royal_flush(Card hand[]) {
// ... (代码与前面相同)
}
int is_straight_flush(Card hand[]) {
// ... (代码与前面相同)
}
int is_four_of_a_kind(Card hand[]) {
// ... (代码与前面相同)
}
int is_full_house(Card hand[]) {
// ... (代码与前面相同)
}
int is_flush(Card hand[]) {
// ... (代码与前面相同)
}
int is_straight(Card hand[]) {
// ... (代码与前面相同)
}
int is_three_of_a_kind(Card hand[]) {
// ... (代码与前面相同)
}
int is_two_pair(Card hand[]) {
// ... (代码与前面相同)
}
int is_pair(Card hand[]) {
// ... (代码与前面相同)
}
int is_high_card(Card hand[]) {
// ... (代码与前面相同)
}
int main() {
Card hand[5];
for (int i = 0; i < 5; i++) {
string s;
cin >> s;
hand[i].rank = s[0];
hand[i].suit = s[1];
}
int max_value = 0;
string max_name;
max_value = max(max_value, is_royal_flush(hand));
if (max_value == 10) max_name = "Royal Flush";
max_value = max(max_value, is_straight_flush(hand));
if (max_value == 9) max_name = "Straight Flush";
max_value = max(max_value, is_four_of_a_kind(hand));
if (max_value == 8) max_name = "Four of a Kind";
max_value = max(max_value, is_full_house(hand));
if (max_value == 7) max_name = "Full House";
max_value = max(max_value, is_flush(hand));
if (max_value == 6) max_name = "Flush";
max_value = max(max_value, is_straight(hand));
if (max_value == 5) max_name = "Straight";
max_value = max(max_value, is_three_of_a_kind(hand));
if (max_value == 4) max_name = "Three of a Kind";
max_value = max(max_value, is_two_pair(hand));
if (max_value == 3) max_name = "Two Pair";
max_value = max(max_value, is_pair(hand));
if (max_value == 2) max_name = "Pair";
max_value = max(max_value, is_high_card(hand));
if (max_value == 1) max_name = "High Card";
cout << max_name << endl;
return 0;
}
代码说明
cmp_rank函数用于比较两张牌的点数,用于排序。is_xxx函数用于判断对应类型的牌型,返回值为权值,0 表示不符合,其他数字表示权值。main函数首先读入五张牌,然后逐个调用is_xxx函数判断牌型,并记录最高权值和对应名称,最后输出最高牌型名称。
总结
本文详细讲解了如何使用 C++ 编写一个程序,判断五张牌的扑克组合,包括代码实现、数据结构定义、组合判断逻辑以及示例。希望本文能够帮助您理解扑克牌组合判断的逻辑和代码实现方法。
原文地址: https://www.cveoy.top/t/topic/mGNx 著作权归作者所有。请勿转载和采集!