| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- //
- // roll.cxx
- // dice-roll
- //
- // Created by Sam Jaffe on 12/1/18.
- // Copyright © 2018 Sam Jaffe. All rights reserved.
- //
- #include "dice-roll/roll.h"
- #include <numeric>
- #include "dice-roll/random.h"
- namespace dice {
- int add_outcome(int accum, die_outcome const & die) {
- return accum + (!die.dropped ? die.roll : 0);
- }
- die_roll::operator int() const {
- return sgn(sign) *
- std::accumulate(rolled.begin(), rolled.end(), 0, &add_outcome);
- }
- dice_roll::operator int() const {
- auto subtotal = std::accumulate(sub_rolls.begin(), sub_rolls.end(), 0) +
- std::accumulate(modifiers.begin(), modifiers.end(), 0);
- if (dc.comp != difficulty_class::test::None) {
- return static_cast<int>(dc(subtotal));
- } else {
- return subtotal;
- }
- }
- std::variant<int, outcome> dice_roll::result() const {
- auto value = static_cast<int>(*this);
- if (dc.comp != difficulty_class::test::None) {
- return value ? outcome::PASS : outcome::FAIL;
- }
- return value;
- }
- die_roll roll_impl(die const & d, engine::random & gen) {
- std::vector<die_outcome> hits;
- for (int i = 0; i < d.num; ++i) {
- hits.push_back(
- {.roll = static_cast<int>(gen.roll(d.sides)), .sides = d.sides});
- }
- switch (d.keep.method) {
- case keep::Highest:
- for (int i = 0; i < d.num - d.keep.amount; ++i) {
- std::min_element(hits.begin(), hits.end())->dropped = true;
- }
- break;
- case keep::Lowest:
- for (int i = 0; i < d.num - d.keep.amount; ++i) {
- std::max_element(hits.begin(), hits.end())->dropped = true;
- }
- break;
- default:
- break;
- }
- return {d.sgn, hits};
- }
- dice_roll roll_impl(dice const & d, engine::random & gen) {
- std::vector<die_roll> hits;
- for (die const & di : d.of) {
- hits.push_back(roll_impl(di, gen));
- }
- return {hits, d.modifier, d.dc};
- }
- roller::roller() : gen() {}
- roller::roller(engine::random && g) : gen(std::forward<engine::random>(g)) {}
- std::vector<dice_roll> roller::operator()(dice const & d) {
- std::vector<dice_roll> out;
- for (int i = 0; i < d.num; ++i) {
- out.emplace_back(roll_impl(d, gen));
- }
- return out;
- }
- }
|