1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
#include <iostream>
#include <random>
#include <numeric>
#include <iterator>
// seed the generator
std::mt19937 generator((std::random_device())());
struct DieInterface
{
virtual ~DieInterface() = default;
virtual unsigned operator()() const = 0 ;
virtual unsigned sides() const = 0;
};
struct Die : public DieInterface
{
Die(unsigned nSides) : _dist(1, nSides) {}
unsigned operator()() const { return _dist(generator); }
unsigned sides() const { return _dist.b(); }
private:
mutable std::uniform_int_distribution<unsigned> _dist;
};
struct LoadedDie : public DieInterface
{
using distribution = std::uniform_int_distribution<unsigned>;
LoadedDie(unsigned nSides, unsigned loadedFace, unsigned weight_out_of_100)
: _dist(1, nSides - 1), _face(loadedFace), _weight(weight_out_of_100) {}
unsigned operator()() const
{
using param_type = distribution::param_type;
if (_dist(generator, param_type{ 1, 100 }) >= _weight)
return _face;
else
{
unsigned face = _dist(generator);
if (face >= _face)
++face;
return face;
}
}
unsigned sides() const { return _dist.b() + 1; }
private:
mutable distribution _dist;
unsigned _face;
unsigned _weight;
};
// Take two dice objects, roll them, and return the sum
template <typename iter_type>
unsigned roll(iter_type beg, iter_type end)
{
using die_type = const DieInterface&;
return std::accumulate(beg, end, 0u, [](unsigned x, die_type d) { return x + d(); });
}
int main()
{
Die dice[] = { Die(6), Die(10) };
std::cout << "\nRolling two normal dice:\n";
for (int i = 0; i < 10; ++i)
std::cout << roll(std::begin(dice), std::end(dice)) << '\n';
{
const unsigned faces = 6;
const unsigned loaded_face = 6;
const unsigned weight = 50;
LoadedDie die(faces, loaded_face, weight);
std::cout << "\n\nRolling the loaded die with a 50 percent chance to roll max val:\n";
for (int i = 0; i < 10; ++i)
std::cout << die() << '\n';
}
{
const unsigned faces = 20;
const unsigned loaded_face = 5;
const unsigned weight = 50;
LoadedDie die(faces, loaded_face, weight);
std::cout << "\n\nRolling a 20-sided loaded die: (" << loaded_face << "is loaded)\n";
for (int i = 0; i < 10; ++i)
std::cout << die() << '\n';
}
}
|