我对我制作的小游戏有疑问。
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int span = 100;
srand(time(0));
int TheNumber = static_cast<double> (rand()) /RAND_MAX * (span -1) +1;
cout << "You need to guess the number between 1 and " << span << endl;
int mynumber;
int numberofAttempts = 0;
do {
cout << ++numberofAttempts <<" Attempt: ";
cin >> mynumber;
if (mynumber > TheNumber)
cout <<"Lower!" << endl;
else if (mynumber < TheNumber)
cout <<"Higher!" << endl;
} while (mynumber != TheNumber);
cout << "SUCESS!!!" << endl;
return 0;
}
游戏应该生成0-100之间的随机数,你应该猜测它。运行此代码15-20次后,相同的数字甚至产生了8次(在我的情况下为2)。
我知道没有绝对的随机数,并且它使用一些数学公式或其他东西得到一个。我知道使用srand(time(0))
使它依赖于当前时间。但是我怎么会让它“更”随机,因为我不希望这些事情发生在我上面提到的。
我第一次运行它的结果是11,在再次运行之后(在猜出正确的数字之后),它仍然是11,即使时间改变了。
答案 0 :(得分:3)
<强> [ADDITION1] 强>
如果你真的希望研究更好的随机数生成,那么这是一个很好的算法:
http://en.wikipedia.org/wiki/Mersenne_twister
请记住,任何“计算机生成”(即数学生成的)随机数只是伪随机数。伪随机意味着虽然算法的输出看起来具有正态分布,但如果知道输入种子,则它们确实是确定性的。真随机数是完全不确定的。
<强> [原稿] 强> 只需尝试下列其中一行:
rand() % (span + 1); // This will give 0 - 100
rand() % span; // this will give 0 - 99
rand() % span + 1; // This will give 1 - 100
而不是:
(rand()) /RAND_MAX * (span -1) +1
另外,不要将结果转换为double,然后放入int。
另见:
http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
回应评论!!! 如果您使用:
rand() / (span + 1);
然后为了获得0到100之间的值,那么rand的输出值确实必须介于0和(100 * 100)之间,并且必须保证这种性质。这是因为简单划分。当rand()产生101 - 201时,值1将基本弹出,当rand()输出值202 - 302等时,2将弹出除法...
在这种情况下,您可能能够以100 * 100的速度逃脱只有10000,并且在32位空间中肯定存在大于此的整数,但通常做分数不允许您采取利用提供的全数字空间的优势!!!
答案 1 :(得分:2)
rand()
存在许多问题。你遇到过其中一个,这就是前几个值不是“随机”的。如果您必须使用rand()
,最好放弃前四个或rand()
的结果。
srand (time(0));
rand();
rand();
rand();
rand();
rand()
的另一个问题是即使在上述黑客攻击之后,低阶位也是非随机的。在某些系统中,最低阶位交替使用0,1,0,1,0,1,...使用高阶位总是更好,例如使用商而不是余数。
其他问题:非随机性(rand()
的大多数实现都失败了许多随机性测试)和短周期。对于所有这些问题,最好的建议是使用rand()
之外的任何东西。
答案 2 :(得分:1)
首先,rand() / RAND_MAX
没有给出介于0和1之间的数字,它返回0.这是因为RAND_MAX在rand()的结果中适合0次。两者都是整数,因此对于整数除法,它不会返回浮点数。
其次,RAND_MAX可能与INT的大小相同。将RAND_MAX与任何东西相乘会产生溢出。