roll.cxx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //
  2. // roll.cxx
  3. // dice-roll
  4. //
  5. // Created by Sam Jaffe on 12/1/18.
  6. // Copyright © 2018 Sam Jaffe. All rights reserved.
  7. //
  8. #include "roll.h"
  9. #include <iostream>
  10. #include <memory>
  11. #include <numeric>
  12. #include "random.h"
  13. namespace dice {
  14. die_roll::operator int() const {
  15. return sgn(sign) * std::accumulate(rolled.begin(), rolled.end(), 0);
  16. }
  17. dice_roll::operator int() const {
  18. return std::accumulate(sub_rolls.begin(), sub_rolls.end(), 0) +
  19. std::accumulate(modifiers.begin(), modifiers.end(), 0);
  20. }
  21. std::ostream & operator<<(std::ostream & out, die_roll const & r) {
  22. out << str(r.sign);
  23. switch (r.rolled.size()) {
  24. case 0:
  25. // Prevent crashes if we somehow get a 0dM expression
  26. return out << "0";
  27. case 1:
  28. // Don't bother with braces if there's only a single roll,
  29. // the braces are for grouping purposes.
  30. return out << r.rolled[0];
  31. default:
  32. out << "[ ";
  33. out << r.rolled[0];
  34. for (int i = 1; i < r.rolled.size(); ++i) {
  35. out << ", " << r.rolled[i];
  36. }
  37. return out << " ]";
  38. }
  39. }
  40. std::ostream & operator<<(std::ostream & out, dice_roll const & r) {
  41. for (die_roll const & dr : r.sub_rolls) {
  42. out << dr;
  43. }
  44. for (mod const & m : r.modifiers) {
  45. out << str(m.sign) << m.value;
  46. }
  47. return out;
  48. }
  49. die_roll roll_impl(die const & d, engine::random & gen) {
  50. std::vector<int> hits;
  51. for (int i = 0; i < d.num; ++i) {
  52. hits.push_back(gen.roll(d.sides));
  53. }
  54. return {d.sgn, hits};
  55. }
  56. dice_roll roll_impl(dice const & d, engine::random & gen) {
  57. std::vector<die_roll> hits;
  58. for (die const & di : d.of) {
  59. hits.push_back(roll_impl(di, gen));
  60. }
  61. return {hits, d.modifier};
  62. }
  63. roller::roller() : gen() {}
  64. roller::roller(engine::random && g)
  65. : gen(std::forward<engine::random>(g)) {
  66. }
  67. std::vector<dice_roll> roller::operator()(dice const & d) {
  68. std::vector<dice_roll> out;
  69. for (int i = 0; i < d.num; ++i) {
  70. out.emplace_back(roll_impl(d, gen));
  71. }
  72. return out;
  73. }
  74. }