Jump to content
  • Advertisement
Sign in to follow this  
Shaitan00

Random not really very Random? [C# 2005]

This topic is 4391 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am experiencing some very odd behavior when using RANDOM to randomly pick a direction for my BOTs to move in (making a game)... Specifically - I have a an object (BOT) that have an object (BRAIN) has a private member - the class BRAIN is responsible for telling the BOT where to go (what direction to move in), typically it is expected to move any a RANDOM direction (defined by MoveDirection)... This is the code I use: Random rand = new Random(); botDirection = (MoveDirection)(rand.Next() % 4); So, this code returns a random choice of MoveDirection (one of 4 possible options: Up,Down,Left, or Right) as expected (so far so good)... And the bots move accordingly (so they move randomly - which is great). Now here is the joke, each object BOT has its own instance of BRAIN (public BRAIN AI = null;) so I would assume that each BOT would move randomly, independent of the other, but I have noticed (been watching for a while, loaded 4 bots to make sure) that they all move in perfect synch. Which leads me to believe the RANDOM keeps returning the same values for each instance of BOT... Coincidence over 20mintes? Why would my Random be the same for each BOT all the time, this code is executed a LOT (each tick they need to determine a new random direction to move in) and yet they all move in the exact same direction all the time... I don't get it ... Should I NOT be using RANDOM? Is there something I am missing? Any ideas, hints, and help would be greatly appreciated, thanks

Share this post


Link to post
Share on other sites
Advertisement
I think you need to search for random seeding.

That is a "random" number generator gets a random number by running a function against an initial "seed" value. If you start with the same (default) seed with each randomizer as is probably happening, then you will get the same series every time.

Share this post


Link to post
Share on other sites
Why do you create a new Random object every time? I would just make it static and use the same Random variable every time. The reason this happens is that the Random() constructor gets seeded with the current time. So what probably happens is that all your Brains work at the same time and thus get seeded with the same value and thus return the same Next(). Solution? Just seed rand once in the constructor and make it static.

Share this post


Link to post
Share on other sites
I'm not sure how Random() works, but you could use rand().

#include <ctime> //include for time()

srand(time(NULL)); //Seeds the rand with time(NULL), call once near the begining of your program.

botDirection = (rand() % 4); //generate a number 0-3

Or...

botDirection = (rand() % 4) + 1; //generate a number 1-4

Just make sure you don't reseed srand(). Only call it once, afterward just get the current number with rand().

Hope that helps, somewhat.

Share this post


Link to post
Share on other sites
Quote:
Original post by Servant of the Lord
I'm not sure how Random() works, but you could use rand().

#include <ctime> //include for time()

srand(time(NULL)); //Seeds the rand with time(NULL), call once near the begining of your program.

botDirection = (rand() % 4); //generate a number 0-3

Or...

botDirection = (rand() % 4) + 1; //generate a number 1-4

Just make sure you don't reseed srand(). Only call it once, afterward just get the current number with rand().

Hope that helps, somewhat.


(S)he's using C#, not C++.

Your problem is seeding; you need to seed the random number generator with a different value each time. You pass the seed to the constructor of the object.

You want to give each it's own Random object so that you can reproduce the behavoir reliably (or make sure the move order is the same) if you want to be able to record your game and play it back later (ala Warcraft and many other RTS games). If you want such functionality, just reseed with the same number (save it in your replay file).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
You want to give each it's own Random object so that you can reproduce the behavoir reliably (or make sure the move order is the same) if you want to be able to record your game and play it back later (ala Warcraft and many other RTS games). If you want such functionality, just reseed with the same number (save it in your replay file).


You could generate same sequences of random numbers with just one instance. I also think that you wouldn't want to rely on random numbers if you want reliability since changing the random number algorithm could break all of your replays.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I used random quit a bit in programming games and I had the same difficulty in some of my games kind of. I went to a wider range of random varibles like instead of 1-4 I would go to 1 to 100 then use the if statement to determine if it is ether 1,2,3, or 4. Some other problems that could be going on is that the class you wrote for random is not efficent. Thats what it sounds like to me because you are little skechy on the details of what you are using the random function for. If you use random in a function then you only need to seed it once then call the class.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shaitan00
I am experiencing some very odd behavior when using RANDOM to randomly pick a direction for my BOTs to move in (making a game)...

Specifically - I have a an object (BOT) that have an object (BRAIN) has a private member - the class BRAIN is responsible for telling the BOT where to go (what direction to move in), typically it is expected to move any a RANDOM direction (defined by MoveDirection)...

This is the code I use:

Random rand = new Random();
botDirection = (MoveDirection)(rand.Next() % 4);


Now here is the joke, each object BOT has its own instance of BRAIN (public BRAIN AI = null;) so I would assume that each BOT would move randomly, independent of the other, but I have noticed (been watching for a while, loaded 4 bots to make sure) that they all move in perfect synch. Which leads me to believe the RANDOM keeps returning the same values for each instance of BOT... Coincidence over 20mintes?

Why would my Random be the same for each BOT all the time, this code is executed a LOT ...

When you call Random() with no parameters, the seed value is the current time. However, timer resolution is large (milliseconds) relative to the time it takes to execute a single statement (microseconds or less). Thus, each instance of your random generator is seeded with the same value, and they therefore all generate the same sequence of numbers.

What you need to do instead is to have a static Random object that is shared amongst all the instances. Then each instance can simply call rand.MoveNext() and be assured of getting an appropriate answer.

hope that helps,

Share this post


Link to post
Share on other sites
The fact that you're not seeding your random number generator is probably your major problem here but it's also worth knowing that using % to generate a small random integer is not a very good way to get an even distribution. Most common PRNGs (Pseudo Random Number Generators) are not as random in their low bits as in their high bits and by using % you're only getting randomness from the low bits. A better method is to cast the random value you get to a float and divide by the maximum value returned by the random number generator cast to a float (usually defined as a constant somewhere) then multiply the resulting floating point value between 0 and 1 by n (4 in your case) and cast back to an int. This will give you a much more random distribution in most cases, though it is a bit more expensive.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!