View Single Post
Portable, self-contained replacements for RANDOM_STUFF()
Old
  (#1)
Pierre-Marie Baty
Roi de France
 
Pierre-Marie Baty's Avatar
 
Status: Offline
Posts: 5,049
Join Date: Nov 2003
Location: 46°43'60N 0°43'0W 0.187A
Default Portable, self-contained replacements for RANDOM_STUFF() - 07-01-2004

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



RACC home - Bots-United: beer, babies & bots (especially the latter)
"Learn to think by yourself, else others will do it for you."

Last edited by Pierre-Marie Baty; 09-01-2004 at 00:17.. Reason: Fixed bugs, fixed comments
  
Reply With Quote