//Random.h #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef Randomh #define Randomh /* This is a random number generator that provides a repeatable random pattern for a given seed. Usage: CRandom Rand; int i=Rand; long j=Rand; double d=Rand; etc... To have all users have the same sequence on any given day use the following code: time_t Time; tm* Now; time(&Time); Now=gmtime(&Time); CRandom Rand(Now->tm_year, Now->tm_yday); int i=Rand; long j=Rand; */ #include #include class CRandom { protected: double m_Array[97]; double m_C; double m_Cd; double m_Cm; int m_Index_1; int m_Index_2; public: CRandom() { m_C =0.0; m_Cd =0.0; m_Cm =0.0; m_Index_1=0; m_Index_2=0; memset(m_Array, sizeof(m_Array),0); InitializeSeed(); } CRandom(WORD seed_1, WORD seed_2) { m_C =0.0; m_Cd =0.0; m_Cm =0.0; m_Index_1=0; m_Index_2=0; memset(m_Array, sizeof(m_Array),0); SetSeed(seed_1, seed_2); } virtual ~CRandom() {} void InitializeSeed() { /* WORD high_word; WORD low_word; SetSeed(low_word, high_word); */ WORD low_word; WORD high_word=LOWORD(::GetTickCount()); DWORD number_of_sectors_per_cluster; DWORD number_of_bytes_per_sector; DWORD number_of_free_clusters; DWORD total_number_of_clusters; if(::GetDiskFreeSpace(NULL, &number_of_sectors_per_cluster, &number_of_bytes_per_sector, &number_of_free_clusters, &total_number_of_clusters) != FALSE) { low_word=LOWORD(number_of_free_clusters); low_word ^= LOWORD(::GetTickCount()); }else{ SYSTEMTIME system_time; ::GetSystemTime(&system_time); BYTE high_byte=LOBYTE(system_time.wMilliseconds); BYTE low_byte =(BYTE) ((system_time.wMilliseconds >> 8) + system_time.wSecond); low_word=MAKEWORD(low_byte, high_byte); } SetSeed(low_word, high_word); } DWORD GetInteger() { double value=GetFloat(); value *= static_cast(0xFFFFFFFF); const unsigned char* buffer=reinterpret_cast(&value); DWORD hash_value=static_cast(value); DWORD temp_value=0; int index=0; while(index < sizeof(value)) { hash_value=(hash_value << 4) + buffer[index++]; temp_value=hash_value & 0xF0000000L; if(temp_value) hash_value ^= temp_value >> 24; hash_value &= ~temp_value; } DWORD return_value=static_cast(value); return_value += ((hash_value >> 5) % 256); return return_value; } double GetFloat() { double return_value=0.0; return_value=m_Array[m_Index_1] - m_Array[m_Index_2]; if(return_value < 0.0) return_value += 1.0; m_Array[m_Index_1--]=return_value; if(m_Index_1 < 0) m_Index_1=96; if(--m_Index_2 < 0) m_Index_2=96; m_C -= m_Cd; if(m_C < 0.0) m_C += m_Cm; return_value -= m_C; if(return_value < 0.0) return_value += 1.0; return return_value; } void SetSeed(WORD seed_1, WORD seed_2) { while(seed_1 > 31328) seed_1 %= 31329; while(seed_2 > 30081) seed_2 %= 30082; int i=static_cast(fmod(seed_1 / 177.0, 177.0) + 2); int j=static_cast(fmod(seed_1 , 177.0) + 2); int k=static_cast(fmod(seed_2 / 169.0, 178.0) + 1); int l=static_cast(fmod(seed_2 , 169.0) ); int outer_loop_index=0; int inner_loop_index=0; double seed=0.0; double t=0.0; double m=0.0; for(outer_loop_index=0; outer_loop_index < 97; outer_loop_index++) { seed=0.0; t =0.5; for(inner_loop_index=0; inner_loop_index < 24; inner_loop_index++) { m=static_cast(::fmod(::fmod(i * j, 179.0) * k , 179.0)); i=j; j=k; k=static_cast(m); l=static_cast(::fmod(53.0 * l + 1.0 , 169.0)); if(::fmod(l * m, 64.0) > 31) seed += t; t=static_cast(0.5 * t); } m_Array[outer_loop_index]=seed; } m_C =static_cast( 362436.0 / 16777216.0); m_Cd=static_cast( 7654321.0 / 16777216.0); m_Cm=static_cast(16777213.0 / 16777216.0); m_Index_1=96; m_Index_2=32; } operator char() {return static_cast(GetInteger() >> 9);} operator unsigned char() {return static_cast(GetInteger() >> 17);} operator int() {return GetInteger();} operator unsigned int() {return GetInteger();} operator short() {return static_cast(GetInteger());} operator unsigned short() {return static_cast(GetInteger());} operator long() {return static_cast(GetInteger());} operator unsigned long() {return GetInteger();} operator float() {return static_cast(GetFloat());} operator double() {return GetFloat();} }; #endif //ndef Randomh