I have a function which is supposed to generate a random number depending of the size of a vector. But each time I execute my program, the patterns are the same 1->1->1->0
but my array can contains 0-4
value.
std::pair<int, int> Maze::getDirection(int x, int y)
{
std::vector<std::pair<int, int>> location;
if (m_maze[x 1][y] == '*')
location.emplace_back(std::make_pair(x 1, y));
if (m_maze[x - 1][y] == '*')
location.emplace_back(std::make_pair(x - 1, y));
if (m_maze[x][y 1] == '*')
location.emplace_back(std::make_pair(x, y 1));
if (m_maze[x][y - 1] == '*')
location.emplace_back(std::make_pair(x, y - 1));
std::cout << "Random number: " << std::rand() % location.size() << "\n" << "Size of vector: " << location.size() << std::endl;
std::srand(std::time(nullptr));
return location.at(std::rand() % location.size());
}
CodePudding user response:
std::srand(std::time(nullptr));
reseeds the rand()
PRNG every time you call the function. If you call it many times during one second, it'll get the same seed and restart the number cycle for that seed.
You should only call std::srand()
once during the whole program run. There are also better tools than rand()
and %
to get random numbers. Since C 11, you can use one of the PRNG:s in <random>
, like std::mt19937
combined with a std::uniform_int_distribution
to get numbers in the range you want - and it will not be biased like using %
is for most cases.
Example:
#include <random>
// A seeded PRNG from the standard library since C 11. Use the same generator
// everywhere in your program. If your program is multithreaded, make it `thread_local`:
std::mt19937 gen{std::random_device{}()};
std::pair<int, int> Maze::getDirection(int x, int y) {
std::vector<std::pair<int, int>> location;
// note: make_pair is not needed when using emplace_back to create a pair:
if (m_maze[x 1][y] == '*') location.emplace_back(x 1, y);
if (m_maze[x - 1][y] == '*') location.emplace_back(x - 1, y);
if (m_maze[x][y 1] == '*') location.emplace_back(x, y 1);
if (m_maze[x][y - 1] == '*') location.emplace_back(x, y - 1);
if(location.empty()) return {-1, -1}; // dead end
// A distribution to scale the PRNG:s random numbers
// from 0 to location.size() - 1
std::uniform_int_distribution<unsigned> dist(0, location.size() - 1);
auto random_number = dist(gen); // generate the number
std::cout << "Random number: " << random_number << '\n'
<< "Size of vector: " << location.size() << '\n';
return location[random_number];
}
CodePudding user response:
rand function can follow the same pattern against the number of iterations so what it cannot randomized as well. Use srand to make them random output and no pattern following algorithm.