Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Sources/Random.cp
/* |
File: Random.cp |
Contains: TRandom is a stackbased utility class for random number generation. |
TRandom.cp contains the member function implementations for TRandom. |
Written by: |
Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/18/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
// Include files |
#ifndef _RANDOM_ |
#include "Random.h" |
#endif |
// _________________________________________________________________________________________________________ // |
// TRandom class member function implementations |
// CONSTRUCTORS & DESTRUCTORS |
#pragma segment Random |
TRandom::TRandom(ERandType theType, |
long theSeed, |
unsigned short low, |
unsigned short high) |
// Default constructor, most of the parameters have default values defined in the |
// header file (change if needed). |
{ |
if (theSeed == 1) // no seed value |
this->ShuffleSeed(); // no first value, random value |
else |
this->SetSeedValue(theSeed); // programmer defined seed |
this->fLow = low; // define the range |
this->fHigh = high; |
this->fRange = high - low; |
Boolean fState = this->IRandom(theType); // initialize the object |
} |
#pragma segment Random |
TRandom::TRandom(const TRandom& other) |
// copy constructor, creates clones of the TRandom class (deep copy). |
{ |
register int x; |
// fill in the needed fields with values from the referenced object |
this->fGenerator = other.fGenerator; |
this->fAlgorithm = other.fAlgorithm; |
this->fLow = other.fLow; |
this->fHigh = other.fHigh; |
this->fRange = other.fRange; |
this->fSeed = other.fSeed; |
this->fState = other.fState; |
this->fPrevNum = other.fPrevNum; |
for (x = 0; x < kSHUFFLETABLE; x++) // copy the values from array |
this->fShuffleBuf[x] = other.fShuffleBuf[x]; |
} |
#pragma segment Random |
TRandom& TRandom::operator=(const TRandom& other) |
// assignment operator, assign a TRandom class to another for quick cloning. |
{ |
register int x; |
// fill in the needed fields with values from the referenced object |
this->fGenerator = other.fGenerator; |
this->fAlgorithm = other.fAlgorithm; |
this->fLow = other.fLow; |
this->fHigh = other.fHigh; |
this->fRange = other.fRange; |
this->fSeed = other.fSeed; |
this->fState = other.fState; |
this->fPrevNum = other.fPrevNum; |
for (x = 0; x < kSHUFFLETABLE; x++) // copy the values from array |
this->fShuffleBuf[x] = other.fShuffleBuf[x]; |
return *this; |
} |
#pragma segment Random |
TRandom::~TRandom() |
// Virtual destructor, we are not doing anything inside this one just now, note |
// that virtual destructors should not be inlined. |
{ |
} |
// INITIATION ROUTINES |
#pragma segment Random |
Boolean TRandom::IRandom(ERandType theType) |
// We are using a special IRandom member function for initializing class fields to |
// known values. This is called from both the constructor, and when we switch the |
// internal random number algorithm. |
{ |
switch (theType) |
{ |
case kMACOS: |
qd.randSeed = this->GetSeedValue(); |
this->fGenerator = &TRandom::MacRandom;// quick init |
this->fAlgorithm = kMACOS; |
break; |
case kSHUFFLE: |
qd.randSeed = this->GetSeedValue(); |
this->fGenerator = &TRandom::ShuffleRandom; |
this->fAlgorithm = kSHUFFLE; |
this->InitShuffleRandom(); |
break; |
case kPM: |
this->fGenerator = &TRandom::ParkMiller; |
this->fAlgorithm = kPM; |
break; |
default: |
ASSERT(false, "\pProblems setting the algorithm for the random generator"); |
return false; // should never get here... |
}; |
return true; |
} |
// RANDOM GENERATOR ALGORITHMS/MEMBER FUNCTIONS |
#pragma segment Random |
unsigned short TRandom::MacRandom() |
// Macintosh Toolbox random number generator. |
{ |
register unsigned short temp; |
temp = |
short(::Random()); // scale to 0 - 65536 |
return (((temp * this->fRange) / k16BIT) + this->fLow); |
} |
#pragma segment Random |
unsigned short TRandom::ShuffleRandom() |
// Shuffle Random algorithm, uses an internal table for shuffling values for more |
// random distribution |
{ |
register unsigned short index; |
index = (this->fPrevNum * kSHUFFLETABLE) / k16BIT; |
this->fPrevNum = this->fShuffleBuf[index]; // get random number from table |
this->fShuffleBuf[index] = Random(); // new random table entry |
return (((this->fPrevNum * this->fRange) / k16BIT) + this->fLow); |
} |
#pragma segment Random |
TRandom& TRandom::InitShuffleRandom() |
// Used to initialize the Shuffle random algorithm |
{ |
register short i; |
for (i = 0; i < kSHUFFLETABLE; i++) |
Random(); // shuffle the random generator |
for (i = 0; i < kSHUFFLETABLE; i++) |
this->fShuffleBuf[i] = Random(); // fill the buffer |
this->fPrevNum = Random(); // get first 'later' value |
return *this; |
} |
#pragma segment Random |
unsigned short TRandom::ParkMiller() |
// CACM Oct 1988 Park& Miller algorithm. |
{ |
unsigned short high, |
low; |
register unsigned short temp; |
high = |
short(this-> fSeed/ kPM3); |
low = |
short(this-> fSeed% kPM3); |
temp = (kPM2 * low) - (kPM1 * high); |
if (temp > 0) |
this->fSeed = temp; |
else |
this->fSeed = temp + kACM_MAX; |
return (((temp * this->fRange) / k16BIT) + this->fLow); |
} |
#pragma segment Random |
unsigned short TRandom::Next() |
// Iterate to next value. |
{ |
return (this->*fGenerator)(); |
} |
#pragma segment Random |
TRandom& TRandom::ShuffleSeed() |
// Shuffle the current seed. |
{ |
this->fSeed = TickCount(); |
return *this; |
} |
// GET/SET FUNCTIONS |
#pragma segment Random |
TRandom& TRandom::SetRandomGenerator(TRandom::ERandType theType) |
// Select the random generator algorithm. |
{ |
this->IRandom(theType); |
return *this; |
} |
#pragma segment Random |
long TRandom::GetSeedValue() const |
// Return current seed value. |
{ |
return this->fSeed; |
} |
#pragma segment Random |
TRandom& TRandom::SetSeedValue(const long theSeed) |
// Set current seed value |
{ |
this->fSeed = theSeed; |
qd.randSeed = theSeed; |
return *this; |
} |
#pragma segment Random |
TRandom::ERandType TRandom::GetAlgorithmType() const |
// Return algorithm type. |
{ |
return this->fAlgorithm; |
} |
// _________________________________________________________________________________________________________ // |
/* Change History (most recent last): |
No Init. Date Comment |
1 khs 6/2/92 New file |
2 khs 1/7/93 Cleanup |
*/ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14