since we can't use rand() for replacing RANDOM_LONG() and RANDOM_FLOAT() and thus save costy engine calls each time, because rand() only returns short integers and not longs, a portable, fast, and self-contained random number generator is something nice indeed
irwigo,

mateys
Code:
// RACC - AI development project for first-person shooter games derived from Valve's Half-Life
// (http://racc.bots-united.com/)
//
// The game to engine interfacing code is based on the work done by Jeffrey 'botman' Broome
// (http://planethalflife.com/botman/)
//
// This project is partially based on the work done by Eric Bieschke in his BSDbot
// (http://gamershomepage.com/csbot/)
//
// This project is partially based on the work done by Brendan "Spyro" McCarthy in his ODD Bot
// (http://oddbot.hlfusion.com/)
//
// This project is partially based on the work done by Alistair 'eLiTe' Stewart in his TEAMbot
// (http://www.planethalflife.com/teambot/)
//
// Rational Autonomous Cybernetic Commandos AI
//
// lrand.cpp
//
#include "racc.h"
// maximum value returned by our number generator (2^31 - 1 = 0x7FFFFFFF)
#define LRAND_MAX 2147483647L
long lseed; // our random number generator's seed
void lsrand (unsigned long initial_seed)
{
// this function initializes the random seed based on the initial seed value passed in the
// initial_seed parameter. Since random seeds are usually initialized with the time of day,
// and time is a value that changes slowly, we bump the seed twice to have it in a more
// random state for future calls of the random number generator.
lseed = (long) initial_seed; // fill in the initial seed of the random number generator
lseed = lrand (); // bump it once
lseed = lrand (); // bump it twice
return; // that's all folks
}
long lrand (void)
{
// this function is the equivalent of the rand() standard C library function, except that
// whereas rand() works only with short integers (i.e. not above 32767), this function is
// able to generate 32-bit random numbers. Isn't that nice ?
// credits go to Ray Gardner for his fast implementation of minimal random number generators
// http://c.snippets.org/snip_lister.php?fname=rg_rand.c
static unsigned long lrand_lo, lrand_hi;
// compose the two 16-bit parts of the long integer and assemble them
lrand_lo = 16807 * (long) (lseed & 0xFFFF); // low part
lrand_hi = 16807 * (long) ((unsigned long) lseed >> 16); // high part
lrand_lo += (lrand_hi & 0x7FFF) << 16; // assemble both in lrand_lo
// is the resulting number greater than LRAND_MAX (half the capacity) ?
if (lrand_lo > LRAND_MAX)
{
lrand_lo &= LRAND_MAX; // then get rid of the disturbing bit
lrand_lo++; // and increase it a bit (to avoid overflow problems, I suppose)
}
lrand_lo += lrand_hi >> 15; // now do twisted maths to generate the next seed
// is the resulting number greater than LRAND_MAX (half the capacity) ?
if (lrand_lo > LRAND_MAX)
{
lrand_lo &= LRAND_MAX; // then get rid of the disturbing bit
lrand_lo++; // and increase it a bit (to avoid overflow problems, I suppose)
}
// now we've got our (pseudo-)random number.
lseed = (long) lrand_lo; // put it in the seed for next time
return (lseed); // and return it. Yeah, simple as that.
}
long RandomLong (long from, long to)
{
// this function returns a random integer number between (and including) the starting and
// ending values passed by parameters from and to.
if (to <= from)
return (from);
return (from + lrand () / (LRAND_MAX / (to - from + 1)));
}
float RandomFloat (float from, float to)
{
// this function returns a random floating-point number between (and including) the starting
// and ending values passed by parameters from and to.
if (to <= from)
return (from);
return (from + (float) lrand () / (LRAND_MAX / (to - from)));
}
// "Anyone who consider arithmetic means of producing random number is,
// of course, in a state of sin"
// -- John Von Neumann
