C++ 扑克牌组合判断程序:完整代码与详细解析

在本挑战中,您需要确定一副五张牌中存在哪种扑克组合。每张牌用一个字符串表示,包括牌值(正面卡片的首字母大写)和花色(小写首字母),例如:

'Ah' ➞ A of 红桃 'Ks' ➞ K of 黑桃 '3d' ➞ 3 of 方块 'Qc' ➞ Q of 梅花

总共有 10 种不同的组合,按重要性降序排列如下:

  1. Royal Flush:A、K、Q、J、10,都同一套花色。
  2. Straight Flush:五张牌依次排列,花色相同。
  3. Four of a Kind:四张相同等级的牌。
  4. Full House:三对一对。
  5. Flush:任何五张相同花色的牌,不按顺序。
  6. Straight:连续五张牌,但花色不同。
  7. Three of a Kind:三张相同等级的牌。
  8. Two Pair:两个不同的对。
  9. Pair:两张相同等级的牌。
  10. 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++ 编写一个程序,判断五张牌的扑克组合,包括代码实现、数据结构定义、组合判断逻辑以及示例。希望本文能够帮助您理解扑克牌组合判断的逻辑和代码实现方法。

C++ 扑克牌组合判断程序:完整代码与详细解析

原文地址: https://www.cveoy.top/t/topic/mGNx 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录