You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:30:19