// // roll.cxx // dice-roll // // Created by Sam Jaffe on 12/1/18. // Copyright © 2018 Sam Jaffe. All rights reserved. // #include "roll.h" #include #include #include #include "random.h" namespace dice { die_roll::operator int() const { return sgn(sign) * std::accumulate(rolled.begin(), rolled.end(), 0); } dice_roll::operator int() const { return std::accumulate(sub_rolls.begin(), sub_rolls.end(), 0) + std::accumulate(modifiers.begin(), modifiers.end(), 0); } std::ostream & operator<<(std::ostream & out, die_roll const & r) { out << str(r.sign); switch (r.rolled.size()) { case 0: // Prevent crashes if we somehow get a 0dM expression return out << "0"; case 1: // Don't bother with braces if there's only a single roll, // the braces are for grouping purposes. return out << r.rolled[0]; default: out << "[ "; out << r.rolled[0]; for (int i = 1; i < r.rolled.size(); ++i) { out << ", " << r.rolled[i]; } return out << " ]"; } } std::ostream & operator<<(std::ostream & out, dice_roll const & r) { for (die_roll const & dr : r.sub_rolls) { out << dr; } for (mod const & m : r.modifiers) { out << str(m.sign) << m.value; } return out; } die_roll roll_impl(die const & d, engine::random & gen) { std::vector hits; for (int i = 0; i < d.num; ++i) { hits.push_back(gen.roll(d.sides)); } return {d.sgn, hits}; } dice_roll roll_impl(dice const & d, engine::random & gen) { std::vector hits; for (die const & di : d.of) { hits.push_back(roll_impl(di, gen)); } return {hits, d.modifier}; } roller::roller() : gen() {} roller::roller(engine::random && g) : gen(std::forward(g)) { } std::vector roller::operator()(dice const & d) { std::vector out; for (int i = 0; i < d.num; ++i) { out.emplace_back(roll_impl(d, gen)); } return out; } }