2

I created a class MyRandomto roll a die on a uniform distribution, given the range as input:

MyRandom.cpp

#include "MyRandom.h"

MyRandom::MyRandom(){
    gen.seed(static_cast<unsigned int>(std::time(0)));
}


int MyRandom::die(int min, int max){

    boost::uniform_int<> dist(min, max);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > role(gen, dist);
    int result = role();
    role.engine().seed();
    role.distribution().reset();
    return result;
}

main.cpp

std::cout <<  myRandom.die(0, 8) << std::endl; 
std::cout <<  myRandom.die(0, 8) << std::endl;
std::cout <<  myRandom.die(0, 8) << std::endl;
std::cout <<  myRandom.die(0, 8) << std::endl;
std::cout <<  myRandom.die(0, 8) << std::endl;
std::cout <<  myRandom.die(0, 8) << std::endl;
std::cout <<  myRandom.die(0, 8) << std::endl;

I keep getting the same number (except the first one, so my reset somewhat works). Obviously, I am not seeding this correctly. I tried to add the reset() as suggested here without success. What am I missing?

Community
  • 1
  • 1
Béatrice Moissinac
  • 934
  • 2
  • 16
  • 41
  • 2
    Seed only once, not every time you're generating a random number. – πάντα ῥεῖ Jul 24 '16 at 02:58
  • It worked. I misunderstand the answer from the linked answer. It solved my problem for the consecutive calls, but not the complete problem, I need to edit my question. – Béatrice Moissinac Jul 24 '16 at 03:01
  • Actually I figured it out. I was passing an object MyRandom myRandom = MyRandom() by value and not by reference, which causes the series of roll to be identical, because it was a copy of the generator, with the same seed :) – Béatrice Moissinac Jul 24 '16 at 03:07

1 Answers1

0

The usual thing that goes wrong is something like this:

std::generate_n(out_iterator, 10, my_random);

This copies the my_random object complete with state. Same thing can happen with lambdas:

MyRandom my_random;
std::generate_n(out_iterator, 10, [=] { return my_random.die(0,8); });

What you want is pass the engine by referece, either doing

std::generate_n(out_iterator, 10, std::ref(my_random));

or

MyRandom my_random;
std::generate_n(out_iterator, 10, [&my_random] { return my_random.die(0,8); });
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Yes, my seeding was wrong and I was passing it by value instead of reference, (that's not shown in the small sample provided - should I edit it?) and thus I was rolling identical series of rolls because i would essentially start with the same copied random dice. – Béatrice Moissinac Jul 25 '16 at 15:57
  • 1
    You could edit it of course. That way it might be more useful to others trying to recognize their problem from your question :) – sehe Jul 25 '16 at 16:27