我正在寻找一种在C ++中快速生成两个随机数的方法。代码用于死亡,需要在滚动时生成随机数。我的代码目前看起来像这样:
Die::Die() {
srand(time(NULL));
}
void Die::roll() {
value = rand() % 6 + 1;
}
如果我使用此代码创建两个对象,则srand()作为静态(非基于实例)函数,将为所有对象生成新种子。我也尝试过这样做:
void Die::roll() {
srand(time(NULL));
value = rand() % 6 + 1;
}
而不是在构造函数中使用它,但如果我快速调用它们如下:
die0->roll();
die1->roll();
他们的价值观通常是平等的。有没有什么方法可以让它每次都随机?感谢你的帮助。 :)
答案 0 :(得分:4)
假设程序运行得足够快,时间(以秒为单位)通常是相同的,这意味着你的种子将是相同的,这意味着你的随机值是相同的。 正如评论者所说,在其他地方做随机种子(比如程序或线程的开头)。
答案 1 :(得分:1)
问题是,如果队列在时间上彼此足够接近,那么你将使用相同的值为rng播种,因此每个种子后得到的第一个值将是相同的。为避免这种情况,您可以确保仅播种一次。例如,您可以从Die类中删除srand,并在第一次使用Die之前的某个时候播种。
或者,如果你不希望Die的使用者负担调用srand的负担,你可以将srand保留在Die的构造函数中,但要防止使用静态bool多次调用它。
Die::Die()
{
static bool seeded = false;
if (!seeded)
{
srand(time(NULL));
seeded = true;
}
}
请注意,此srand仍然可以影响srand()和rand()的其他类,但这可能无关紧要。但是如果你需要在你定义的多个类中使用随机数,你可以考虑创建一个RNG单例来为你生成数字。
答案 2 :(得分:1)
最不容易出错的方法是使用uniform_int_distribution
标头中的random
。这也避免了modulo bias
,这是基本的例子:
#include <iostream>
#include <random>
class Die
{
public:
template <class Generator>
void roll( Generator &g )
{
std::uniform_int_distribution<int> dist(1,6);
std::cout << dist(g) ;
}
private:
} ;
int main()
{
std::random_device rd;
std::mt19937 e1(rd());
Die d1, d2 ;
for (int n = 0; n < 10; ++n) {
d1.roll( e1 ) ;
std::cout << " , " ;
d2.roll( e1 ) ;
std::cout << std::endl ;
}
}
或者,您也可以使用static
成员,正如詹姆斯建议的那样:
class Die
{
public:
Die() {} ;
void roll()
{
std::uniform_int_distribution<int> dist(1,6);
std::cout << dist(e1) ;
}
private:
static std::random_device rd;
static std::mt19937 e1 ;
} ;
答案 3 :(得分:0)
正如其他人所说,你不想更多地重新设置发电机
不止一次。如果Die
是rand
的唯一用户(或者即使它
不是),您可以使用名称空间范围内的变量来播种它:
int seeded = (srand( time( NULL ) ), rand());
这是否是一个好主意取决于;它成功了
不可能复制一段代码进行调试
例如,目的。如果这是一个问题,你会想要1)
记录您使用的种子,2)在命令行中添加一个选项
指定种子;后者意味着从中调用srand
main
。
(另请注意,我已经添加了对rand()
的调用
初始化。在至少一个广泛实施中,
第一次调用rand()
会返回种子,这意味着它可以
非常可预测。)