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

Posted

技术标签:

【中文标题】掷骰子程序在每次运行时生成相同的随机数序列【英文标题】:Dice Rolling Program generates the same sequence of random numbers on every run 【发布时间】:2012-02-02 18:36:13 【问题描述】:

我编写了一个程序,该程序可以掷出用户指定边数的骰子。问题是,它太可预测了。

我使用的是 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;

【问题讨论】:

请不要链接到您的代码 - 在此处显示。 在调用 rand() 之前使用 srand() 播种随机数生成器。 time() 是一个不错的种子。 你用的是什么随机数生成器?您当然必须播种,但要告诉您如何,您必须向我们提供更多详细信息。 【参考方案1】:

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

【讨论】:

【参考方案2】:

转到http://www.boost.org 并获取他们的随机数生成器库。这是我见过的最好的随机生成器,特别是对于 c++ 来说,在任何地方都很难找到一个像样的随机生成器。

他们有大量非常棒的库,用于 c++ 中的各种东西,所以我强烈建议浏览它们,但这应该可以解决您遇到的输出过于可预测的问题。只需确保您阅读了有关如何使用它的说明并首先正确地为生成器播种。

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

【讨论】:

【参考方案3】:

首先,CStdLib.Rand 不是一个出色的 PRNG。但是,我对 C++ 的了解还不够,无法知道 C++ 世界中什么是更好的;我会看看推荐用于密码学的 PRNG。对于大多数非安全目的来说,这个应该足够好。

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

【讨论】:

【参考方案4】:

简单回答:

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

详细回答:

默认的随机数生成器 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/

【讨论】:

以上是关于掷骰子程序在每次运行时生成相同的随机数序列的主要内容,如果未能解决你的问题,请参考以下文章

用 Python PyQT5 掷骰子

从 5 次掷骰子中,生成一个范围为 [1 - 100] 的随机数

scratch中的在1到6之间取随机一个数=1是啥意思?

尝试随机掷两个骰子并将总和相加直到达到 21

模拟算法_掷骰子游戏&&猜数游戏

Java方法(DiceProblem)[关闭]