highscore.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef __HIGHSCORE_H
  2. #define __HIGHSCORE_H
  3. #include "serialize.h"
  4. #include "common_types.h"
  5. #include "common.h"
  6. #include "bones.h"
  7. #include "nlp.h"
  8. namespace highscore {
  9. struct Scores {
  10. struct order_t {
  11. int dlev;
  12. unsigned int plev;
  13. double worth;
  14. bones::bone_t bone;
  15. size_t scum_streak;
  16. bool victory;
  17. // HACK!
  18. order_t() : dlev(0), plev(0), worth(0), scum_streak(0), victory(false) {}
  19. order_t(int l, const bones::bone_t& b, size_t ss) :
  20. dlev(l),
  21. plev(b.level),
  22. worth(std::max(b.worth, 0.0)),
  23. bone(b),
  24. scum_streak(ss),
  25. victory(b.cause.name == "VICTORY")
  26. {}
  27. };
  28. std::vector<order_t> scores;
  29. Scores() {
  30. try {
  31. serialize::Source source("bones.dat");
  32. std::unordered_map<bones::session_t, size_t> scum_streaks;
  33. while (1) {
  34. try {
  35. bones::key_t key;
  36. bones::pt xy;
  37. bones::bone_t bone;
  38. bones::session_t sess;
  39. serialize::read(source, key);
  40. serialize::read(source, xy);
  41. serialize::read(source, bone);
  42. serialize::read(source, sess);
  43. size_t& ss = scum_streaks[sess];
  44. scores.push_back(order_t(key.worldz, bone, ss));
  45. ++ss;
  46. } catch (...) {
  47. break;
  48. }
  49. }
  50. } catch (...) {
  51. }
  52. }
  53. static bool sort_plev(const order_t& a, const order_t& b) {
  54. if (a.victory > b.victory) return true;
  55. if (a.victory == b.victory && a.plev > b.plev) return true;
  56. if (a.victory == b.victory && a.plev == b.plev && a.dlev > b.dlev) return true;
  57. if (a.victory == b.victory && a.plev == b.plev && a.dlev == b.dlev && a.worth > b.worth) return true;
  58. if (a.victory == b.victory && a.plev == b.plev && a.dlev == b.dlev && a.worth == b.worth &&
  59. a.scum_streak < b.scum_streak) return true;
  60. return false;
  61. }
  62. static bool sort_dlev_d(const order_t& a, const order_t& b) {
  63. if (a.victory > b.victory) return true;
  64. if (a.victory == b.victory && a.dlev > b.dlev) return true;
  65. if (a.victory == b.victory && a.dlev == b.dlev && a.plev > b.plev) return true;
  66. if (a.victory == b.victory && a.dlev == b.dlev && a.plev == b.plev && a.worth > b.worth) return true;
  67. if (a.victory == b.victory && a.dlev == b.dlev && a.plev == b.plev && a.worth > b.worth &&
  68. a.scum_streak < b.scum_streak) return true;
  69. return false;
  70. }
  71. static bool sort_dlev_a(const order_t& a, const order_t& b) {
  72. if (a.victory > b.victory) return true;
  73. if (a.victory == b.victory && a.dlev < b.dlev) return true;
  74. if (a.victory == b.victory && a.dlev == b.dlev && a.plev > b.plev) return true;
  75. if (a.victory == b.victory && a.dlev == b.dlev && a.plev == b.plev && a.worth > b.worth) return true;
  76. if (a.victory == b.victory && a.dlev == b.dlev && a.plev == b.plev && a.worth > b.worth &&
  77. a.scum_streak < b.scum_streak) return true;
  78. return false;
  79. }
  80. static bool sort_worth(const order_t& a, const order_t& b) {
  81. if (a.victory > b.victory) return true;
  82. if (a.victory == b.victory && a.worth > b.worth) return true;
  83. if (a.victory == b.victory && a.worth == b.worth && a.plev > b.plev) return true;
  84. if (a.victory == b.victory && a.worth == b.worth && a.plev == b.plev && a.dlev > b.dlev) return true;
  85. if (a.victory == b.victory && a.worth == b.worth && a.plev == b.plev && a.dlev > b.dlev &&
  86. a.scum_streak < b.scum_streak) return true;
  87. return false;
  88. }
  89. static bool sort_rank(const order_t& a, const order_t& b) {
  90. double ar = ::log(a.plev + 1) * ::log(a.worth + 0.01) * abs(::log(abs(a.dlev) + 0.9));
  91. double br = ::log(b.plev + 1) * ::log(b.worth + 0.01) * abs(::log(abs(b.dlev) + 0.9));
  92. if (ar > br) return true;
  93. return false;
  94. }
  95. template <typename FUNC>
  96. void process(FUNC f, int vfilt = -1, size_t limit = 10, bool uniq = false) {
  97. size_t n = 0;
  98. std::set<std::string> filter;
  99. for (auto i = scores.begin(); i != scores.end() && n < limit; ++i) {
  100. if (vfilt >= 0 && vfilt != (int)i->victory)
  101. continue;
  102. bones::bone_t& bone = i->bone;
  103. if (uniq) {
  104. std::string name = bone.name.name;
  105. std::string::size_type achpos = name.find(" (");
  106. if (achpos != std::string::npos) {
  107. name = name.substr(0, achpos);
  108. }
  109. if (filter.count(name))
  110. continue;
  111. filter.insert(name);
  112. }
  113. if (bone.cause.name.empty())
  114. bone.cause.name = "unnatural causes"_m;
  115. if (bone.name.name.empty())
  116. bone.name.name = "anonymous"_m;
  117. f(n, bone.name, bone.cause, i->plev, i->dlev, i->worth, i->victory, i->scum_streak);
  118. ++n;
  119. }
  120. }
  121. void by_ts() {
  122. std::reverse(scores.begin(), scores.end());
  123. }
  124. void by_plev() {
  125. std::sort(scores.begin(), scores.end(), sort_plev);
  126. }
  127. void by_dlev_d() {
  128. std::sort(scores.begin(), scores.end(), sort_dlev_d);
  129. }
  130. void by_dlev_a() {
  131. std::sort(scores.begin(), scores.end(), sort_dlev_a);
  132. }
  133. void by_worth() {
  134. std::sort(scores.begin(), scores.end(), sort_worth);
  135. }
  136. void by_rank() {
  137. std::sort(scores.begin(), scores.end(), sort_rank);
  138. }
  139. };
  140. }
  141. #endif