cleanup of unnecessarily convoluted function call
[rocksndiamonds.git] / src / game_bd / bd_random.c
index 57fe1c068c87e4710134901391df22da3d83e0fd..b40ee4fc43a12758e3964501a4f5c2d3ba107da2 100644 (file)
 #include <unistd.h>
 #include <time.h>
 
+#include "main_bd.h"
+
 #if defined(PLATFORM_WINDOWS)
 #include <process.h>   // for getpid()
+#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__MINGW64_VERSION_MAJOR)
+extern errno_t rand_s (unsigned int *randomValue);
+#endif
 #endif
-
-#include "main_bd.h"
 
 
 /**
@@ -387,6 +390,9 @@ gd_rand_int (GdRand *rand)
   return y;
 }
 
+// transform [0..2^32] -> [0..1]
+#define GD_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
+
 /**
  * gd_rand_int_range:
  * @rand_: a #GdRand
@@ -435,6 +441,52 @@ gd_rand_int_range (GdRand *rand, int begin, int end)
   return begin + random;
 }
 
+/**
+ * gd_rand_double:
+ * @rand_: a #GRand
+ *
+ * Returns the next random #double from @rand_ equally distributed over
+ * the range [0..1).
+ *
+ * Returns: a random number
+ */
+double
+gd_rand_double (GdRand *rand)
+{
+  /* We set all 52 bits after the point for this, not only the first
+     32. That's why we need two calls to gd_rand_int */
+  double retval = gd_rand_int(rand) * GD_RAND_DOUBLE_TRANSFORM;
+  retval = (retval + gd_rand_int(rand)) * GD_RAND_DOUBLE_TRANSFORM;
+
+  /* The following might happen due to very bad rounding luck, but
+   * actually this should be more than rare, we just try again then */
+  if (retval >= 1.0)
+    return gd_rand_double (rand);
+
+  return retval;
+}
+
+/**
+ * gd_rand_double_range:
+ * @rand_: a #GRand
+ * @begin: lower closed bound of the interval
+ * @end: upper open bound of the interval
+ *
+ * Returns the next random #double from @rand_ equally distributed over
+ * the range [@begin..@end).
+ *
+ * Returns: a random number
+ */
+double
+gd_rand_double_range (GdRand *rand, double begin, double end)
+{
+  double r;
+
+  r = gd_rand_double(rand);
+
+  return r * end - (r - 1) * begin;
+}
+
 static GdRand *
 get_global_random (void)
 {
@@ -447,6 +499,32 @@ get_global_random (void)
   return global_random;
 }
 
+/**
+ * gd_random_boolean:
+ *
+ * Returns a random #gboolean.
+ * This corresponds to an unbiased coin toss.
+ *
+ * Returns: a random #gboolean
+ */
+/**
+ * gd_random_int:
+ *
+ * Return a random #guint32 equally distributed over the range
+ * [0..2^32-1].
+ *
+ * Returns: a random number
+ */
+unsigned int
+gd_random_int (void)
+{
+  unsigned int result;
+
+  result = gd_rand_int(get_global_random());
+
+  return result;
+}
+
 /**
  * gd_random_int_range:
  * @begin: lower closed bound of the interval
@@ -466,3 +544,40 @@ gd_random_int_range (int begin, int end)
 
   return result;
 }
+
+/**
+ * gd_random_double:
+ *
+ * Returns a random #double equally distributed over the range [0..1).
+ *
+ * Returns: a random number
+ */
+double
+gd_random_double (void)
+{
+  double result;
+
+  result = gd_rand_double(get_global_random());
+
+  return result;
+}
+
+/**
+ * gd_random_double_range:
+ * @begin: lower closed bound of the interval
+ * @end: upper open bound of the interval
+ *
+ * Returns a random #double equally distributed over the range
+ * [@begin..@end).
+ *
+ * Returns: a random number
+ */
+double
+gd_random_double_range (double begin, double end)
+{
+  double result;
+
+  result = gd_rand_double_range(get_global_random(), begin, end);
+
+  return result;
+}