程序每次运行时生成相同的随机数?

4
我刚写完了一个扫雷类型的游戏,除了每次运行应用程序时都生成相同的数字之外,一切都很好(我运行了它三次,将输出保存到三个文本文件中并在Linux中使用diff命令,没有发现任何差异)。它是由time(NULL)种子生成的,所以每次都应该改变,对吧?
以下是我的代码:
main.cpp
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <string>
#include "Minesweeper/box.h"
#include <cstdio>

int main(int argc, char** argv){
using namespace std;
bool gameOver  = false;
int x, y, score = 0;
const int HEIGHT = 10;
const int WIDTH = 10;
unsigned int Time = time(0);

cout << "Welcome to Minesweeper. " << endl;


//setup grid
Box grid[10][10];

for(int i = 0; i < WIDTH; i++)
for(int n = 0; n < HEIGHT; n++){
  unsigned int value = rand() %100 + 1;
  cout << value << endl;
  if(value <= 38){
grid[i][n].setFill(MINE);
//cout << i << "," << n << " is mined." << endl;
  }
  else
grid[i][n].setFill(EMPTY);
}

for(int r = 0; r < WIDTH; r++)
for(int l = 0; l < HEIGHT; l++)
  if(grid[r][l].getFill() == EMPTY)
cout << r << "," << l << " - EMPTY." << endl;
  else if (grid[r][l].getFill() == MINE)
cout << r << "," << l << " - MINE." << endl;

while(!gameOver){
cout << "Enter coordinates (x,y): ";
scanf("%i,%i",&x,&y);
if(grid[x][y].getFill() == MINE)
  gameOver = true;
else{
  cout << "Good job! (You chose " << x << "," << y << ")" << endl;
  score++;
}
}

cout << "You hit a mine! Game over!" << endl;
cout << "Final score: " << score  << endl;
getchar();

return EXIT_SUCCESS;
}
3个回答

9

它由time(NULL)种子生成。

如果是这样,我无法看到它。实际上,在您的代码中搜索此内容将返回空值。如果您没有显式地设定种子,则默认行为与使用值1相同。

您需要明确声明类似于:

srand (time (NULL));

main 的开始处某个地方添加下面的代码(确保只添加一次)。
需要注意的是,这会让随机数生成器依赖于当前时间 - 如果在同一秒内(或你的时间分辨率)启动多个作业,它们将以相同的种子开始。
以下是C标准关于此功能的说明(C++也基于此进行了兼容性处理):
srand 函数使用参数作为一个新的伪随机数序列的种子,以返回后续调用 rand 生成的伪随机数。如果 srand 使用相同的种子值再次被调用,则产生的伪随机数序列也将重复。如果在调用 srand 之前调用 rand,则在使用种子值 1 调用 srand 时将生成相同的序列。

谢谢,那是我犯的一个非常愚蠢的错误。 - airplaneman19
1
如果 OP 提交了一个批处理作业,那么这也可能会导致重复。在这种情况下,多个作业将同时有效地启动。 - jww
好主意,@jww,我会加一条注释来说明这点。 - paxdiablo

1
为了补充其他人的答案,您可以使用Mersenne Twister算法,它是C++11库的一部分。它正在快速成为许多常见软件生成随机数的标准。
例如,这是我编写的函数,我经常在我的其他代码中使用它来生成随机数:
 std::vector<double> mersennetwister(const int& My,const int& Mz,
 const int& Ny,const int& Nz)
 {
 int ysize = (My + 2*Ny + 1);
 int zsize = (Mz + 2*Nz + 1);
 int matsize = ysize*zsize;
 unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
 // Seeding the generator with the system time
 std::mt19937_64 generator (seed);
 // Calling the Mersenne-Twister Generator in C++11
 std::uniform_real_distribution<double> distribution(0,1);
 // Specifying the type of distribution you want
 std::vector<double>  randarray(matsize,0);
 // Saving random numbers to an array
 for (int i=0;i<matsize;++i)
 {
    randarray[i] = distribution(generator); // Generates random numbers fitting the 
    // Distribution specified earlier
 }
 return(randarray);
 } 

总之,C++11拥有一些出色的数值运算特性,值得深入研究。至于Mersenne Twister, http://en.wikipedia.org/wiki/Mersenne_twister


1
你需要使用随机数生成器。在程序开头调用srand()函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接