【问题标题】:How to enforce explicit Randomness with rand() [duplicate]如何使用 rand() 强制执行显式随机性 [重复]
【发布时间】:2013-07-20 21:18:22
【问题描述】:
#include <iostream>
#include <stdlib.h>
#include <ctime>

class Minesweeper {
   public:
       void buildBoards();
       void printTopLvlBoard();
       void printBottomLvlBoard();
       void userEntry(int x, int y);
       void gameOver();
       bool stateGood();
   private:
       static const int CLMN_MAX_SIZE = 5;
       static const int ROW_MAX_SIZE = 5;
       char topLvlBoard[ROW_MAX_SIZE][CLMN_MAX_SIZE];
       char bottomLvlBoard[ROW_MAX_SIZE][CLMN_MAX_SIZE];
       bool gameState;
   };

void Minesweeper::printTopLvlBoard(){
    std:: cout << "Board" << std:: endl;
    for(int i = 0; i < ROW_MAX_SIZE; i++) {
       for(int j = 0; j < CLMN_MAX_SIZE; j++) {
          std::cout << topLvlBoard[i][j];
       }
    std::cout << std::endl;
    }
}

void Minesweeper::buildBoards(){
   for(int i = 0; i < ROW_MAX_SIZE; i++){
       for(int j = 0; j < CLMN_MAX_SIZE; j++){
           bottomLvlBoard[i][j] = 'O';
           topLvlBoard[i][j] = 'x';
       }
   }
   for(int k = 0; k < 5; k++) {
       bottomLvlBoard[**rand()%5**][**rand()%5**] = 'B';
   }
   gameState = true;
}

void Minesweeper::printBottomLvlBoard(){
   for(int i = 0; i < CLMN_MAX_SIZE; i++){
      for(int j = 0; j < ROW_MAX_SIZE; j++){
        std::cout << bottomLvlBoard[i][j];
      }
      std::cout << std:: endl;
   }
}  

void Minesweeper::userEntry(int x,int y){
   char bottomTmp = bottomLvlBoard[x-1][y-1];

   if(bottomTmp == 'O'){
      topLvlBoard[x-1][y-1] = '*';
      bottomLvlBoard[x-1][y-1] = 'C';
   }
   else if(bottomTmp == 'B'){
      gameOver();
   }
}
void Minesweeper::gameOver() {

  std::cout << std:: endl;
  std::cout << "**********************" << std:: endl;
  std::cout << "**********************" << std:: endl;
  std::cout << "*** BOMB BOMB BOMB ***" << std:: endl;
  std::cout << "*** BOMB BOMB BOMB ***" << std:: endl;
  std::cout << "*** BOMB BOMB BOMB ***" << std:: endl;
  std::cout << "*** BOMB BOMB BOMB ***" << std:: endl;
  std::cout << "**********************" << std:: endl;
  std::cout << "**********************" << std:: endl;
  std::cout << std:: endl;

  std::cout << "You have landed on a bomb!" << std:: endl;
  std::cout << std:: endl;

  printBottomLvlBoard();
  gameState = false;
}

bool Minesweeper::stateGood(){
   bool tmpYesNo = (gameState == true) ? true : false;
   return tmpYesNo;
}

有没有通过 rand() 函数强制执行显式随机性?每次我运行这个程序时,我都会在网格上得到相同的可预测的炸弹模式。即使我更改 main() 中的种子,我仍然只能得到大约 3 种模式的变化。

【问题讨论】:

  • 播种是关键。你如何调用 srand()?
  • 嘿! Stack Overflow 上没有那些明显的东西!!

标签: c++ random


【解决方案1】:

首先使用种子初始化伪随机生成器 (PRNG),一个简单的方法是使用当前时间,如下所示。

 #include <ctime>

 // and put the following before calling rand, and where it is only called once
 srand(time(NULL));

即调用srand 的好地方可以是main() 函数的开始。

【讨论】:

  • 并将其放在只调用一次的地方。
【解决方案2】:

Why do I always get the same sequence of random numbers with rand()?

本质上,rand() 没有种子将始终返回相同的伪随机数数组——在这种情况下,种子通常为“1”。带有 fixed 种子的 rand() 也将始终返回相同的伪随机数数组。

【讨论】:

  • 我没有使用固定种子。它包含在我的实现中。可能是我得到了一个非常小的值变化集,即使是播种。
  • @user2069483:如果您不调用srand(),那么您正在使用固定种子;这相当于在程序开始时调用srand(1)srand(time(NULL)) 应该在每次程序运行时给你一个不同的序列,只要你的运行间隔超过 1 秒。
【解决方案3】:

如果您在最初使用不同的 n 值调用 srand(n)(srand() 仅在 main 开始时调用一次)之后在程序中重复运行 rand(),并且基本上您会得到一个小集合的副本当您期望得到更多样化的结果集时,几乎可以保证问题不在于 rand() - 这就是您使用随机数的方式。即,可以使用“真正的随机性”作为算法的一部分,但您的算法仍然倾向于以高概率收敛到一个常见状态(或少数常见状态之一)。

查看您的代码,您没有提供 main() 或描述您打印的时间/内容是给出“相同 3 种模式的变体”,或描述您的 3 种模式的变体究竟意味着什么,或者描述了您希望看到的其他类型的模式。如果没有这些信息,就很难对您的问题提供更多见解。也许这 3 种模式的所有“变化”都是人们期望看到的,而且概率很高。

【讨论】:

  • 仔细查看代码后更新答案
猜你喜欢
  • 2013-04-23
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
  • 1970-01-01
相关资源
最近更新 更多