Well I don't really know how to search for the thing I'm looking for. Google gives tons of results, but none which match my criteria.
So I'm asking it here: Is there any known piece of code that can create a number, that is predictable, looks random, and is based on a 'seed' (in my case it's the unix timestamp) and between a specified range?
I want to be able to create weather forecast in a script for a game I'm coding (but I need the C++ code which I can port, I don't think many people here are familiar with 'PAWN' [a.k.a. SMALL] scripting language? :) ). The weather id's vary from 0 to ~100, including some deprecated ID's (so my solution would be to make a array holding valid weather ID's so we don't need to worry about those BAD_ID's, let's not make the function too complicated).
I could possibly make such formula but the problem in the past I had was that the weather was changing too fast (like every second, though I lost the code somewhere :/ ) and for now I'm really out of ideas on how I'm going to make such a formula.
Any suggestions are really appreciated too!
What you really want is a hash function. To limit the range you can use one of the usual tricks (the dirtiest being the remainder operator).
Specifically, you want to hash integers into integers. You can pick up such a function here. I recommend the one titled "Robert Jenkins' 32 bit integer hash function" -- always worked well for me.
You'll end up with something like:
If you want more interesting weather behavior, you can linearly interpolate between time values. You can use Perlin noise with linear combinations of such interpolated noise at differing frequencies and intensities to make some pretty nice behavior. (I've done this with multiplayer RPGs and it works well.)
Obviously a number cannot be both "predictable" and "random" - those are directly contradictory terms.
I'm assuming what you mean is a number that is both deterministic and semirandom.
Luckily for you, this is what pseudorandom number generators (PRNGs) produce: when they are run with a consistent seed, they give you the same output.
So I would recommend setting your seed with
srandom
, then usingrandom() % MAX_VALUE
to get a number between 0 andMAX_VALUE
. If you get a "bad value", just go again. Repeat sans reseeding for as many numbers as you like.I think you can use rand for generating random numbers. However, you can give the same value to srand like say 99 so that your numbers will be random but predictable every time.
If you need a slow changing value you can use a noise function, such as Perlin Noise.
The problem with
srand
andrand
is that only their call signatures (and not the values they generate) are dictated by the C standard. If you need portable and deterministic pseudo-random numbers, you should implement it yourself. Here is a class, written in C++, which is based on one found in Numerical Recipes, and is completely portable. You may instantiate the random number stream with a seed if you'd like to. I hard-code this seed instead of using the time in case I want the same pseudo-random sequence again and again. You can also use theRandomInteger(a,b)
method to get integers on the half-open interval [a,b).Look at the C implementation of the random number generator used by VB6. It's perfect for games because it generates fairly believable random seqeuences but uses a seed and the same seed always generates the same sequence. So in game data files you can save a set of seed values that will give you known (but random-looking) sequences that you can easily reproduce.
Here's an implementation that returns values in a range: