【发布时间】:2011-12-06 13:52:50
【问题描述】:
我输出的随机数,每次运行我的游戏时都以相同的顺序输出。为什么会这样?
我有
#include <cstdlib>
我正在使用它来生成随机数
randomDiceRollComputer = 1 + rand() % 6;
【问题讨论】:
我输出的随机数,每次运行我的游戏时都以相同的顺序输出。为什么会这样?
我有
#include <cstdlib>
我正在使用它来生成随机数
randomDiceRollComputer = 1 + rand() % 6;
【问题讨论】:
您需要播种随机数生成器:
试着把它放在程序的开头:
srand ( time(NULL) );
请注意,您需要#include <ctime>。
这里的想法是在每次启动程序时为 RNG 播种不同的编号。通过使用时间作为种子,每次启动程序时都会得到不同的数字。
【讨论】:
srand之后调用一次rand并丢弃返回值。事实证明,相似的种子会产生相似的第一个值,但会迅速发散。
time(NULL) 将给您相同的值。这可能是也可能不是问题,具体取决于应用程序。
rdtsc 播种。但这是一个不同的故事......
srand(time(NULL)) 不够好,那么rand() 可能还不够好。
你需要给随机数生成器一个种子。这可以通过获取当前时间来完成,因为这可能是某种随机的。
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int r;
srand(time(0));
r = rand();
return 0;
}
【讨论】:
伪随机数生成器采用一个起始数字或种子,然后从中生成序列中的下一个数字。这就是它们被称为伪随机的原因,因为如果它们始终使用相同的起始值,它们将生成与 C 标准库生成器相同的数字序列。这可以通过为生成器提供一个起始值来解决,该起始值将在下次程序运行时像当前时间一样发生变化。
无论如何,您正在寻找的代码就像其他人所说的那样:
srand(time(0)); //Seed the generator, give it a starting value
【讨论】:
rand() 函数特别需要在使用给定种子播种时产生相同的数字序列(通过调用srand());每个可能的种子值指定一个序列。如果你从不调用srand(),你会得到与在调用rand()之前调用srand(1)相同的序列。
(这不适用于不同的 C 或 C++ 实现。)
这对于测试目的很有用。例如,如果您的程序中存在错误,您可以通过使用相同的种子重新运行它来重现它,从而保证(除非出现其他不可预测的行为)您将获得相同的伪随机数序列。
调用srand(time(NULL)) 是获得或多或少不可预测的伪随机数的常用推荐方法。但这并不完美。如果您的程序在同一秒内运行两次,您可能会得到相同的序列,因为time()(通常)具有 1 秒的分辨率。典型的 `rand() 实现对于加密使用来说不够;攻击者很容易猜到你会得到什么数字。
还有许多其他的随机数实现。 Linux 系统有两个伪设备,/dev/random 和/dev/urandom,您可以从中读取相当高质量的伪随机字节值。某些系统可能具有random()、drand48() 等功能。并且有很多算法;我听说过关于Mersenne Twister 的好消息。
对于像游戏这样的游戏,您不期望或不关心试图作弊的玩家,srand(time(NULL)) 和 rand() 可能就足够了。出于更严肃的目的,您应该向比我了解更多的人寻求建议。
comp.lang.c FAQ 的第 13 节有一些关于伪随机数生成的非常好的信息。
【讨论】: