看似随意的结果并不总是随机的

时间:2018-05-04 22:31:07

标签: c++ random

我正在建立一个现实游戏的模拟,我需要随机挑选参与每一轮比赛的球员的指数。问题是,在第一轮中,两个团队的索引有时是相同的,有时候不是,在第二轮和第三轮中,两个团队总是有相同的索引。任何人都可以对此有所了解吗?

代码如下:

#include <iostream>

using namespace std;

int ArraySearch(int* a, int num);

int compete()
{
    int round = 0; //current round
    int temp = 0;  //(temporary) random player index
    int Team1Players[5];  //player indexes of team 1
    int Team2Players[5];  //indexes of 2

    round++; //start from the 1st round

    while (round < 4)  //competition lasts for 3 rounds
    {
        srand(time(NULL));
        cout << "This is Round " << round << endl;  //DEBUG MSG

        cout << "Team 1 Players: ";  //DEBUG MSG
        for (int i = 0; i < 5; i++)
        {
            do     //change the chosen number when it already exists
            {
                temp = rand() % 11;
                Team1Players[i] = temp;
                //cout << "Grabbed a random number for team 1: " << Team1Players[i] << endl; //DEBUG MSG
            }
            while (ArraySearch(Team1Players, temp) == 1);
            cout << Team1Players[i] << " "; //DEBUG MSG
        }
        cout << endl;

        cout << "Team 2 Players: ";
        for (int i = 0; i < 5; i++)
        {
            do //same as above for team 2
            {
                temp = rand() % 11;
                Team2Players[i] = temp;
                //cout << "Grabbed a random number for team 2: " << Team2Players[i] << endl; //DEBUG MSG

            }
            while (ArraySearch(Team2Players, temp) == 1);
            cout << Team2Players[i] << " "; //DEBUG MSG
        }
        cout << endl;
        round++;
    }
}

int ArraySearch(int* a, int num)  //returns 1 when a number exists more than once, 0 when it does not exist or is unique
{
    int occurrences = 0;
    for (int i = 0; i < 5; i++)
    {
        if (a[i] == num)
        {
            occurrences += 1;
        }
    }
    if (occurrences > 1)
    {
        return 1;
    }
    return 0;
}

非常感谢提前。

2 个答案:

答案 0 :(得分:2)

您应该为整个程序播放rand 一次。这是你看到这个问题的原因。将此行移至main的顶部:

srand(time(NULL));

但等等,rand在这里是正确的选择吗?结果rand实际上通常不是一个好主意(更多请参阅this great talk)。相反,与this question一样,您应该使用<random>

#include <random>

std::random_device rseed;
std::mt19937 rgen(rseed()); // mersenne_twister
std::uniform_int_distribution<int> idist(0,10); // [0,100]

int compete() {
    ...
    temp = idist(rgen);

答案 1 :(得分:0)

rand()返回的随机数并非真正随机。它们是pseudo-random,因为它们属于一个似乎是随机的序列,不容易被猜到。序列的开头以srand()为种子。

<强>问题

您遇到的问题是因为您根据当前time()在循环的每次迭代中播种随机数:

   srand(time(NULL));

时序的准确性取决于实现,但大多数实现都是精确的。不幸的是,你循环可以足够快,时间戳是相同的,这样你就可以一次又一次地获得相同的随机数序列,直到你到达下一秒。

解决方案

在应用程序中仅设置种子一次,因此在进入循环之前。