C rand()在模运算后不生成随机数

C rand()在模运算后不生成随机数,c,C,我正在复习C,并参加了一个棋盘游戏作为练习。棋盘游戏是“将军们的游戏”,与国际象棋非常相似,因为它使用的棋子在8x8的正方形上排列 基本上,电路板的实现是特定结构的二维数组。因此,可以通过其索引访问电路板的正方形,很像x-y坐标系 现在,我决定在整个电路板上随机分布这些部件,逻辑是生成一个随机的x-y坐标,检查一个部件是否已经存在于电路板上的这些坐标上,并用一个部件(如果可用)填充它。如果不是,则生成另一个随机x-y坐标。这一直持续到所有的碎片都被计算出来 我使用rand()生成特定范围内的随机

我正在复习C,并参加了一个棋盘游戏作为练习。棋盘游戏是“将军们的游戏”,与国际象棋非常相似,因为它使用的棋子在8x8的正方形上排列

基本上,电路板的实现是特定结构的二维数组。因此,可以通过其索引访问电路板的正方形,很像x-y坐标系

现在,我决定在整个电路板上随机分布这些部件,逻辑是生成一个随机的x-y坐标,检查一个部件是否已经存在于电路板上的这些坐标上,并用一个部件(如果可用)填充它。如果不是,则生成另一个随机x-y坐标。这一直持续到所有的碎片都被计算出来

我使用rand()生成特定范围内的随机数(我使用一个模运算符和一个填充数来指定范围。请参阅下面的代码)

但是rand()似乎没有给出足够的随机数供我使用。我一次又一次地以同样的作品发行而告终!(但有趣的是,我可以在Mac上生成不同的发行版,但发行版仍然是一致的!)

请参阅下面的代码,了解我如何使用rand()生成具有范围的数字

void initPieces(){

    int player, rank_index, population, rand_min, rand_x, rand_y;

    for(player = 1; player <= 2; player++){

       if(player == 1){
            rand_min = 5;
        }else{
           rand_min = 1;
        }

        for(rank_index = 0; ir < sizeof ranking/sizeof ranking[0]; rank_index++){

            for(population = 0; population < getRank(rank_index)->population; population++){

               do{
                   rand_x = (rand() % 8) + 1;
                   rand_y = (rand() % 4) + rand_min;

               }while((getGrid(rand_x,rand_y))->has_piece == 1);

               assignPiecetoGrid(player,rank_index,rand_x,rand_y);

            }

       }

   }

}
void initPieces(){
整型玩家,排名指数,人口,随机最小值,随机x,随机y;
对于(玩家=1;玩家数量;人口++){
做{
rand_x=(rand()%8)+1;
rand_y=(rand()%4)+rand_min;
}而((getGrid(rand_x,rand_y))->具有_片段==1);
分配分段网格(玩家、排名索引、随机x、随机y);
}
}
}
}

您需要意识到
是一个,它经过专门设计,可以为给定的种子返回相同的数字序列。种子通过
srand()函数设置

srand(0);
printf("the first rand() with seed 0 is %d\n", rand());
srand(1);
printf("the first rand() with seed 1 is %d\n", rand());
srand(0);
printf("the first rand() with seed 0 is still %d\n", rand());
因此,使其不那么可预测的方法通常是从更随机的东西中重新播种,或者至少从每次运行程序时都不相同的东西中重新播种:

srand((NULL))

您应该使用来为随机生成器设定种子

常见的随机种子是
srand(time(NULL))

是的,因为您不能“初始化”rand()。 尝试这样做
srand(time(NULL))

您还必须包括
time.h

调用此命令一次:

srand (time(NULL));

要在调用
rand()
之前进行初始化,请确保对随机数生成器进行初始化/设定种子:

#include <time.h>

srand(time(NULL));
#包括
srand(时间(空));

必须使用随机种子初始化随机数生成器。请参见
srand()
函数。通常它是用时间初始化的:
srand(time(NULL))

如果您没有为伪随机数生成器设定种子,就像您在程序开始时调用:

srand(1);
您可以使用一个取决于时间的参数调用
srand
,以便连续两次调用 您的程序将生成不同的数字:

srand(time(NULL));

所有答案都是正确的,您需要在rand函数中添加如下内容

srand(time(NULL));
但是为什么呢

'rand'是一种所谓的伪随机数生成器。这意味着这些数字并不是真正的随机数,但该函数使用一种算法生成一系列数字,这些数字具有与随机数相似的特征,特别是在均匀分布方面

这意味着当使用相同的种子时,将产生相同的序列。这就是为什么这些生成器也称为确定性随机数生成器


设定种子将提供不同的起始值,从而产生不同的数字序列。

您是否在某个地方设定了生成器的
srand()
?我喜欢有人删除我的评论。这是管理问题吗?这是实际的可编译代码吗?它看起来甚至不会编译给我,例如,
for(population=0;populationpopulation;人口++)
?@Paul R:也许有一个
定义getRank(a)*(a++
潜伏在那里?:)不,我当然同意,代码看起来很奇怪。对不起,保罗。它应该是
getRank(rank\u index)
。当我编辑它时,只是按错了键(实际代码中的
ri
。只是让它在这里更可读。是的,我知道,我应该从一开始就使用
rank\u index
)+1作为完整答案。只要提醒一下,类似于srand(time(NULL))的调用;是需要的。@nyarlathotep:说得好,我想我把自己弄糊涂了。:)编辑进来,谢谢各位。只是为OP澄清一下:种子只能在节目开始时进行一次。如果您的程序经常运行(每秒不止一次),则需要找到备用的、特定于平台的种子值源,例如UNIX上的/dev/random或/dev/urandom。在Windows上,如果时间不够,可以使用CryptGenRandom()进行种子设定。@unwind谢谢,伙计!简洁明了。干杯