]> git.pond.sub.org Git - empserver/blobdiff - src/lib/gen/chance.c
Switch PRNG from BSD random() to Mersenne Twister
[empserver] / src / lib / gen / chance.c
index 73e24f286b0d7793475288f58b43f004eab68fa1..2a00789fd0b2e4a1094271fc5c52e7970736e1b5 100644 (file)
@@ -35,6 +35,7 @@
 #include <math.h>
 #include <stdlib.h>
 #include "chance.h"
+#include "mt19937ar.h"
 
 /*
  * Return non-zero with probability D.
@@ -42,7 +43,7 @@
 int
 chance(double d)
 {
-    return d > (random() % 32768) / 32768.0;
+    return d > genrand_real2();
 }
 
 /*
@@ -54,22 +55,43 @@ pct_chance(int pct)
     return roll(100) <= pct;
 }
 
+static unsigned
+round_up_to_pow2(unsigned val)
+{
+    val--;
+    val |= val >> 1;
+    val |= val >> 2;
+    val |= val >> 4;
+    val |= val >> 8;
+    val |= val >> 16;
+    val++;
+    return val;
+}
+
 /*
  * Return a random number in [0..N-1].
+ * N must be in [1..2^31-1].
  */
 int
 roll0(int n)
 {
-    return random() % n;
+    unsigned pow2 = round_up_to_pow2(n);
+    int r;
+
+    do
+       r = genrand_int32() & (pow2 - 1);
+    while (r >= n);
+    return r;
 }
 
 /*
  * Return a random number in [1..N].
+ * N must be in [0..2^31-1].
  */
 int
 roll(int n)
 {
-    return 1 + random() % n;
+    return 1 + roll0(n);
 }
 
 /*
@@ -91,5 +113,5 @@ roundavg(double val)
 void
 seed_prng(unsigned seed)
 {
-    srandom(seed);
+    init_genrand(seed);
 }