我编写了一个程序,用一个用户指定的边数滚动模具。问题是,它太可预测了。
我正在使用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;
}
答案 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