Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random but predictable number generator? [C++]

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!


2 Answers

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:

typedef int Int32;
typedef unsigned int UInt32;

class CRnd
{
    private:
        static const UInt32 INITIAL_VALUE = 0x50000;
        static const UInt32 INCREMENT = 0xC39EC3;
        static const UInt32 MULTIPLIER = 0x43FD43FD;

    private:
        UInt32 m_nRnd;

    public:
        CRnd () { m_nRnd = INITIAL_VALUE; };
        CRnd ( IN UInt32 nSeed ) { m_nRnd = nSeed; };
        virtual ~CRnd () {};

        Int32 Get ( IN Int32 nFrom, IN Int32 nTo )
        {
            if ( nTo < nFrom ) // nFrom should be less than nTo
            {
                Int32 nTmp = nTo;

                nTo = nFrom;
                nFrom = nTmp;
            }
            else if ( nTo == nFrom )
            {
                return ( nTo );
            }

            m_nRnd = ( m_nRnd * MULTIPLIER + INCREMENT ) & 0xFFFFFF;

            float fTmp = (float) m_nRnd / (float) 16777216.0;

            return ( (Int32) ( ( fTmp * ( nTo - nFrom + 1 ) ) + nFrom ) );
        };

        void SetSeed ( IN UInt32 nSeed ) { m_nRnd = nSeed; };
        UInt32 GetSeed () { return ( m_nRnd ); };
};
like image 99
xxbbcc Avatar answered Sep 19 '25 20:09

xxbbcc


Look into srand and rand for starters.

C++11 includes many more advanced algorithms as well, but for basic needs the above two are sufficient.

To keep the numbers within a range of 0 to n, use the % operator.

like image 26
StilesCrisis Avatar answered Sep 19 '25 18:09

StilesCrisis