骰子滚动程序在每次运行时生成相同的随机数序列

时间:2012-02-02 18:36:13

标签: c++ windows random mingw codeblocks

我编写了一个程序,用一个用户指定的边数滚动模具。问题是,它太可预测了。

我正在使用CodeBlocks IDE,编译器是GCC。该程序可以很好地编译为调试和发布版本,但无论我选择什么构建选项,可执行文件每次运行时都会返回相同的值。我不能拥有它,因为它的预期用途是作为桌面RPG工具,如果智能玩家知道掷骰子的模式,那么智能玩家就会相对容易作弊。

解决此问题的最简单方法是什么?

这是来源:

#include <iostream>     /* for input and output */
#include <cstdlib>      /* for random numbers */

using namespace std;

void rolldie() {
    cout << "How many sides to the die?" << endl << "D";
    int die;
    cin >> die;
    int roll = rand() % die +1;
    cout << endl << "The die rolled " << roll << endl << endl <<  "Roll another? (Y for yes, anything else for no; Capitalization counts) ";
}

int main() {
    rolldie();
    char again;
    cin >> again;
    while (again == 89) {
        rolldie();
        cin >> again;
    }
    return 0;
}

4 个答案:

答案 0 :(得分:8)

您没有为随机数生成器播种。我不会下载你的zip文件,但由于你使用的是MinGW,我猜你可能想看看srandom(3)srand(3)

答案 1 :(得分:2)

嗯,首先,CStdLib.Rand不是一个伟大的PRNG。但是,我不太了解C ++,不知道C ++世界中哪些更好;我会看看推荐用于密码学的PRNG。这个应该适用于大多数非安全目的。

更重要的是,你还没有“播种”PRNG。这不会像某些其他语言的内置PRNG(如.NET)那样自动发生。如果它没有播种,则种子总是恒定的(可能为零),因此PRNG算法产生的数字流将始终相同。最常见的种子将基于当前时间(最好是“滴答”分辨率,因此很难准确猜出呼叫检索到的毫秒的几分之一);种子数据的其他好的来源包括鼠标光标的位置,最后访问的RAM或HDD的地址,或者从附加设备获得的真正随机数据(在线赌场的服务器通常具有提供实际随机环境数据的真实RNG设备可以用来播种PRNG)。

答案 2 :(得分:2)

转到http://www.boost.org并获取随机数生成器库。它是我见过的最好的随机发生器,特别是对于c ++,在任何地方都很难找到合适的。

他们有很多真正令人敬畏的库用于c ++中的各种各样的东西,所以我强烈建议浏览它们,但这应该可以解决你输出的问题太可预测了。只需确保您已阅读有关如何使用它的说明并首先正确播种发电机。

对于种子用于随机生成器的内容,在c ++中使用的常用方法是time(NULL)(在time.h或ctime中找到)。这只返回一个数字,表示自1970年1月1日以来的当前时间(以秒为单位)。由于每次运行程序时它将返回不同的值,它对于更简单的随机数很有用,如果你将它与boost的随机生成器结合使用,你的输出应该是看起来不错。

答案 3 :(得分:0)

简单回答:

您希望每次使用某些来源的输入为您的随机数生成器播种,无论是系统(如时间),用户,文件等。

详细答案:

默认的随机数生成器rand()在大多数情况下都非常平庸,但请参阅此内容以获取有关rand的更详细答案:What's the Right Way to use the rand() Function in C++?

我的建议:

我的公司使用随机数字,这些数字每天都要求不可预测,并且他们使用Mersenne Twister算法的变体,并且在游戏中使用时,你会发现它的表现绰绰有余。

作为一个额外的好处,它已经以各种形式在C和C ++中实现,因此将它集成到任何项目中非常简单。

例如:http://www-personal.umich.edu/~wagnerr/MersenneTwister.html

或:http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/