選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

91 行
3.0KB

  1. #include <iostream>
  2. #include <cmath>
  3. #include <memory>
  4. #include <string>
  5. #include "base.h"
  6. // https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf
  7. template<typename ... Args>
  8. std::string string_format( const std::string& format, Args ... args)
  9. {
  10. size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0'
  11. if (size <= 0) {
  12. return std::string("");
  13. }
  14. std::unique_ptr<char[]> buf(new char[size]);
  15. snprintf(buf.get(), size, format.c_str(), args ...);
  16. return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
  17. }
  18. void Dealer::updateMeanAndVariance(void) {
  19. double delta = playerStats.currentOutcome - playerStats.mean;
  20. playerStats.mean += delta / (double)(n_hand);
  21. playerStats.M2 += delta * (playerStats.currentOutcome - playerStats.mean);
  22. playerStats.variance = playerStats.M2 / (double)(n_hand);
  23. return;
  24. }
  25. void Dealer::reportPrepare(void) {
  26. // we need to update these statistics after the last played hand
  27. updateMeanAndVariance();
  28. double error = error_standard_deviations * sqrt (playerStats.variance / (double) n_hand);
  29. int precision = (int) (std::ceil(-std::log10(error))) - 2;
  30. if (precision < 0) {
  31. precision = 0;
  32. }
  33. std::string format = "\"(%+." + std::to_string(precision) + "f ± %." + std::to_string(precision) + "f) %%%%\"";
  34. report.push_back(reportItem(1, "result", string_format(format, 100*playerStats.mean, 100*error), 0.0));
  35. report.push_back(reportItem(2, "mean", "%g", playerStats.mean));
  36. report.push_back(reportItem(2, "error", "%g", error));
  37. report.push_back(reportItem(2, "hands", "%g", n_hand));
  38. report.push_back(reportItem(2, "bankroll", "%g", playerStats.bankroll));
  39. report.push_back(reportItem(3, "bustsPlayer", "%g", playerStats.bustsPlayer / (double) n_hand));
  40. report.push_back(reportItem(3, "bustsDealer", "%g", playerStats.bustsDealer / (double) n_hand));
  41. report.push_back(reportItem(3, "wins", "%g", playerStats.wins / (double) n_hand));
  42. report.push_back(reportItem(3, "pushes", "%g", playerStats.pushes / (double) n_hand));
  43. report.push_back(reportItem(3, "losses", "%g", playerStats.losses / (double) n_hand));
  44. report.push_back(reportItem(4, "total_money_waged", "%g", playerStats.totalMoneyWaged));
  45. report.push_back(reportItem(5, "variance", "%g", playerStats.variance));
  46. report.push_back(reportItem(5, "deviation", "%g", sqrt(playerStats.variance)));
  47. return;
  48. }
  49. int Dealer::writeReportYAML(void) {
  50. FILE *out;
  51. if (report_file_path != "") {
  52. out = fopen(report_file_path.c_str(), "w");
  53. } else {
  54. out = stderr;
  55. }
  56. // TODO: choose if comments with explanations are to be added
  57. fprintf(out, "---\n");
  58. for (auto item : report) {
  59. if (item.level <= report_verbosity) {
  60. fprintf(out, "%s: ", item.key.c_str());
  61. fprintf(out, item.format.c_str(), item.value);
  62. fprintf(out, "\n");
  63. }
  64. }
  65. fprintf(out, "...\n");
  66. if (report_file_path != "") {
  67. fclose(out);
  68. }
  69. return 0;
  70. }