🔒 Locked
Predictable Randomization
Advertisement
Original Post
I''ve upgraded to Visual C++.NET from an ancient copy of Borland''s Turbo C. I wrote a function that used the "rand" function to generate random numbers from X-Y, but for any given set of X & Y, the function returns the same random variable over and over again, even if I seed the random number generator with the system time!!
For goodness sakes, someone help me out here! How do I generate random numbers that are actually random?
In case you need to know, the function uses the 0-32767 number returned, converts it to a double, rescales it by multiplying it by Y-X+1 and dividing it by 32767, rounds it off, and adds X. (At least I think this is how I wrote it; I''m not typing this post on my own computer.)
Is there a simpler system function, perhaps?
As a fairly recent (started learning C two years ago, C++ this month) convert to Visual C++, I may not know what I''m doing, but this seems like a fairly clear-cut case of poor documentation to me.
Here''s the function:
Here''s the function:
#include <math.h>
#include <stdlib.h>
#include <time.h>
int trueRand(int start, int finish)
{
srand( (unsigned)time( NULL ) );
double scaleConversion=RAND_MAX/(1+finish-start);
int tmpRandom=rand();
tmpRandom=((tmpRandom+start)/scaleConversion)+start-1;
return tmpRandom;
}
Remove that srand call; it''s seeding the random number generator with the same value over and over.
And that''s not a "true" random number generator. This is.
And that''s not a "true" random number generator. This is.
quote:
Original post by DuranStrife
As a fairly recent (started learning C two years ago, C++ this month) convert to Visual C++, I may not know what I''m doing, but this seems like a fairly clear-cut case of poor documentation to me.
The MSDN docs I own say this:
"The srand function sets the starting point for generating a series of pseudorandom integers."
Note the term ''series'', which implies that you call srand once for every X calls of rand. It may not be explicit what you need to do in your situation, but sometimes you do need to call srand several times, so it can hardly say "you must only call srand once".
[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]
quote:
Original post by Kylotan
The MSDN docs I own say this:
"The srand function sets the starting point for generating a series of pseudorandom integers."
Note the term ''series'', which implies that you call srand once for every X calls of rand.
I don''t see how A implies B here.
The docs merely explains what rand does: returns a pseudorandom series, meaning that from any starting seed the random numbers generated will be the same as subsequent calls to rand starting from the same seed. This doesn''t imply that you need to re-seed it every X calls. It wouldn''t hurt your randomness unless you seed it to the same value each time, but it would incur unnecessary overhead.
quote:
It may not be explicit what you need to do in your situation, but sometimes you do need to call srand several times, so it can hardly say "you must only call srand once".
The only times I can think you''d want to call srand are:
- beginning of the program.
- beginning of a "replay" or some function where you want to synchronize the pseudo-random sequence to a prior value.
- beginning of a "match" in a multiplayer game where it''s important that random events are generated in the same way on each player''s computer.
quote:
Original post by Stoffel
This doesn''t imply that you need to re-seed it every X calls.
What I said was unclear. I didn''t mean that you need to re-seed it every X calls, I meant that there is a 1 to many relationship between srand and rand calls, as opposed to the 1 to 1 relationship that so many new programmers mistakenly use.
quote:
The only times I can think you''d want to call srand are:
- beginning of the program.
- beginning of a "replay" or some function where you want to synchronize the pseudo-random sequence to a prior value.
- beginning of a "match" in a multiplayer game where it''s important that random events are generated in the same way on each player''s computer.
I use it to get reproducable ''random'' number sequences, meaning that someone with a 1% lockpicking skill on my RPG can''t just try 100 times (or thereabouts) and be sure to succeed.
[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]
quote:
Original post by Kylotan
I use it to get reproducable ''random'' number sequences, meaning that someone with a 1% lockpicking skill on my RPG can''t just try 100 times (or thereabouts) and be sure to succeed.
Very nice, hadn''t thought of that application. That''s pretty ingenious.
Note that if a player has 1% lockpicking chance, it can mean three things:
1°/ If he finds a door, and tries to lockpick it 100 times and be sure to get it open.
2°/ If he finds 100 doors, he will be able to open only one of them.
3°/ You skipped the wrong mathematics course.
Cheating on the player will get the player angry, even if he doesn''t know it. Instead of preventing the player from opening the door JUST because you don''t want him to open the door, prevent him by telling him his lockpick is broken.
Moreover, if he cannot open a door just by lockpicking it 100 times, then his lockpicking chance is less than 1%. If you tell him it IS 1%, you''re just feeding the player false information. And if you''re not USING that percentage anyway, why do you show it? Wouldn''t it be easier and less rude to the player to use fuzzy values (for instance Lockpicking LVL 3)?
This is just the way I''m being frustrated when playing Diablo2: having 95% chances hitting some monster, and having 20-30 misses in a row against it...
Not so cheerful, ToohrVyk.
1°/ If he finds a door, and tries to lockpick it 100 times and be sure to get it open.
2°/ If he finds 100 doors, he will be able to open only one of them.
3°/ You skipped the wrong mathematics course.
Cheating on the player will get the player angry, even if he doesn''t know it. Instead of preventing the player from opening the door JUST because you don''t want him to open the door, prevent him by telling him his lockpick is broken.
Moreover, if he cannot open a door just by lockpicking it 100 times, then his lockpicking chance is less than 1%. If you tell him it IS 1%, you''re just feeding the player false information. And if you''re not USING that percentage anyway, why do you show it? Wouldn''t it be easier and less rude to the player to use fuzzy values (for instance Lockpicking LVL 3)?
This is just the way I''m being frustrated when playing Diablo2: having 95% chances hitting some monster, and having 20-30 misses in a row against it...
Not so cheerful, ToohrVyk.
If you make 100 attempts, each with a 1% probability of success, then there should be about a 63.4% chance that you succeed at least once.
huh?!
beer hunter you need to show me the math on that one!
beer hunter you need to show me the math on that one!
Chances of failure = 0.99
Chances of 100 failures in a row = 0.99100
Chances of succeeding at least once = 1 - 0.99100 = about 63.4%
Chances of 100 failures in a row = 0.99100
Chances of succeeding at least once = 1 - 0.99100 = about 63.4%
thank you.
obviously i have to take statistics/probability before i get out of school.
obviously i have to take statistics/probability before i get out of school.
quote:
Original post by ToohrVyk
Note that if a player has 1% lockpicking chance, it can mean three things:
1°/ If he finds a door, and tries to lockpick it 100 times and be sure to get it open.
If I flip a coin twice, am I guaranteed to get heads once? If I roll a six-sided die six times, am I guaranteed a four?
Read the first chapter of any introductory stats textbook.
Don''t listen to me. I''ve had too much coffee.
The function srand shouldn't act this way, since the system time is constantly changing, but moving the srand call to the beginning of main did indeed fix my problem. Many thanks to Beer Hunter!!
Oh, and by the way, the principle Beer Hunter showed comes greatly in handy in pen & paper roleplaying games that list default encounter chances per hour for certain terrain types. Just take the chance of NOT being attacked in a given hour, ^24 it, and subtract from 100 to get the % chance of being attacked at least once in a 24-hour period. Understanding this concept of probability also comes greatly in handy when creating balanced statistics rules for a computer RPG.
[edited by - DuranStrife on September 13, 2002 9:19:27 PM]
Oh, and by the way, the principle Beer Hunter showed comes greatly in handy in pen & paper roleplaying games that list default encounter chances per hour for certain terrain types. Just take the chance of NOT being attacked in a given hour, ^24 it, and subtract from 100 to get the % chance of being attacked at least once in a 24-hour period. Understanding this concept of probability also comes greatly in handy when creating balanced statistics rules for a computer RPG.
[edited by - DuranStrife on September 13, 2002 9:19:27 PM]
The value returned by time only changes once per second.
quote:
Original post by Anonymous Poster
And if you call srand before every call to rand you are limiting the non-repeating length of the random sequence to the maximum size of the parameter to srand (an unsigned int IIRC). rand can produce longer non-repeating sequences than that if srand is only called once.
Please ignore this insane statement.
quote:
Original post by Kylotan
I use it to get reproducable ''random'' number sequences, meaning that someone with a 1% lockpicking skill on my RPG can''t just try 100 times (or thereabouts) and be sure to succeed.
I don''t get it. Wouldn''t you get the same results with any random number generator? What''s the use of srand there? To get ''reproducable'' numbers? Why would you want that?
Cédric
quote:
Original post by Kylotan
I use it to get reproducable ''random'' number sequences, meaning that someone with a 1% lockpicking skill on my RPG can''t just try 100 times (or thereabouts) and be sure to succeed.
quote:
Original post by cedricl
I don''t get it. Wouldn''t you get the same results with any random number generator? What''s the use of srand there? To get ''reproducable'' numbers? Why would you want that?
I am in the same boat as cedric. Can you please give a little more explanation?
In most D&D house rules I know of, if you fail at picking a lock or disarming a trap, you can''t try again. Using the method Kylotan describes, you can implement this easily without having to track which traps or doors a player has tried already, as long as each object has a unique ID. Each time an attempt is made, the RNG is seeded with the object''s unique ID. This assures that the same RN will be generated for each try.
Using this method, if a poor thief with 1% lockpick skill was presented with 100 doors, the odds are that he''d only be able to pick 1 of the locks. No matter how many times he tries, he will never be able to open any of the other doors. Likewise, if a thief has a 90% lockpicking skill, odds are that around 10 of the doors simply will not open for him.
Using this method, if a poor thief with 1% lockpick skill was presented with 100 doors, the odds are that he''d only be able to pick 1 of the locks. No matter how many times he tries, he will never be able to open any of the other doors. Likewise, if a thief has a 90% lockpicking skill, odds are that around 10 of the doors simply will not open for him.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement