deck.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include "deck.h"
  2. #include <sstream>
  3. Deck::Deck() {
  4. cardback = door::ANSIColor(door::COLOR::RED);
  5. init();
  6. }
  7. Deck::Deck(door::ANSIColor backcolor) : cardback{backcolor} { init(); }
  8. void Deck::init(void) {
  9. for (int i = 0; i < 52; ++i) {
  10. cards.push_back(card_of(i));
  11. }
  12. // 0 = BLANK, 1-4 levels
  13. for (int i = 0; i < 5; ++i) {
  14. backs.push_back(back_of(i));
  15. }
  16. }
  17. Deck::~Deck() {
  18. for (auto c : cards) {
  19. delete c;
  20. }
  21. cards.clear();
  22. for (auto b : backs) {
  23. delete b;
  24. }
  25. backs.clear();
  26. }
  27. int Deck::is_suit(int c) { return c / 13; }
  28. int Deck::is_rank(int c) { return c % 13; }
  29. char Deck::rank_symbol(int c) {
  30. switch (c) {
  31. case 0:
  32. return 'A';
  33. case 1:
  34. case 2:
  35. case 3:
  36. case 4:
  37. case 5:
  38. case 6:
  39. case 7:
  40. case 8:
  41. return char(c + 0x30 + 1);
  42. case 9:
  43. return 'T';
  44. case 10:
  45. return 'J';
  46. case 11:
  47. return 'Q';
  48. case 12:
  49. return 'K';
  50. }
  51. return '?';
  52. }
  53. std::string Deck::suit_symbol(int c) {
  54. // unicode
  55. if (door::unicode) {
  56. switch (c) {
  57. case 0:
  58. return std::string("\u2665");
  59. case 1:
  60. return std::string("\u2666");
  61. case 2:
  62. return std::string("\u2663");
  63. case 3:
  64. return std::string("\u2660");
  65. }
  66. } else {
  67. switch (c) {
  68. case 0:
  69. return std::string(1, '\x03');
  70. case 1:
  71. return std::string(1, '\x04');
  72. case 2:
  73. return std::string(1, '\x05');
  74. case 3:
  75. return std::string(1, '\x06');
  76. }
  77. }
  78. return std::string("!", 1);
  79. }
  80. door::Panel *Deck::card_of(int c) {
  81. int suit = is_suit(c);
  82. int rank = is_rank(c);
  83. bool is_red = (suit < 2);
  84. door::ANSIColor color;
  85. if (is_red) {
  86. color = door::ANSIColor(door::COLOR::RED, door::COLOR::WHITE);
  87. } else {
  88. color = door::ANSIColor(door::COLOR::BLACK, door::COLOR::WHITE);
  89. }
  90. door::Panel *p = new door::Panel(0, 0, 5);
  91. // setColor sets border_color. NOT WHAT I WANT.
  92. // p->setColor(color);
  93. char r = rank_symbol(rank);
  94. std::string s = suit_symbol(suit);
  95. // build lines
  96. std::ostringstream oss;
  97. oss << r << s << " ";
  98. std::string str = oss.str();
  99. p->addLine(std::make_unique<door::Line>(str, 5, color));
  100. oss.str(std::string());
  101. oss.clear();
  102. oss << " " << s << " ";
  103. str = oss.str();
  104. p->addLine(std::make_unique<door::Line>(str, 5, color));
  105. oss.str(std::string());
  106. oss.clear();
  107. oss << " " << s << r;
  108. str = oss.str();
  109. p->addLine(std::make_unique<door::Line>(str, 5, color));
  110. oss.str(std::string());
  111. oss.clear();
  112. return p;
  113. }
  114. std::string Deck::back_char(int level) {
  115. std::string c;
  116. if (level == 0) {
  117. c = ' ';
  118. return c;
  119. }
  120. if (door::unicode) {
  121. switch (level) {
  122. case 1:
  123. c = "\u2591";
  124. break;
  125. case 2:
  126. c = "\u2592";
  127. break;
  128. case 3:
  129. c = "\u2593";
  130. break;
  131. case 4:
  132. c = "\u2588";
  133. break;
  134. }
  135. } else {
  136. switch (level) {
  137. case 1:
  138. c = "\xb0";
  139. break;
  140. case 2:
  141. c = "\xb1";
  142. break;
  143. case 3:
  144. c = "\xb2";
  145. break;
  146. case 4:
  147. c = "\xdb";
  148. break;
  149. }
  150. }
  151. return c;
  152. }
  153. door::Panel *Deck::back_of(int level) {
  154. // using: \xb0, 0xb1, 0xb2, 0xdb
  155. // OR: \u2591, \u2592, \u2593, \u2588
  156. // door::ANSIColor color(door::COLOR::RED, door::COLOR::BLACK);
  157. door::Panel *p = new door::Panel(0, 0, 5);
  158. std::string c = back_char(level);
  159. std::string l = c + c + c + c + c;
  160. p->addLine(std::make_unique<door::Line>(l, 5, cardback));
  161. p->addLine(std::make_unique<door::Line>(l, 5, cardback));
  162. p->addLine(std::make_unique<door::Line>(l, 5, cardback));
  163. return p;
  164. }
  165. void Deck::part(int x, int y, door::Door &d, int level, bool left) {
  166. // Render part of the back of a card.
  167. y += 2;
  168. if (!left) {
  169. x += 2;
  170. }
  171. std::string c = back_char(level);
  172. std::string l = c + c + c;
  173. door::Goto g(x, y);
  174. d << g << cardback << l;
  175. }
  176. door::Panel *Deck::card(int c) { return cards[c]; }
  177. door::Panel *Deck::back(int level) { return backs[level]; }
  178. /*
  179. 1 2 3 4 5 6
  180. 0123456789012345678901234567890123456789012345678901234567890
  181. ░░░░░ ░░░░░ ░░░░░
  182. ░░░░░ ░░░░░ ░░░░░
  183. ▒▒▒▒▒░▒▒▒▒▒ #####░##### #####░#####
  184. ▒▒▒▒▒ ▒▒▒▒▒ ##### ##### ##### #####
  185. ▓▓▓▓▓▒▓▓▓▓▓▒▓▓▓▓▓ #####=#####=##### #####=#####=#####
  186. ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ##### ##### ##### ##### ##### #####
  187. █████▓█████▓█████▓#####=#####=#####=#####=#####=#####=#####
  188. █████ █████ █████ ##### ##### ##### ##### ##### ##### #####
  189. █████ █████ █████ ##### ##### ##### ##### ##### ##### #####
  190. */
  191. void cardgo(int pos, int &x, int &y, int &level) {
  192. /*
  193. int levels[4] = {3, 6, 9, 10};
  194. for (level = 0; level < 4; ++level) {
  195. if (pos < levels[level]) {
  196. level++;
  197. // we're here
  198. y = (level -1) * 2 + 1;
  199. } else {
  200. pos -= levels[level];
  201. }
  202. }
  203. */
  204. if (pos < 3) {
  205. // top
  206. level = 1;
  207. y = (level - 1) * 2 + 1;
  208. x = (pos)*18 + 10;
  209. return;
  210. } else {
  211. pos -= 3;
  212. }
  213. if (pos < 6) {
  214. level = 2;
  215. y = (level - 1) * 2 + 1;
  216. int group = (pos) / 2;
  217. x = (pos)*6 + (group * 6) + 7;
  218. return;
  219. } else {
  220. pos -= 6;
  221. }
  222. if (pos < 9) {
  223. level = 3;
  224. y = (level - 1) * 2 + 1;
  225. x = (pos)*6 + 4;
  226. return;
  227. } else {
  228. pos -= 9;
  229. }
  230. if (pos < 10) {
  231. level = 4;
  232. y = (level - 1) * 2 + 1;
  233. x = (pos)*6 + 1;
  234. return;
  235. } else {
  236. // something is wrong.
  237. y = -1;
  238. x = -1;
  239. level = -1;
  240. }
  241. }