io.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //
  2. // io.h
  3. // dice-roll
  4. //
  5. // Created by Sam Jaffe on 7/24/24.
  6. // Copyright © 2024 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <iostream>
  10. #include "dice-roll/die.h"
  11. #include "dice-roll/roll.h"
  12. namespace dice {
  13. template <typename OStream> OStream & operator<<(OStream & os, outcome e) {
  14. switch (e) {
  15. case outcome::PASS:
  16. return os << "PASS";
  17. case outcome::FAIL:
  18. return os << "FAIL";
  19. }
  20. }
  21. template <typename OStream> OStream & operator<<(OStream & os, sign s) {
  22. switch (s) {
  23. case sign::PLUS:
  24. return os << '+';
  25. case sign::MINUS:
  26. return os << '-';
  27. case sign::ZERO:
  28. return os;
  29. }
  30. }
  31. template <typename OStream>
  32. OStream & operator<<(OStream & os, difficulty_class::test t) {
  33. switch (t) {
  34. case difficulty_class::test::None:
  35. return os;
  36. case difficulty_class::test::Less:
  37. return os << '<';
  38. case difficulty_class::test::LessOrEqual:
  39. return os << '<' << '=';
  40. case difficulty_class::test::Greater:
  41. return os << '>';
  42. case difficulty_class::test::GreaterOrEqual:
  43. return os << '>' << '=';
  44. }
  45. }
  46. template <typename OStream> OStream & operator<<(OStream & os, keep const & k) {
  47. switch (k.method) {
  48. case keep::Highest:
  49. return os << 'k' << 'h' << k.amount;
  50. case keep::Lowest:
  51. return os << 'k' << 'l' << k.amount;
  52. default:
  53. return os;
  54. }
  55. }
  56. template <typename OStream> OStream & operator<<(OStream & os, dice const & d) {
  57. if (d.num != 1) os << d.num << '{';
  58. for (die const & di : d.of) {
  59. os << di.sgn << di.num << 'd' << di.sides << di.keep;
  60. }
  61. for (mod m : d.modifier) {
  62. os << m.sign << m.value;
  63. }
  64. if (d.dc.comp != difficulty_class::test::None) {
  65. os << d.dc.comp << d.dc.against;
  66. }
  67. if (d.num != 1) os << '}';
  68. return os;
  69. }
  70. template <typename OStream>
  71. OStream & operator<<(OStream & os, die_outcome const & r) {
  72. return os << r.roll;
  73. }
  74. template <typename OStream>
  75. OStream & operator<<(OStream & os, die_roll const & r) {
  76. os << r.sign;
  77. switch (r.rolled.size()) {
  78. case 0:
  79. // Prevent crashes if we somehow get a 0dM expression
  80. return os << "0";
  81. case 1:
  82. // Don't bother with braces if there's only a single roll,
  83. // the braces are for grouping purposes.
  84. return os << r.rolled[0];
  85. default:
  86. os << "[ ";
  87. os << r.rolled[0];
  88. for (int i = 1; i < r.rolled.size(); ++i) {
  89. os << ", " << r.rolled[i];
  90. }
  91. return os << " ]";
  92. }
  93. }
  94. template <typename OStream>
  95. OStream & operator<<(OStream & os, dice_roll const & r) {
  96. for (die_roll const & dr : r.sub_rolls) {
  97. os << dr;
  98. }
  99. for (mod const & m : r.modifiers) {
  100. os << m.sign << m.value;
  101. }
  102. return os;
  103. }
  104. template <typename OStream>
  105. OStream & operator<<(OStream & os,
  106. std::pair<dice, std::vector<dice_roll>> const & pair) {
  107. os << "Result of '" << pair.first << "':";
  108. if (pair.second.size() == 1) {
  109. os << ' ';
  110. std::visit([&os](auto v) { os << v; }, pair.second[0].result());
  111. return os << ' ' << '(' << pair.second[0] << ')';
  112. }
  113. for (int i = 0; i < pair.second.size(); ++i) {
  114. os << "\n Result/" << i << ": ";
  115. std::visit([&os](auto v) { os << v; }, pair.second[i].result());
  116. os << ' ' << '(' << pair.second[i] << ')';
  117. }
  118. return os;
  119. }
  120. }