0

I'm trying to make a Tetris game using the SDL-library. When a new shape appears I want it to be random, so therefore I've tried to make a function that takes a takes a random number between 0 to 4, which is later used to decide what shape that will appear. Here's the function so far:

int EventHandler::setShapeType() {

    if (m_seeded == false) {
        srand(time(NULL) * SDL_GetTicks()); //SDL_GetTicks returns the number of miliseconds since the SDL_library was initialized
        m_seeded = true;
    }

    int shapeType = (int) (((double) rand()/RAND_MAX) * 4.999);

    cout << shapeType << endl;

    return shapeType;
}

m_seeded is a method variable in EventHandler and is set to false in the constructor, so the first if-statement only runs once.

As you can see the function is not complete yet, and the printing of shapeType is solely there for debugging purposes, but so far it should atleast be able to generate a random number... Which it doesn't seem to do. In my main function I made a 10000 iteration loop in which counted how often every number between 0 to 4 was returned, and afterwards printed out the final result as percentage relative to the maximum number of iterations. Here's the result:

  • Zero: 29.8
  • One: 23.9
  • Two: 19.2
  • Three: 14.7
  • Four: 12.4

Now, I thought that for 10000 iterations every number would appear around the same number of times, but they don't! With small differences, this is the result I get every time. I know that rand() in fact just takes numbers from a premade list, and that the "randomness" comes from what seed you use, but shoudn't I get more varied results than what I'm getting? Well, I'm lost, I'd love some help on this.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • 1
    Would you mind posting a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)? – MikeCAT Jun 24 '16 at 14:54
  • @πάνταῥεῖ That may not the right dupe target. The user is calling `srand` conditionally. We just cannot tell if that condition ever happens without an [mcve]. – NathanOliver Jun 24 '16 at 14:57
  • 8
    If this code is executed near the start of your program, it seems like `SDL_GetTicks` could very easily be returning 0 every time you run the program, which means you are getting the same seed (0) every time. I don't see any reason to not just use `time(NULL)` by itself. – Benjamin Lindley Jun 24 '16 at 15:06
  • `` is much nicer, use the stuff in there.http://en.cppreference.com/w/cpp/numeric/random – Mat Jun 24 '16 at 15:16
  • When I want a random range I normally do something like `rand() % range + 1` – Matt Jun 24 '16 at 15:21
  • Which libc implementation is this? I ran your generator against glibc and got very closely equal values for each bucket. srand shouldn't affect the distribution because the LCRNG period is much larger than your 10k test. – Andy Brown Jun 24 '16 at 15:26
  • Something worth watching: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful – Revolver_Ocelot Jun 24 '16 at 15:46
  • Try checking the value of `SDL_GetTicks()` in your debugger (or print it out) every time it is used. That will tell you if a) you are calling `srand()` more than once or b) you are multiplying by zero. As Benjamin said, it might be returning 0. – rossum Jun 24 '16 at 15:49
  • @matt Bad advice, that can lead to [modulo bias](http://stackoverflow.com/q/10984974/2166798). – pjs Jun 24 '16 at 17:24

0 Answers0