0

In my c++ code I have a problem. My random drawBlock function which should return xRandom and yRandom is not so random.

void Game::drawBlock() 
{
    int xRandom, yRandom;
    std::cout<<time(NULL) << std::endl;
    xRandom =  (rand () % 620) + 1;
    yRandom =  (rand () % 440) + 1;
    std::cout << "x: " << xRandom << std::endl;
    std::cout << "y: " << yRandom;
    mBlock.setSize(sf::Vector2f(20,20));
    mBlock.setPosition(xRandom,yRandom);
    mBlock.setFillColor(sf::Color::Red);
}

so what basically happens is that the first random number, in this case xRandom isn't really random. When I run the program everything seems fine xRandom gets a random number and yRandom gets a random number. But when I restart the program my xRandom number is almost the same. while my yRandom number changes completely. so for example when I start my code: xRandom = 33 yRandom = 381 when I than re-run my code xRandom = 41 and after re-running it for 10 times is looks something like this: 55,66,84,101,125,140,180,201,234,251 Something strange is that the new xRandom is always more than the last one.

Here is the code were I call srand:

#include <SFML/Graphics.hpp>
#include "Game.h"

int main()
{
    srand(time(0));
    Game game;
    game.run();
    return 0;
}
that guy
  • 404
  • 1
  • 7
  • 15
  • 1
    What have you used as the random number's seed? – PaulG Mar 20 '14 at 15:38
  • 2
    Using [uniform_int_distribution](http://stackoverflow.com/questions/19553265/how-does-modulus-and-rand-work/19553318#19553318) may save you some trouble, there is a short example in the linked answer and I also include a boost example too. – Shafik Yaghmour Mar 20 '14 at 15:40
  • In order to test the random distribution, you should call `game.run()` several times, **not** execute your program several times. – barak manos Mar 20 '14 at 15:41
  • It's random whatever you say, you can't check a probability law with a sampling of 8... – user2076694 Mar 20 '14 at 15:42
  • 2
    Maybe the first call to `rand` returns the seed - in which case you'll get a similar value if you run the program again within a few seconds. In any case, `rand` doesn't give high-quality pseudo-randomness. Use the C++11 `` library if you can. – Mike Seymour Mar 20 '14 at 15:43
  • Exactly. If u want multiple random numbers, call the function repeatedly instead of restarting program. It will be fine then – aghoribaba Mar 20 '14 at 15:48
  • Assuming its a game and not a scientific simulator, does it really matter? – David Mar 20 '14 at 15:49
  • Have you included `#include ` ? – Shravan40 Mar 20 '14 at 15:51
  • 1
    If you really think there's an issue with the first call to `rand()` in your library's implementation you could try calling `rand()` in a short loop, after seeding the generator, to consume the initial value(s). – Blastfurnace Mar 20 '14 at 15:54
  • @Blastfurnace - Just seed the random number generator. As the random number generator is pseudo it will not make any difference ignoring the first x as that list is predictiable. – Ed Heal Apr 09 '14 at 00:36

2 Answers2

1

You're usage of rand() seems to be relatively standard. rand() is infamous as a poor source of random data and perhaps the implementation you're using is simply worse than usual in this particular way. You might find a solution that allows you to use that particular implementation, but I'd suggest moving to another source of random numbers.

C++11 introduced the <random> library which provides random facilities with guaranteed qualities, is more powerful and flexible, and is easier to use. It should be preferred whenever it is available.

To use the <random> library in C++11 you create and seed a source of randomness:

#include <random>

std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 engine(seed);

And then use 'distributions' to take random data from the engine and produce random numbers:

std::uniform_int_distribution<> dist(1, 6);
int die_roll = dist(engine);

For your usage you would probably have the engine be a member of Game:

class Game {
  std::mt19937 engine;
// ...

And then in drawBlock():

xRandom = std::uniform_int_distribution<>(1, 620)(engine);
yRandom = std::uniform_int_distribution<>(1, 440)(engine);
bames53
  • 86,085
  • 15
  • 179
  • 244
0

Here is how I did it:

int a;
srand(time(NULL));
a=rand()%100+1

It worked for me, to generate a random number.