C语言决斗概率模拟代码无报错但无法运行/循环的问题求助
排查C语言决斗模拟代码的循环卡死问题
嘿,我一眼就看到你这段代码里的核心问题了——这是C语言新手最容易踩的赋值运算符=和比较运算符==混淆的坑,直接导致你的模拟循环根本停不下来,咱们一步步拆解问题:
核心问题:用赋值代替比较
你代码里所有的条件判断(while和if里)都用了=而不是==,比如:
while (((aaron_alive = true) && (bob_alive = true)) || ((bob_alive = true) && (charlie_alive = true)) || ((aaron_alive = true) && (charlie_alive = true)))
还有:
if (aaron_alive = true)
=是赋值操作,会把右边的值赋给左边的变量,然后返回这个值。所以上面的while条件永远会被计算为true——你每次都把三个变量强制设为true,循环永远不会终止,这就是代码“无法执行模拟循环”的直接原因。
正确的做法是用==做比较,或者因为变量是bool类型,直接写变量名就行(比如if (aaron_alive)就等价于if (aaron_alive == true))。
其他次要但关键的问题
除了赋值/比较的混淆,代码里还有几个逻辑错误:
- 冗余且错误的嵌套判断:比如Aaron射击Charlie的代码里,你写了:
这段代码逻辑完全错误,应该用if (random < aaron_accuracy * 100) { charlie_alive = false; if (random > aaron_accuracy * 100) { // 这里永远不会执行,因为上面已经满足<的条件了 charlie_alive = true; } }else来处理没命中的情况,或者直接不写——因为没命中的话charlie_alive本来就是true,不需要额外赋值。 - 错误的胜负计数位置:你把统计胜负的代码放在了内部循环(每一轮射击)里面,这会导致每射击一次就统计一次,而不是每一局决斗结束后统计。必须把计数代码移到内部
while循环的外面。 - 随机数未初始化:代码里用了
rand()但没有调用srand(time(NULL))初始化随机数生成器,每次运行程序都会得到完全相同的模拟结果。
修正后的代码示例
下面是修复了这些问题的版本,关键修改点我加了注释:
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <time.h> int main() { int puzzle_count = 0; double aaron_accuracy = 1.0 / 3.0; double bob_accuracy = 1.0 / 2.0; double charlie_accuracy = 1.0; bool aaron_alive; bool bob_alive; bool charlie_alive; double random; double aaronwins = 0; double bobwins = 0; double charliewins = 0; double aaron_percent = 0; double bob_percent = 0; double charlie_percent = 0; printf("\n Who is the greatest puzzler of all time?"); // 初始化随机数生成器,保证每次运行结果不同 srand(time(NULL)); while (puzzle_count < 10000) { aaron_alive = true; bob_alive = true; charlie_alive = true; // 修正循环条件:用比较而非赋值,判断是否至少两人存活 while ((aaron_alive && bob_alive) || (bob_alive && charlie_alive) || (aaron_alive && charlie_alive)) { if (aaron_alive) { // 直接用bool变量作为条件,简洁清晰 if (charlie_alive) { random = rand() % 100; if (random < aaron_accuracy * 100) { charlie_alive = false; } // 没命中不需要额外操作,charlie_alive保持true } else if (bob_alive) { // Charlie死了才打Bob random = rand() % 100; if (random < aaron_accuracy * 100) { bob_alive = false; } } } if (bob_alive) { if (charlie_alive) { random = rand() % 100; if (random < bob_accuracy * 100) { charlie_alive = false; } } else if (aaron_alive) { // Charlie死了才打Aaron random = rand() % 100; if (random < bob_accuracy * 100) { aaron_alive = false; } } } if (charlie_alive) { if (bob_alive) { // Charlie优先攻击威胁更大的Bob(符合谜题设定) random = rand() % 100; if (random < charlie_accuracy * 100) { bob_alive = false; } } else if (aaron_alive) { random = rand() % 100; if (random < charlie_accuracy * 100) { aaron_alive = false; } } } } // 一局决斗结束后再统计胜负,移到内部循环外面 if (aaron_alive) aaronwins++; if (bob_alive) bobwins++; if (charlie_alive) charliewins++; puzzle_count++; } if (aaronwins + bobwins + charliewins == 10000) { aaron_percent = aaronwins / 10000; bob_percent = bobwins / 10000; charlie_percent = charliewins / 10000; // 修正百分比输出:乘以100后才是正确的百分比数值 printf("\n Aaron won %.0f/10000 or %.2f%% of the time", aaronwins, aaron_percent * 100); printf("\n Bob won %.0f/10000 or %.2f%% of the time", bobwins, bob_percent * 100); printf("\n Charlie won %.0f/10000 or %.2f%% of the time", charliewins, charlie_percent * 100); } return 0; }
补充说明
我还调整了Charlie的攻击逻辑:按照常理,百发百中的Charlie会优先攻击威胁更大的Bob(命中率1/2),而不是Aaron(命中率1/3),这符合原谜题的设定。另外也修正了百分比的输出格式,确保显示的是正确的百分比数值。
内容的提问来源于stack exchange,提问作者Cronin709
相关产品推荐
相关产品推荐

