Blackjack概率计算C语言代码纠错求助:实验逻辑问题排查
问题分析与代码修正
原代码核心错误点
- 未初始化变量
aftersum:int aftersum=sum+k;定义时sum和k未赋值,为垃圾数据,导致后续循环判断完全失效。 - 错误的成功判定逻辑:当首次抽牌和小于目标时,无论后续抽牌是否超过目标,都直接判定成功并累加统计,违背题目“超过目标则失败”的规则。
- Ace处理漏洞:初始两张牌的Ace转换逻辑不严谨,后续抽牌的Ace处理未正确结合当前总和判断。
- 概率与牌数计算错误:概率计算未按总实验次数100000次换算百分比;成功平均用牌数错误除以总实验次数,而非成功次数。
- 缺失失败分支处理:未处理首次抽牌和超过目标的失败场景,导致成功次数统计虚高。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { // 初始化随机数种子,保证每次运行结果不同 srand((unsigned int)time(NULL)); printf("Points Probability #Cards\n"); // 遍历4到21的所有目标点数 for (int points = 4; points <= 21; points++) { int count = 0; // 当前目标的实验次数 unsigned int total = 0; // 成功次数 unsigned int cardsum = 0; // 成功实验的总用牌数 // 执行100000次实验 while (count < 100000) { count++; int sum = 0; int card_count = 0; // 抽取初始两张牌 for (int i = 0; i < 2; i++) { int card = rand() % 13 + 1; // 转换牌面:J/Q/K为10,Ace暂按11计算(后续调整) if (card > 10) { card = 10; } else if (card == 1) { card = 11; } sum += card; card_count++; } // 处理两张Ace的特殊情况:11+11=22,自动转为1+11=12 if (sum == 22) { sum = 12; } // 首次抽牌结果判断 if (sum > points) { // 超过目标,实验失败,跳过统计 continue; } else if (sum == points) { // 恰好等于目标,成功 total++; cardsum += card_count; continue; } // 总和小于目标,继续抽牌直到结果明确 while (sum < points) { int card = rand() % 13 + 1; if (card > 10) { card = 10; } else if (card == 1) { // Ace智能转换:加11不超目标则用11,否则用1 card = (sum + 11) <= points ? 11 : 1; } sum += card; card_count++; // 抽牌后超过目标,实验失败,终止抽牌 if (sum > points) { break; } } // 循环结束后判断是否成功 if (sum == points) { total++; cardsum += card_count; } } // 计算成功概率(百分比)和成功时的平均用牌数 float percent = (float)total / 100000.0 * 100; float avg_cards = (float)cardsum / total; // 仅除以成功次数 printf(" %2d %5.2f%% %.2f\n", points, percent, avg_cards); } return 0; }
关键修正说明
- 随机数种子初始化:添加
srand((unsigned int)time(NULL)),避免每次运行生成相同的随机牌序列。 - 严谨的胜负判定:
- 首次抽牌超过目标直接标记失败,不参与成功统计。
- 后续抽牌若超过目标,立即终止抽牌并标记失败,仅当总和恰好等于目标时计入成功。
- 优化Ace处理:
- 两张Ace自动调整为12,避免初始总和22的无效情况。
- 后续抽Ace时,根据当前总和动态选择1或11,确保不提前超过目标。
- 修正统计逻辑:
- 成功概率按
(成功次数/总实验次数)*100计算,正确转换为百分比。 - 成功平均用牌数为成功总用牌数/成功次数,解决了目标点数4时结果异常的问题。
- 成功概率按
- 清晰的牌数统计:用
card_count直接记录单次实验的用牌数,成功时累加至cardsum,逻辑直观不易出错。
内容的提问来源于stack exchange,提问作者pinglin chen
相关产品推荐
相关产品推荐

