【问题标题】:Program is generating same random numbers on each run? [duplicate]程序在每次运行时生成相同的随机数? [复制]
【发布时间】:2011-11-27 08:57:46
【问题描述】:

我刚刚完成了一个扫雷类型游戏的编码,一切都很好,除了每次运行应用程序时,它都会生成相同的数字(我运行了 3 次不同的时间,将输出保存到 3 个文本文件并使用了@987654321 @ 命令在 Linux 中,它没有发现任何差异)。它是由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;
}

【问题讨论】:

    标签: c++ random minesweeper


    【解决方案1】:

    按时间播种(NULL)

    如果是,我看不到。事实上,在您的代码中搜索它不会返回任何内容。如果您没有显式播种,则默认行为与您使用值 1 播种时相同。

    您需要明确声明如下内容:

    srand (time (NULL));
    

    main 的开头某处(并确保您执行此操作一次且仅一次)。

    尽管请记住,这使其依赖于当前时间 - 如果您在同一秒内(或无论您的时间分辨率是什么)启动多个作业,它们将以相同的种子开始。

    来自 C 标准(这些兼容性特性基于 C++):

    srand 函数使用参数作为新的伪随机数序列的种子,这些伪随机数序列将由后续调用 rand 返回。如果随后使用相同的种子值调用 srand,则应重复伪随机数序列。如果在调用 srand 之前调用了 rand,则应生成与第一次调用 srand 时相同的序列,种子值为 1。

    【讨论】:

    • 谢谢,这是我的一个愚蠢的错误。
    • 如果 OP 提交批处理作业,那么这也可能重复。在这种情况下,多个作业实际上是同时启动的。
    • 好点子,@jww,我会为此添加注释。
    【解决方案2】:

    您需要播种随机数。一开始请致电srand()

    【讨论】:

      【解决方案3】:

      要添加其他人的答案,您可以使用 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 具有一些出色的数值运算功能,研究它们是个好主意。至于梅森捻线机,http://en.wikipedia.org/wiki/Mersenne_twister

      【讨论】:

        猜你喜欢
        • 2014-05-07
        • 1970-01-01
        • 1970-01-01
        • 2011-12-06
        • 1970-01-01
        • 2021-11-08
        • 2013-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多