summaryrefslogtreecommitdiff
path: root/src/common/random2.hpp
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-02-12 20:18:58 -0800
committerBen Longbons <b.r.longbons@gmail.com>2013-02-12 21:09:59 -0800
commitb17b9021ecf9b16c265d0a6b60faa761b34eae35 (patch)
treee8192de5b2458864f0f5ce5edd0e1ccf5605c644 /src/common/random2.hpp
parent80e36aa669274637bcd5956fbf4020dba1d4739c (diff)
downloadtmwa-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.hpp74
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