diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2013-02-12 20:18:58 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2013-02-12 21:09:59 -0800 |
commit | b17b9021ecf9b16c265d0a6b60faa761b34eae35 (patch) | |
tree | e8192de5b2458864f0f5ce5edd0e1ccf5605c644 /src/common/random2.hpp | |
parent | 80e36aa669274637bcd5956fbf4020dba1d4739c (diff) | |
download | tmwa-b17b9021ecf9b16c265d0a6b60faa761b34eae35.tar.gz tmwa-b17b9021ecf9b16c265d0a6b60faa761b34eae35.tar.bz2 tmwa-b17b9021ecf9b16c265d0a6b60faa761b34eae35.tar.xz tmwa-b17b9021ecf9b16c265d0a6b60faa761b34eae35.zip |
Replace mt_rand with <random>
Also add some utility methods and classes.
Diffstat (limited to 'src/common/random2.hpp')
-rw-r--r-- | src/common/random2.hpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/common/random2.hpp b/src/common/random2.hpp new file mode 100644 index 0000000..86deddf --- /dev/null +++ b/src/common/random2.hpp @@ -0,0 +1,74 @@ +#ifndef RANDOM2_HPP +#define RANDOM2_HPP + +# include "random.hpp" +# include "utils2.hpp" + +# include <algorithm> + +namespace random_ +{ + namespace detail + { + struct RandomIterator + { + int bound; + int current; + bool frist; + + void operator ++() + { + frist = false; + // TODO: reimplement in terms of LFSRs, so that certain + // blockage patterns don't favor adjacent cells. + current = current + 1; + if (current == bound) + current = 0; + } + int operator *() + { + return current; + } + }; + + inline + bool operator == (RandomIterator l, RandomIterator r) + { + return l.current == r.current && l.frist == r.frist; + } + + inline + bool operator != (RandomIterator l, RandomIterator r) + { + return !(l == r); + } + } + + /// Yield every cell from 0 .. bound - 1 in some order. + /// The starting position is random, but not the order itself. + /// + /// Expected usage: + /// for (int i : random_::iterator(vec.size())) + /// if (vec[i].okay()) + /// return frob(vec[i]); + inline + IteratorPair<detail::RandomIterator> iterator(int bound) + { + int current = random_::to(bound); + return + { + detail::RandomIterator{bound, current, true}, + detail::RandomIterator{bound, current, false} + }; + } + + /// similar to std::random_shuffle(c.begin(), c.end()), but guaranteed + /// to use a good source of randomness. + template<class C> + void shuffle(C&& c) + { + std::random_shuffle(c.begin(), c.end(), random_::to); + } +} // namespace random_ + +#endif // RANDOM2_HPP |