This commit is contained in:
Trevius
2014-12-04 23:07:23 -06:00
41 changed files with 680 additions and 780 deletions
+1
View File
@@ -169,6 +169,7 @@ SET(common_headers
ptimer.h
queue.h
races.h
random.h
rdtsc.h
rulesys.h
ruletypes.h
-154
View File
@@ -54,20 +54,6 @@
#include <errno.h>
#endif
static bool WELLRNG_init = false;
static int state_i = 0;
static unsigned int STATE[R];
static unsigned int z0, z1, z2;
unsigned int (*WELLRNG19937)(void);
static unsigned int case_1 (void);
static unsigned int case_2 (void);
static unsigned int case_3 (void);
static unsigned int case_4 (void);
static unsigned int case_5 (void);
static unsigned int case_6 (void);
uint32 rnd_hash(time_t t, clock_t c);
void oneseed(const uint32 seed);
void CoutTimestamp(bool ms) {
time_t rawtime;
struct tm* gmt_t;
@@ -179,41 +165,6 @@ const char * itoa(int num, char* a,int b) {
}
#endif
/*
* generate a random integer in the range low-high this
* should be used instead of the rand()%limit method
*/
int MakeRandomInt(int low, int high)
{
if(low >= high)
return(low);
//return (rand()%(high-low+1) + (low));
if(!WELLRNG_init) {
WELLRNG_init = true;
oneseed( rnd_hash( time(nullptr), clock() ) );
WELLRNG19937 = case_1;
}
unsigned int randomnum = ((WELLRNG19937)());
if(randomnum == 0xffffffffUL)
return high;
return int ((randomnum / (double)0xffffffffUL) * (high - low + 1) + low);
}
double MakeRandomFloat(double low, double high)
{
if(low >= high)
return(low);
//return (rand() / (double)RAND_MAX * (high - low) + low);
if(!WELLRNG_init) {
WELLRNG_init = true;
oneseed( rnd_hash( time(nullptr), clock() ) );
WELLRNG19937 = case_1;
}
return ((WELLRNG19937)() / (double)0xffffffffUL * (high - low) + low);
}
uint32 rnd_hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
@@ -239,111 +190,6 @@ uint32 rnd_hash( time_t t, clock_t c )
return ( h1 + differ++ ) ^ h2;
}
void oneseed( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register int j = 0;
STATE[j] = seed & 0xffffffffUL;
for (j = 1; j < R; j++)
{
STATE[j] = ( 1812433253UL * ( STATE[j-1] ^ (STATE[j-1] >> 30) ) + j ) & 0xffffffffUL;
}
}
// WELL RNG code
/* ***************************************************************************** */
/* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */
/* Makoto Matsumoto, Hiroshima University */
/* Notice: This code can be used freely for personal, academic, */
/* or non-commercial purposes. For commercial purposes, */
/* please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca */
/* A modified "maximally equidistributed" implementation */
/* by Shin Harase, Hiroshima University. */
/* ***************************************************************************** */
unsigned int case_1 (void){
// state_i == 0
z0 = (VRm1Under & MASKL) | (VRm2Under & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1);
z2 = MAT3POS (9, VM2) ^ MAT0POS (1, VM3);
newV1 = z1 ^ z2;
newV0Under = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i = R - 1;
WELLRNG19937 = case_3;
return (STATE[state_i] ^ (newVM2Over & BITMASK));
}
static unsigned int case_2 (void){
// state_i == 1
z0 = (VRm1 & MASKL) | (VRm2Under & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1);
z2 = MAT3POS (9, VM2) ^ MAT0POS (1, VM3);
newV1 = z1 ^ z2;
newV0 = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i = 0;
WELLRNG19937 = case_1;
return (STATE[state_i] ^ (newVM2 & BITMASK));
}
static unsigned int case_3 (void){
// state_i+M1 >= R
z0 = (VRm1 & MASKL) | (VRm2 & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1Over);
z2 = MAT3POS (9, VM2Over) ^ MAT0POS (1, VM3Over);
newV1 = z1 ^ z2;
newV0 = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i--;
if (state_i + M1 < R)
WELLRNG19937 = case_5;
return (STATE[state_i] ^ (newVM2Over & BITMASK));
}
static unsigned int case_4 (void){
// state_i+M3 >= R
z0 = (VRm1 & MASKL) | (VRm2 & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1);
z2 = MAT3POS (9, VM2) ^ MAT0POS (1, VM3Over);
newV1 = z1 ^ z2;
newV0 = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i--;
if (state_i + M3 < R)
WELLRNG19937 = case_6;
return (STATE[state_i] ^ (newVM2 & BITMASK));
}
static unsigned int case_5 (void){
// state_i+M2 >= R
z0 = (VRm1 & MASKL) | (VRm2 & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1);
z2 = MAT3POS (9, VM2Over) ^ MAT0POS (1, VM3Over);
newV1 = z1 ^ z2;
newV0 = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i--;
if (state_i + M2 < R)
WELLRNG19937 = case_4;
return (STATE[state_i] ^ (newVM2Over & BITMASK));
}
static unsigned int case_6 (void){
// 2 <= state_i <= (R - M3 - 1)
z0 = (VRm1 & MASKL) | (VRm2 & MASKU);
z1 = MAT0NEG (-25, V0) ^ MAT0POS (27, VM1);
z2 = MAT3POS (9, VM2) ^ MAT0POS (1, VM3);
newV1 = z1 ^ z2;
newV0 = MAT1 (z0) ^ MAT0NEG (-9, z1) ^ MAT0NEG (-21, z2) ^ MAT0POS (21, newV1);
state_i--;
if (state_i == 1)
WELLRNG19937 = case_2;
return (STATE[state_i] ^ (newVM2 & BITMASK));
}
// end WELL RNG code
float EQ13toFloat(int d)
{
return ( float(d)/float(1<<2));
+84
View File
@@ -0,0 +1,84 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __random_h__
#define __random_h__
#include <random>
#include <utility>
/* This uses mt19937 seeded with the std::random_device
* The idea is to have this be included as a member of another class
* so mocking out for testing is easier
* If you need to reseed random.Reseed()
* Eventually this should be derived from an abstract base class
*/
namespace EQEmu {
class Random {
public:
// AKA old MakeRandomInt
const int Int(int low, int high)
{
if (low > high)
std::swap(low, high);
return std::uniform_int_distribution<int>(low, high)(m_gen); // [low, high]
}
// AKA old MakeRandomFloat
const double Real(double low, double high)
{
if (low > high)
std::swap(low, high);
return std::uniform_real_distribution<double>(low, high)(m_gen); // [low, high)
}
// example Roll(50) would have a 50% success rate
// Roll(100) 100%, etc
// valid values 0-100 (well, higher works too but ...)
const bool Roll(const int required)
{
return Int(0, 99) < required;
}
// valid values 0.0 - 1.0
const bool Roll(const double required)
{
return Real(0.0, 1.0) <= required;
}
void Reseed()
{
// We could do the seed_seq thing here too if we need better seeding
// but that is mostly overkill for us, so just seed once
std::random_device rd;
m_gen.seed(rd());
}
Random()
{
Reseed();
}
private:
std::mt19937 m_gen;
};
}
#endif /* !__random_h__ */