From b17b9021ecf9b16c265d0a6b60faa761b34eae35 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Tue, 12 Feb 2013 20:18:58 -0800 Subject: Replace mt_rand with Also add some utility methods and classes. --- src/common/random2.hpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/common/random2.hpp (limited to 'src/common/random2.hpp') 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 + +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 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 + void shuffle(C&& c) + { + std::random_shuffle(c.begin(), c.end(), random_::to); + } +} // namespace random_ + +#endif // RANDOM2_HPP -- cgit v1.2.3-60-g2f50