使用枚举类型时二十一点手牌计分系统计算异常排查
解决二十一点手牌计分的ACE逻辑问题
我来帮你搞定这个二十一点的计分函数问题~首先明确你的核心需求:手牌里有ACE时,基础总分(ACE先按1算)小于11的话,要把ACE当成11分(也就是额外加10);基础总分大于等于11时,ACE只按1分算。目前你的函数只实现了ACE计1分的基础逻辑,缺少了根据总分动态调整ACE分值的部分。
先补全你的类型定义(保证代码完整性)
我先把你没写完的牌面值枚举补全,毕竟J/Q/K在二十一点里都是10分:
typedef enum { HEARTS, DIAMONDS, SPADES, CLUBS } suit_t; typedef enum { ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } rank_t; // 假设你的手牌是由卡牌结构体组成的数组,这里定义通用的卡牌结构 typedef struct { suit_t suit; rank_t rank; } card_t;
问题分析:原始函数的不足
你的原始计分函数应该是类似这样的(仅给ACE计1分,没统计ACE数量也没做动态调整):
// 原始逻辑(仅ACE计1分,无动态调整) int calculate_hand_score(card_t hand[], int num_cards) { int score = 0; for (int i = 0; i < num_cards; i++) { rank_t rank = hand[i].rank; if (rank >= JACK && rank <= KING) { score += 10; } else { score += rank; // ACE这里只加1,没有后续调整 } } return score; }
这个函数的核心问题是:没有统计手牌中的ACE数量,也没有根据当前总分判断是否需要给ACE额外加10分,完全忽略了ACE的可变分值特性。
修改后的完整计分函数(实现你的需求)
下面的代码会先计算基础分(ACE按1算),同时统计ACE的数量,再根据你的需求动态调整ACE的分值:
int calculate_hand_score(card_t hand[], int num_cards) { int score = 0; int ace_count = 0; // 第一步:计算基础分,同时统计手牌中的ACE数量 for (int i = 0; i < num_cards; i++) { rank_t rank = hand[i].rank; if (rank >= JACK && rank <= KING) { score += 10; } else if (rank == ACE) { score += 1; // 先按1分计算基础分 ace_count++; } else { score += rank; // 2-10直接加对应数值 } } // 第二步:根据需求调整ACE的分值 // 当基础分小于11,且还有未调整的ACE时,额外加10(把ACE当成11分) // 同时确保加10后总分不超过21(符合二十一点规则,避免爆牌) while (ace_count > 0 && score < 11) { if (score + 10 <= 21) { score += 10; ace_count--; } else { break; // 加10会爆牌,停止调整 } } return score; }
典型场景验证
- 场景1:手牌是
ACE + TWO→ 基础分1+2=3 <11,加10后总分13(ACE按11算,符合需求) - 场景2:手牌是
ACE + KING→ 基础分1+10=11,不满足<11的条件,总分保持11(严格遵循你的需求);如果要贴合真实二十一点规则(ACE可选1或11,只要不爆牌),可以把while循环的条件改成score + 10 <=21,这样这个场景会得到21的满分 - 场景3:手牌是
ACE + ACE + FIVE→ 基础分1+1+5=7 <11,先加10变成17,剩余1个ACE,但17+10=27>21,停止调整,最终总分17(正确,一个ACE按11,一个按1)
内容的提问来源于stack exchange,提问作者Stacy Willis
相关产品推荐
相关产品推荐

