first and last commit
This commit is contained in:
commit
c9e78fd810
381 changed files with 37141 additions and 0 deletions
153
random.h
Normal file
153
random.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
|
||||
#define RNG_MULT 0x5DEECE66DL
|
||||
#define RNG_ADDEND 0xBL
|
||||
#define RNG_MASK (1L << 48) - 1
|
||||
#define RNG_UNIT 0x1.0p-53 // 1.0 / (1L << 53)
|
||||
|
||||
ulong rng_rseed() {
|
||||
return (((sys.rng_uniq *= 181783497276652981L) ^ tmr_ntime()) ^ RNG_MULT) & RNG_MASK;
|
||||
}
|
||||
|
||||
ulong rng_sseed(ulong seed) {
|
||||
return (seed ^ RNG_MULT) & RNG_MASK;
|
||||
}
|
||||
|
||||
uint rng_gen(ulong *rand, int bits) {
|
||||
*rand = ((*rand) * RNG_MULT + RNG_ADDEND) & RNG_MASK;
|
||||
return (uint)((*rand) >> (48 - bits));
|
||||
}
|
||||
|
||||
uint rng_uint(ulong *rand) {
|
||||
return rng_gen(rand, 32);
|
||||
}
|
||||
|
||||
int rng_zrange(ulong *rand, int bound) {
|
||||
sys_assert(bound > 0);
|
||||
int r = rng_gen(rand, 31);
|
||||
int m = bound - 1;
|
||||
if((bound & m) == 0) // ^2
|
||||
r = (int)((bound * (long)r) >> 31);
|
||||
else
|
||||
for(int u = r; u - (r = u % bound) + m < 0; u = rng_gen(rand, 31));
|
||||
return r;
|
||||
}
|
||||
|
||||
uint rng_urange(ulong *rand, uint bound) {
|
||||
sys_assert(bound);
|
||||
uint r = rng_gen(rand, 32);
|
||||
uint m = bound - 1;
|
||||
if((bound & m) == 0) // ^2
|
||||
r = (uint)((bound * (ulong)r) >> 31);
|
||||
else
|
||||
for(uint u = r; u - (r = u % bound) + m < 0; u = rng_gen(rand, 32));
|
||||
return r;
|
||||
}
|
||||
|
||||
ulong rng_ulong(ulong *rand) {
|
||||
return ((ulong)(rng_gen(rand, 32)) << 32) | (ulong)rng_gen(rand, 32);
|
||||
}
|
||||
|
||||
byte rng_bool(ulong *rand) {
|
||||
return (byte)rng_gen(rand, 1);
|
||||
}
|
||||
|
||||
float rng_float(ulong *rand) {
|
||||
return rng_gen(rand, 24) / ((float)(1 << 24));
|
||||
}
|
||||
|
||||
double rng_double(ulong *rand) {
|
||||
return (((long)(rng_gen(rand, 26)) << 27) + rng_gen(rand, 27)) * RNG_UNIT;
|
||||
}
|
||||
|
||||
void rng_gauss(ulong *rand, double *n1, double *n2) {
|
||||
double v1, v2, s;
|
||||
do {
|
||||
v1 = 2.0 * rng_double(rand) - 1.0; // between -1 and 1
|
||||
v2 = 2.0 * rng_double(rand) - 1.0; // between -1 and 1
|
||||
s = v1 * v1 + v2 * v2;
|
||||
}
|
||||
while (s >= 1.0 || s == 0.0);
|
||||
double mul = sqrt(-2.0 * log(s)/s);
|
||||
*n1 = v1 * mul;
|
||||
*n2 = v2 * mul;
|
||||
}
|
||||
|
||||
int rng_excl(ulong *rand, int min, int max) {
|
||||
return min + rng_zrange(rand, max - min);
|
||||
}
|
||||
|
||||
int rng_ch_offset(ulong *rand) {
|
||||
return 8 + rng_gen(rand, 4);
|
||||
}
|
||||
|
||||
int rng_roll(ulong *rand, int range) {
|
||||
return 1 + rng_zrange(rand, range);
|
||||
}
|
||||
|
||||
int rng_roll_bonus(ulong *rand, int range, int bonus) {
|
||||
return 1 + rng_zrange(rand, range) + rng_zrange(rand, bonus + 1);
|
||||
}
|
||||
|
||||
int rng_range(ulong *rand, int min, int max) {
|
||||
return min + rng_zrange(rand, max + 1 - min);
|
||||
}
|
||||
|
||||
int rng_range_bonus(ulong *rand, int min, int max, int bonus) {
|
||||
return (min + rng_zrange(rand, max + 1 - min)) + rng_zrange(rand, bonus + 1);
|
||||
}
|
||||
|
||||
int rng_range_checked(ulong *rand, int min, int max) {
|
||||
return min >= max ? min : (rng_zrange(rand, max + 1 - min) + min);
|
||||
}
|
||||
|
||||
float rng_frange(ulong *rand, float min, float max) {
|
||||
return min >= max ? min : (rng_float(rand) * (max - min) + min);
|
||||
}
|
||||
|
||||
double rng_drange(ulong *rand, double min, double max) {
|
||||
return min >= max ? min : (rng_double(rand) * (max - min) + min);
|
||||
}
|
||||
|
||||
byte rng_chance(ulong *rand, int chance) {
|
||||
return !rng_zrange(rand, chance);
|
||||
}
|
||||
|
||||
byte rng_rarity(ulong *rand, int chance) {
|
||||
return rng_zrange(rand, chance) != 0;
|
||||
}
|
||||
|
||||
void *rng_select(ulong *rand, void *a, void *b, int chance) {
|
||||
return rng_zrange(rand, chance) ? a : b;
|
||||
}
|
||||
|
||||
int rng_iselect(ulong *rand, int a, int b, int chance) {
|
||||
return rng_zrange(rand, chance) ? a : b;
|
||||
}
|
||||
|
||||
byte rng_percent(ulong *rand, float chance) {
|
||||
return rng_float(rand) < chance / 100.0f;
|
||||
}
|
||||
|
||||
void *rng_pselect(ulong *rand, void *a, void *b, float chance) {
|
||||
return rng_float(rand) < chance / 100.0f ? b : a;
|
||||
}
|
||||
|
||||
void *rng_rselect(ulong *rand, void *a, void *b) {
|
||||
return rng_gen(rand, 1) != 0 ? b : a;
|
||||
}
|
||||
|
||||
void *rng_pick(ulong *rand, void **obj, uint size) {
|
||||
return obj[rng_zrange(rand, size)];
|
||||
}
|
||||
|
||||
int rng_ipick(ulong *rand, int *obj, uint size) {
|
||||
return obj[rng_zrange(rand, size)];
|
||||
}
|
||||
|
||||
void *rng_weight(ulong *rand, void *a, void *b, int ca, int cb) {
|
||||
return rng_zrange(rand, ca + cb) >= ca ? b : a;
|
||||
}
|
||||
|
||||
void *rng_fselect(ulong *rand, void *a, void *b, float chance) {
|
||||
return rng_float(rand) < chance ? b : a;
|
||||
}
|
Reference in a new issue