Removing randomness for testing

Normally, games have some sort of randomness. This makes it difficult to test because each time you play the game a different set of events occur.

I had this idea to have a switchable random number class. Normally, the class returns a random number, but when the test flag is set, it returns numbers inĀ  a pre determined sequence.
Here’s the code:

class RandNumber
{
public:
  RandNumber();
  ~RandNumber();
  void LoadSeq();
  void GenSeq();
  int GetInt(int max)
  {
    int randNum;
    if (m_listSeq.empty())
    {
      randNum = rand();
    }
    else
    {
      randNum = m_listSeq[m_currSeqIX];
      m_currSeqIX++;
    }
    randNum = int((float)randNum*max*m_invRandMax);
    return randNum;
  }
  float GetFloat(float max)
  {
    int randNum;
    if (m_listSeq.empty())
    {
      randNum = rand();
    }
    else
    {
      randNum = m_listSeq[m_currSeqIX];
      m_currSeqIX++;
      if (m_currSeqIX == (int)m_listSeq.size())
        m_currSeqIX = 0;
    }
    return (float)randNum*max*m_invRandMax;
  }
private:
  vector m_listSeq;
  int m_currSeqIX;
  float m_invRandMax;
};

You need to call GenSeq() initially to create the file with the sequence of numbers.
#include "RandNumber.h"

RandNumber::RandNumber()
{
  m_invRandMax = 1.0f/(float)RAND_MAX;
}

RandNumber::~RandNumber()
{
}

const char* szSeqFilename = "randSeq.txt";

void RandNumber::LoadSeq()
{
  FILE* pFile;
  pFile = fopen(szSeqFilename, "rb");
  if (pFile == NULL)
    throw RacException("cannot open ", szSeqFilename);
  m_currSeqIX = 0;
  char* pBuffer;

  fseek(pFile, 0, 2 /* SEEK_END */);
  int fileSize = (int)ftell(pFile);
  if (fileSize == 0) return;
  fseek(pFile, 0, 0 /* SEEK_SET */);
  pBuffer = new char[fileSize];
  int bytesRead = (int)fread(pBuffer, fileSize, 1, pFile);  // read length and type
  if (bytesRead != 1)
    throw RacException("cannot read ", szSeqFilename);
  fclose(pFile);

  char* szToken;
  szToken = strtok(pBuffer,",");
  while(szToken != NULL)
  {
    m_listSeq.push_back(atoi(szToken));
    szToken = strtok(NULL, ",");
  }
  delete [] pBuffer;
}

void RandNumber::GenSeq()
{
  string file = g_resManager.GetDirResources()+szSeqFilename;
  FILE* pFile = fopen(file.c_str(), "wt");
  if (pFile == NULL)
  {
    assert(false);
    return;
  }
  ostringstream os;
  for (int n = 0; n < 10000; n++)
  {
    os << rand() << ",";
  }
  fwrite(os.str().c_str(), os.str().length(), 1, pFile);
  fclose(pFile);
}

This entry was posted in Testing. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Anti-Spam Quiz: