-1

I am trying to get a random value, but that doesn't work.

I use this for exemple.

  srand(time(NULL) ^ getpid());

  int a = rand() % 100;

I get a random value the first time, but every other time I call rand(), I get the same value.

My full code :

Worms::Worms(std::string const& name, Ogre::SceneManager *scene,
  Ogre::ColourValue &color, unsigned char hp) :
  _name(name), _hp(hp), _scene(scene), _color(color)
{
  srand(time(NULL) ^ getpid());
  std::cout << "creating worms" << name << std::endl;
  std::cout << color << std::endl;
  this->_ent = scene->createEntity(name, "Worm.mesh");
  this->generatePosition();
  this->setColor(color);
}

void                            Worms::generatePosition()
{
  int a = rand() % 10;
  std::cout << a << std::endl;
  Ogre::Vector3 pos(rand() % 800 + 100 , 450, 0);
  std::cout << pos << std::endl;
  this->_node = this->_scene->getRootSceneNode()->createChildSceneNode(this->_name);
  this->_node->attachObject(this->_ent);
  this->_node->showBoundingBox(true);
  this->_node->scale(_node->getScale() * 4);
  _node->rotate(Ogre::Vector3::UNIT_X, Ogre::Degree(90));
  _node->rotate(Ogre::Vector3::UNIT_Z, Ogre::Degree(90));
  _node->setPosition(pos);
}

And the output :

4
Vector3(498, 450, 0)
creating worms K04L4_1
creating wormsK04L4_1 Captain_2
ColourValue(1, 0, 0, 0)
4
Vector3(498, 450, 0)
creating worms K04L4_1
creating wormsK04L4_1 Captain_3
ColourValue(1, 0, 0, 0)
4
Vector3(498, 450, 0)
creating worms K04L4_1
ok
creating wormsOP3X_2 Pride_1
ColourValue(0, 1, 0, 0)
4
Vector3(498, 450, 0)
creating worms OP3X_2
creating wormsOP3X_2 Captain_2
ColourValue(0, 1, 0, 0)
Dimitri Danilov
  • 1,338
  • 1
  • 17
  • 45
  • 1
    Are you calling `srand(time(NULL) ^ getpid());` more than once? If you call `srand()` with the same value from `time()`, that will reset the "random" number generation. – Andrew Henle May 18 '16 at 10:00
  • 4
    `rand()` is ---deprecated--- old and ugly. Consider using `` instead. – Bartek Banachewicz May 18 '16 at 10:00
  • 4
    Fyi, Unless there is only ONE `Worms` object *ever* created in your process (and judging by your output, that is NOT the case), that `srand` does not belong in that constructor; it belongs in a only-executed-once-ever block of code, usually the head of `main()`. And I concur with Bartek completely. [``](http://en.cppreference.com/w/cpp/numeric/random) is what's for dinner for modern C++ programs, and I *strongly* encourage it. – WhozCraig May 18 '16 at 10:01
  • 2
    [See related question](https://stackoverflow.com/questions/6729214/rand-function-returns-same-values-when-called-within-a-single-function-c) and consider how it applies in your situation. – WhozCraig May 18 '16 at 10:09
  • Please also read about [Minimal, Complete, Verifiable Examples](http://stackoverflow.com/help/mcve). It's easy to demonstrate this problem with only a few lines of *complete* code that anyone could compile. And the point in question has nothing to do with ogre. – HostileFork says dont trust SE May 18 '16 at 10:15

2 Answers2

1

I was using srand() more than one time in my program, now I call it once in my main() function and that works fine.

Dimitri Danilov
  • 1,338
  • 1
  • 17
  • 45
0

time(NULL) only has second resolution so if your function is called within the same second it will always use the same seed. Try GetTickCount() for millisecond resolution or pass microsecond ticks into srand()

using namespace std::chrono;
auto ticks = time_point_cast<microseconds>(system_clock::now()).time_since_epoch().count();

The downcast from 64 to 32 bits (srand() takes 32 bit argument) is specific to the compiler but it usually discards the high order bits which is what you to want to get a more random seed.

As you said, you can call srand() once and then keep calling rand(). You'll then step through the entire pseudorandom sequence.

John D
  • 1,627
  • 1
  • 11
  • 10
  • I am puzzled why you recommend `std::chrono` to replace `std::time` and don’t make the logical step of recommending `std::random` instead of `std::srand`. – Konrad Rudolph May 18 '16 at 11:13
  • Excellent point. The bugbears of pseudorandom number generators are short cycles and unsatisfactory randomness. I haven't used `std::random` so can't comment on it. I worked with statisticians a long time ago and they rolled their own PNG's so they could guarantee a decent cycle length before the sequence repeated and to pass a range of statistical randomness tests. – John D May 18 '16 at 12:08