From 9e425136f1aee51d9c1f3baf48989346bb7d7e16 Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 27 Feb 2011 21:54:43 +0000 Subject: [PATCH] Adding new types of random number generators: 1. shuffle a list non-deterministic (not the default shuffle) 2. get random numbers of a range 3. get random numbers of a range, without duplicates (the latest based on floty's idea). Note that the existing random number works quite well, the new approach uses boost::random and is more flexible if other distributions are needed for the AI. The code is currently disabled due to link problems on debian/ubuntu (boost::random seems to be missing there). --- src/engine/local_engine/tools.cpp | 67 +++++++++++++++++++++++++++++++ src/engine/local_engine/tools.h | 5 +++ 2 files changed, 72 insertions(+) diff --git a/src/engine/local_engine/tools.cpp b/src/engine/local_engine/tools.cpp index b03e04c6..3df7d05f 100755 --- a/src/engine/local_engine/tools.cpp +++ b/src/engine/local_engine/tools.cpp @@ -23,10 +23,77 @@ #include #include +#include +#include +#include +#include +#include #include + using namespace std; +#if 0 // TODO temporarily disabled until build problems are solved +boost::thread_specific_ptr g_rand_state; + +struct nondet_rng : std::unary_function { + boost::random_device &_state; + unsigned operator()(unsigned i) { + boost::uniform_int<> rng(0, i - 1); + return rng(_state); + } + nondet_rng(boost::random_device &state) : _state(state) {} +}; + +static inline void InitRandState() { + if (!g_rand_state.get()) { + g_rand_state.reset(new boost::random_device); + } +} + +void Tools::ShuffleArrayNonDeterministic(int *inout, unsigned count) +{ + InitRandState(); + nondet_rng rand(*g_rand_state); + std::random_shuffle(&inout[0], &inout[count], rand); +} + +void Tools::GetRand(int minValue, int maxValue, unsigned count, int *out) +{ + InitRandState(); + boost::uniform_int<> dist(minValue, maxValue); + boost::variate_generator > gen(*g_rand_state, dist); + int *startPtr = out; + for (unsigned i = 0; i < count; i++) { + *startPtr++ = gen(); + } +} + +void Tools::GetRandUnique(int minValue, int maxValue, unsigned count, int *out) +{ + InitRandState(); + unsigned numCreated = 0; + int *startPtr = out; + std::set tmpSet; + for (unsigned i = 0; i < count; i++) { + boost::uniform_int<> dist(minValue, maxValue - numCreated); + boost::variate_generator > gen(*g_rand_state, dist); + *startPtr = gen(); + std::set::const_iterator v = tmpSet.begin(); + std::set::const_iterator end = tmpSet.end(); + while (v != end) { + if (*v <= *startPtr) { + (*startPtr)++; + } + ++v; + } + tmpSet.insert(*startPtr); + startPtr++; + numCreated++; + } +} +#endif + void Tools::getRandNumber(int start, int end, int howMany, int* randArray, bool different, int* bad, int countBad) { diff --git a/src/engine/local_engine/tools.h b/src/engine/local_engine/tools.h index 29515a29..a8e27bd6 100755 --- a/src/engine/local_engine/tools.h +++ b/src/engine/local_engine/tools.h @@ -23,6 +23,11 @@ class Tools { public: + + static void ShuffleArrayNonDeterministic(int *inout, unsigned count); + static void GetRand(int minValue, int maxValue, unsigned count, int *out); + static void GetRandUnique(int minValue, int maxValue, unsigned count, int *out); + static void getRandNumber(int, int, int, int*, bool, int* = 0, int = 0); };