0

I have an enemy class called Slime and each slime travels down the path (like a tower defense game) and I'm trying to get a random number (which will tell the slime when to change directions for the path change). But I tried it with using 3 Slimes and they all end up with the same random numbers. My enemy class has this code in it to generate random numbers for x and y:

Enemy::Enemy(Level* level, float x, float y, float speed, int direction, int width, int height)
    :
    Entity(level, x, y, width, height), // Each enemy is an entity
    speed(speed),
    direction(direction)
{
    srand((unsigned)time(0));

    rangeX = (level->GetTileWidth() * level->GetScale() - width * level->GetScale()) - (width * level->GetScale()) + 1;
    rangeY = (level->GetTileHeight() * level->GetScale() - height * level->GetScale()) - (height * level->GetScale()) + 1;

    randNumX = (rand() % rangeX) + (width * level->GetScale());
    randNumY = (rand() % rangeY) + (height * leel->GetScale());
}

That code is being called whenever I create a new Slime object. I'm testing with three different slimes and they all give me the same random numbers. When I restart it, they're different numbers than the original, but all three slimes still have that same random numbers. Am I doing something wrong? Should I be seeding the rand outside of this class so it's only called once? And the rangeX and rangeY just give me a number within the path so no enemy is on the grass or hanging off the path.

Vince
  • 2,596
  • 11
  • 43
  • 76
  • 2
    You appear to be initializing them all with the same seed. Seed once in your main, then don't seed again unless you have good reason to do so. – Carcigenicate Jul 18 '17 at 21:01
  • 1
    `rand() % rangeX` is a terrible, terrible way to get a uniformly distributed integer, for at least two reasons. Do some research. – Buster Jul 18 '17 at 21:02
  • 1
    Modern C++ provides rich random number generator. Why you use `srand((unsigned)time(0));` and `rand()`. – CroCo Jul 18 '17 at 21:02
  • Start by reading [here](http://en.cppreference.com/w/cpp/numeric/random) and watch [this](https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful). – Jesper Juhl Jul 18 '17 at 21:15

2 Answers2

1

You are re-seeding rand() to the same value every time you create a new Slime object. This means that rand() produces the same number for each Slime.

If you only seed rand() once at the beginning of the program (in the main), you'll get different values.

  • 1
    You should really abandon `rand()`. It doesn't generate random numbers. – CroCo Jul 18 '17 at 21:12
  • @CroCo -- neither does any other pseudo-random number generator. But `rand()` is adequate for many purposes, including this one. – Pete Becker Jul 18 '17 at 21:14
  • 1
    @PeteBecker, nonetheless, `rand()` is really really bad and fortunately there are some _standard_ alternative random number generators. Saying `rand()` is adequate is a scary thought. – CroCo Jul 18 '17 at 21:20
  • @Pete Becker `rand` is *far from adequate* for almost *any* purpose. Example: the commercial product I work on *used* to use it to generate session IDs - they were so bad that I actually noticed (without knowing the implementation at that point) that there were patterns in the values. – Jesper Juhl Jul 18 '17 at 21:23
  • @JesperJuhl -- egad! Let's make sure that these Slime creatures have cryptographically secure movement patterns! Seriously, though, citing examples where the result of using `rand()` was not adequately random (and giving you the benefit of the double that the problem was **entirely** because of the use of `rand()` and not because of the **way it was used**) does not mean that it's inappropriate here. But let's not pull this any farther down that rathole. – Pete Becker Jul 18 '17 at 21:26
  • @Pete Becker while it *may* not matter for the "slime creatures" there's (in my oppinion) no reason to *ever* use as poor random numbers as `rand` generates when there are better options readily available - not saying they need to be cryptographically safe, but they are better and just as available as `rand` - so why on earth use `rand` - ever? – Jesper Juhl Jul 18 '17 at 21:32
  • @JesperJuhl -- because it's simple, and because it's what the original question is about. Part of teaching people is to engage them in solutions; telling them that what they've done is unusable doesn't engage, it alienates. Again: `rand()` is adequate for what's behind done here, and insisting that a beginner rethink their use of `rand()` just adds more complexity to what they're doing, and for some, builds the impression that programming is too hard. – Pete Becker Jul 18 '17 at 21:37
  • @Pete Becker - we may very well "agree to disagree" (and that's fine), but *I* believe we should always be teaching the *better option*. And yes, programming *is* hard; beginners might as wełl learn that now rather than later - and weeding out some of the cruft wouldn't hurt either - there are too many people in this field who really should not be here. – Jesper Juhl Jul 18 '17 at 21:47
-1

Lose the srand((unsigned)time(0));. Do that only once when your current thread first starts.

If you really need each one of your objects to contain its own random number generator, then either equip each one of your objects with an instance of a class that implements such a random number generator, or roll your own; you will find some good ideas here: https://stackoverflow.com/a/1640399/773113

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 1
    Or only once, when the program starts. – Pete Becker Jul 18 '17 at 21:01
  • @CroCo yes, that's why I added the pointer to the Q&A with roll-your-own random number generators. – Mike Nakis Jul 18 '17 at 21:06
  • 1
    @Mike Nakis one should *not* "roll-your-own random number generators". One should use the fine ones that modern C++11 and later provide [in the standard library](http://en.cppreference.com/w/cpp/numeric/random). – Jesper Juhl Jul 18 '17 at 21:18
  • @JesperJuhl yes. I provided for that too, in my answer. But rolling your own is also always an option. – Mike Nakis Jul 18 '17 at 21:29