【问题标题】:Program Not Returning Results as Expected. Probably Misuse of "bool"?程序未按预期返回结果。可能误用“布尔”?
【发布时间】:2013-09-19 21:04:32
【问题描述】:

我是编程新手,我必须开发一个可以模拟 10,000 次掷骰子游戏的程序。我得到它来计算房子和玩家的分数,直到我添加了函数“diceRoll”,玩家一次又一次地滚动,直到它匹配第一个滚动或 7(房子获胜)。现在它给出的结果绝对不是随机的(例如房子在 10,000 次中获胜 0 次)。我做错了什么?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

bool diceRoll (int a)
{
    srand( (unsigned)time(NULL));
    int n = 0;
    int b = 0;
    while(n < 1) {
        b = rand() % 12;
        if(b == a || b == 6) n++;
    }
    if(b == 6) return false;
    else return true;
}


int main (void)
{
    srand( (unsigned)time(NULL));
    int a, n, house, player, point;
    house = 0;
    player = 0;
    point = 0;

    for(n = 0; n < 10000; n++) {
        a = rand() % 12;
        if(a == 1 || a == 2 || a == 11) {
            house++;
        }
        else if(a == 6 || a == 10) {
            player++;
        }
        else {
            if(diceRoll(a) == true) player++;
            else house++;
        }
    }

    printf("The house has %i points.\n", house);
    printf("The player has %i points.\n", player);
    return 0;
}

【问题讨论】:

  • 你掉进了播种的陷阱,这和不播种一样糟糕。您只需为给定的随机数生成器播种一次。
  • 您最好向read this article 询问,由于rand() - 模加权的副作用,您为什么要将您的骰子游戏加载到统计上的非均匀分布。最好现在而不是以后发现。

标签: c random srand


【解决方案1】:

您已经过度播种,删除diceRoll 中对srand() 的调用,您应该没问题(这忽略了bias due to modulo usage)。

【讨论】:

  • 我更新了我的答案以包含为什么存在模偏差的链接,比我更有说服力。
  • 我理解偏见。我没有被监督。
  • @zubergu 如果你想了解 why 事情背后的真相see this document
  • IIRC,在同一秒内多次播种将一遍又一遍地产生相同的结果。
  • @zubergu:似乎倒退了,但足够公平!每次您播种随机数生成器时,它都会从头开始。播种并不需要很长时间,因此使用time(NULL) 作为参数就像在紧密循环中调用srand(4)。不断重新播种会导致不断的悲伤。
【解决方案2】:

仅在main() 中播种(而不是在循环中),不要在diceRoll(a) 函数中播种。

我按照你的方式运行,得到了house = 2, player = 9998

删除diceroll(a) 中的srand((unsigned)time(null)); 返回:

The house has 5435 points

The player has 4565 points

我想这就是你想要的

bool diceRoll (int a)
{
    int n = 0;
    int b = 0;
    while(n < 1) {
        b = rand() % 12;
        if(b == a || b == 6) n++;
    }
    if(b == 6) return false;
    else return true;
}

int main (void)
{
    srand( (unsigned)time(NULL));
    int a, n, house, player, point;
    house = 0;
    player = 0;
    point = 0;

    for(n = 0; n < 10000; n++) {
        a = rand() % 12;
        if(a == 1 || a == 2 || a == 11) {
            house++;
        }
        else if(a == 6 || a == 10) {
            player++;
        }
        else {
            if(diceRoll(a) == true) player++;
            else house++;
        }
    }

    printf("The house has %i points.\n", house);
    printf("The player has %i points.\n", player);
    return 0;
}

【讨论】:

  • 你给出了一个解决方案,但没有解释为什么按照他的方式做是错误的。
猜你喜欢
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2017-03-18
相关资源
最近更新 更多