The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

CRand

From Allegro Wiki
Jump to: navigation, search

This is a simple random number generator class. The only real feature is that it automatically seeds the random generator and you can have several random series (you can create as many CRand objects as you want).

Maybe someone can implement a pseudo-random number generator, instead of using libc.

libc

Here's a reference implementation of rand() and srand(), directly from the C99 standard. As pointed out by someone on the talk page, the CRand class below won't quite work with it (the 15-bit result of rand() is used as seed the next time, making a really bad random number generator even worse). However, making the _seed variable below a private class variable to CRand for each stream will fix this.

<highlightSyntax language="cpp">

   static unsigned long int _seed = 1;
   #define RAND_MAX 32767
   int rand(void) {
       _seed = _seed * 1103515245 + 12345;
       return (unsigned int)(_seed/65536) % 32768;
   }
   void srand(unsigned int seed) {
       _seed = seed;
   }
</highlightSyntax>

CRand.h

<highlightSyntax language="cpp">////////////////////////////////////////////////////////// // // // rand.h // // // // Random number generation class, using the standard // // C library, // // by Oscar Giner Mart�ez // // o_giner@hotmail.com // // // //////////////////////////////////////////////////////////


class CRand {

  unsigned seed;
  static bool first_time;
  static unsigned global_seed;   // Used for making different
                                 // seeds for each object

public:

  CRand(void);
  CRand(int s);
  // With this constructor, the class will be initialized using
  // the current seed of r
  CRand(CRand& r);
  
  ~CRand(void);
  // Initializes the CRand class. You don't need to call this
  // because the constructor do this for you.
  // If its the first time you call this function in your program
  // the seed will be initialized looking at the time, else
  // the seed will be calculated adding 1 to the previos one,
  // so you can instanciate more than one CRand classes at the
  // same time obtaining different seeds. Adding 1 is not a good way,
       // but it works perfectly with gcc; however I cannot say the same with MSVC...
  void initialize(void);
  // Gets a random number
  int rand(void);
  // Sets the seed
  void set_seed(int s) {seed = s;};
  // Gets the current seed
  int get_seed(void) {return seed;};

};

</highlightSyntax>

CRand.cpp

<highlightSyntax language="cpp">////////////////////////////////////////////////////////// // // // rand.cpp // // // // Random number generation class, using the standard // // C library, // // by Oscar Giner Mart�ez // // o_giner@hotmail.com // // // //////////////////////////////////////////////////////////


  1. include <stdlib.h>
  2. include <time.h>
  1. include "rand.h"

bool CRand::first_time = true; unsigned CRand::global_seed = 0;

CRand::CRand(void) {

  initialize();

}

CRand::CRand(int s) {

  seed = s;

}

CRand::CRand(CRand& r) {

  seed = r.seed;

}

CRand::~CRand(void) { }

void CRand::initialize(void) {

  if (first_time)
  {
     global_seed = time(NULL);
     first_time = false;
  }
  else
  {
     global_seed++;
  }
  seed = global_seed;

}

int CRand::rand(void) {

  srand(seed);
  seed = ::rand();
  return seed;

}

</highlightSyntax>