C语言扑克牌手牌作业:Royal Flush(皇家同花顺)功能无法实现求助
搞定皇家同花顺功能的分步指南
嘿,别发愁啦!我帮你捋清楚皇家同花顺的实现思路,其实它就是同花顺的一个特殊分支,没你想的那么复杂~
先明确核心定义
皇家同花顺的本质是:
- 同时满足同花(Flush)和顺子(Straight)(也就是同花顺的基础)
- 必须是特定的顺子组合:10、J、Q、K、A(对应数值通常映射为10、11、12、13、14,把A设为14会让判断更简单)
基于现有代码的修改步骤
假设你已经实现了is_flush()(判断同花)、is_straight()(判断顺子),以及手牌排序的逻辑,只需要在同花顺的判断分支里加一层特殊检查即可:
步骤1:统一牌面数值映射
先把牌面转换成方便判断的数字:
- 2-10 → 2-10
- J → 11,Q → 12,K →13
- A →14(避免和“小顺子A-2-3-4-5”混淆,后续单独处理那种情况)
步骤2:在同花顺判断中细分皇家同花顺
当你判断出手牌是同花顺后,只需要检查排序后的手牌是否刚好是10,11,12,13,14这个序列。因为已经排序过,直接看首尾值或者逐个检查都可以:
// 假设你已经有排序后的牌面数组sorted_ranks[5],以及flush和straight的判断结果 if (flush && straight) { // 检查是否是皇家同花顺:排序后第一个是10,最后一个是14(A) if (sorted_ranks[0] == 10 && sorted_ranks[4] == 14) { royal_flush_count++; // 累加皇家同花顺计数 } else { straight_flush_count++; // 累加普通同花顺计数 } } else if (flush) { flush_count++; } else if (straight) { straight_count++; }
特殊情况处理:如果你的A是用1表示的
如果之前的代码里A被映射为1,那皇家同花顺的排序结果会是1,10,11,12,13,这时候需要额外加一个判断条件:
if (flush && straight) { // 两种皇家同花顺的情况:A作为14的正常序列,或者A作为1的特殊序列 int is_royal = (sorted_ranks[0] ==10 && sorted_ranks[4]==14) || (sorted_ranks[0]==1 && sorted_ranks[1]==10 && sorted_ranks[2]==11 && sorted_ranks[3]==12 && sorted_ranks[4]==13); if (is_royal) { royal_flush_count++; } else { straight_flush_count++; } }
完整代码示例(包含50000次统计)
这里给你一个可参考的完整片段,你可以替换成自己的发牌逻辑:
#include <stdio.h> #include <stdlib.h> #include <time.h> // 判断是否同花:所有花色相同 int is_flush(int suits[5]) { return (suits[0] == suits[1] && suits[1] == suits[2] && suits[2] == suits[3] && suits[3] == suits[4]); } // 判断是否顺子:连续5个数字,包含A-2-3-4-5的特殊情况 int is_straight(int ranks[5]) { // 先排序手牌(用冒泡排序,你可以换成更高效的算法) for (int i = 0; i < 4; i++) { for (int j = 0; j < 4 - i; j++) { if (ranks[j] > ranks[j+1]) { int temp = ranks[j]; ranks[j] = ranks[j+1]; ranks[j+1] = temp; } } } // 普通顺子:连续递增1 int normal_straight = 1; for (int i = 0; i < 4; i++) { if (ranks[i+1] != ranks[i] + 1) { normal_straight = 0; break; } } // 特殊顺子:A-2-3-4-5(这里A是1) int low_ace_straight = (ranks[0] == 1 && ranks[1] == 2 && ranks[2] == 3 && ranks[3] == 4 && ranks[4] == 5); return normal_straight || low_ace_straight; } int main() { srand(time(NULL)); // 初始化随机数种子 const int TOTAL_HANDS = 50000; int straight_count = 0, flush_count = 0; int straight_flush_count = 0, royal_flush_count = 0; for (int hand = 0; hand < TOTAL_HANDS; hand++) { int ranks[5], suits[5]; // 生成随机手牌(简化版,实际项目可以用更严谨的发牌逻辑避免重复) for (int i = 0; i < 5; i++) { ranks[i] = rand() % 13 + 1; // 1=A, 2-10=2-10, 11=J,12=Q,13=K suits[i] = rand() % 4; // 0-3代表四种花色 } // 复制一份牌面用于排序,避免修改原数组 int sorted_ranks[5]; for (int i = 0; i < 5; i++) sorted_ranks[i] = ranks[i]; int flush = is_flush(suits); int straight = is_straight(sorted_ranks); // 转换A为14,方便皇家同花顺判断(注意要在顺子判断之后,避免影响小顺子的判断) for (int i = 0; i < 5; i++) { if (sorted_ranks[i] == 1) sorted_ranks[i] = 14; } // 重新排序一次,因为A变成14后顺序变了 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4 - i; j++) { if (sorted_ranks[j] > sorted_ranks[j+1]) { int temp = sorted_ranks[j]; sorted_ranks[j] = sorted_ranks[j+1]; sorted_ranks[j+1] = temp; } } } // 按优先级判断牌型 if (flush && straight) { // 检查是否是皇家同花顺 if (sorted_ranks[0] == 10 && sorted_ranks[4] == 14) { royal_flush_count++; } else { straight_flush_count++; } } else if (flush) { flush_count++; } else if (straight) { straight_count++; } } // 输出统计结果 printf("50000手牌统计结果:\n"); printf("顺子:%d\n", straight_count); printf("同花:%d\n", flush_count); printf("同花顺:%d\n", straight_flush_count); printf("皇家同花顺:%d\n", royal_flush_count); return 0; }
关键注意点
- 排序是核心:无论哪种判断,都要先把手牌按从小到大排序,这样检查连续序列或首尾值会非常方便
- 避免重复统计:皇家同花顺属于同花顺的子集,所以一定要先判断皇家同花顺,再统计普通同花顺,不要搞反顺序
- 随机数种子:记得用
time(NULL)初始化随机数,不然每次运行结果都一样
内容的提问来源于stack exchange,提问作者Lauryn
相关产品推荐
相关产品推荐

