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

发布于 2024-12-07 12:51:39 字数 1692 浏览 0 评论 0原文

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

I just finished coding a Minesweeper type game, and everything's good except for that each time I run the application, it generates the same number (I ran it 3 different times, saved the output to 3 text files and used the diff command in Linux, it didn't find any differences). It's seeded by time(NULL) so it should change every time, right?

Here's my code:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梨涡少年 2024-12-14 12:51:39

按时间播种(NULL)

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

您需要明确声明类似以下内容:

srand (time (NULL));

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

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

来自 C 标准(C++ 的这些兼容性功能基于该标准):

srand 函数使用参数作为后续调用 rand 返回的新伪随机数序列的种子。如果随后使用相同的种子值调用 srand,则应重复伪随机数序列。如果在对 srand 进行任何调用之前调用 rand,则应生成与首次使用种子值 1 调用 srand 时相同的序列。

It's seeded by time(NULL)

If it is, I can't see it. In fact, a search for it in your code returns nothing. The default behaviour, if you don't explicitly seed, is the same as if you had seeded it with the value 1.

You need to explicitly state something like:

srand (time (NULL));

at the start of main somewhere (and make sure you do this once and once only).

Though keep in mind this makes it dependent on the current time - if you start multiple jobs in the same second (or whatever your time resolution is), they'll start with the same seed.

From the C standard (on which C++ is based for these compatibility features):

The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1.

め七分饶幸 2024-12-14 12:51:39

您需要播种随机发生器。在开头调用 srand() 。

You need to seed randomizer. Call srand() at the beginning.

笙痞 2024-12-14 12:51:39

要添加其他人的答案,您可以使用 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

To add to the answers by others, you can use the Mersenne Twister Algorithm, which is a part of the C++11 library. Its fast becoming a standard in many common softwares to generate random numbers.

For example, this is the function I wrote, which I use often to generate random numbers in my other codes:

 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);
 } 

Bottomline: C++11 has some excellent features for numerical operations and it would be a good idea to look into them. As for the Mersenne Twister, http://en.wikipedia.org/wiki/Mersenne_twister

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文