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

292 行
6.3KB

  1. /*------------ -------------- -------- --- ----- --- -- - -
  2. * Libre Blackjack - base classes
  3. *
  4. * Copyright (C) 2020 jeremy theler
  5. *
  6. * This file is part of Libre Blackjack.
  7. *
  8. * Libre Blackjack is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * Libre Blackjack is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with Libre Blackjack. If not, see <http://www.gnu.org/licenses/>.
  20. *------------------- ------------ ---- -------- -- - - -
  21. */
  22. #ifndef BASE_H
  23. #define BASE_H
  24. #include <string>
  25. #include <list>
  26. #include <random>
  27. #include <cmath>
  28. namespace Libreblackjack {
  29. void shortversion(void);
  30. void help(const char *);
  31. void copyright(void);
  32. }
  33. // TODO: namespace
  34. enum class DealerAction {
  35. None,
  36. StartNewHand,
  37. AskForBets,
  38. DealPlayerFirstCard,
  39. AskForInsurance,
  40. CheckforBlackjacks,
  41. AskForPlay,
  42. MoveOnToNextHand,
  43. HitDealerHand,
  44. };
  45. enum class PlayerActionRequired {
  46. None,
  47. Bet,
  48. Insurance,
  49. Play
  50. };
  51. enum class PlayerActionTaken {
  52. None,
  53. // common
  54. Quit,
  55. Help,
  56. Count,
  57. UpcardValue,
  58. Bankroll,
  59. Hands,
  60. Table,
  61. // particular
  62. Bet,
  63. Insure,
  64. DontInsure,
  65. Stand,
  66. Double,
  67. Split,
  68. Hit,
  69. };
  70. enum class Info {
  71. None,
  72. InvalidBet,
  73. NewHand,
  74. Shuffle,
  75. CardPlayer,
  76. CardDealer,
  77. CardDealerRevealsHole,
  78. DealerBlackjack,
  79. PlayerWinsInsurance,
  80. PlayerBlackjackAlso,
  81. PlayerPushes,
  82. PlayerLosses,
  83. PlayerBlackjack,
  84. PlayerWins,
  85. NoBlackjacks,
  86. PlayerBustsAllHands,
  87. DealerBusts,
  88. Help,
  89. Bye,
  90. };
  91. // alphabetically-sorted
  92. enum class Suit {
  93. Clubs = 0,
  94. Diamonds = 1,
  95. Hearts = 2,
  96. Spades = 3
  97. };
  98. class Card {
  99. public:
  100. Card(unsigned int);
  101. ~Card() { };
  102. // TODO: delete copy & move
  103. // TODO: decidir si conviene usar getters o public members
  104. Suit getSuit() { return suit; };
  105. unsigned int getNumber() { return number; };
  106. unsigned int getValue() { return value; };
  107. std::string getNumberASCII() { return numberASCII; };
  108. std::string getSuitUTF8() { return suitUTF8; };
  109. Suit suit;
  110. unsigned int number;
  111. unsigned int value;
  112. std::string ascii() {
  113. return numberASCII + suitASCII;
  114. }
  115. std::string utf8(bool single = false) {
  116. return single ? singleUTF8 : numberASCII + suitUTF8;
  117. }
  118. std::string text();
  119. private:
  120. std::string numberASCII;
  121. std::string suitASCII;
  122. std::string suitUTF8;
  123. std::string suitName;
  124. std::string singleUTF8;
  125. };
  126. // TODO: static inside a class
  127. extern Card card[52];
  128. class Hand {
  129. public:
  130. std::list<int> cards;
  131. // inline on purpose
  132. int total() {
  133. unsigned int soft = 0;
  134. unsigned int n = 0;
  135. unsigned int value = 0;
  136. for (auto tag : cards) {
  137. value = card[tag].value;
  138. n += value;
  139. soft += (value == 11);
  140. }
  141. // this loop should be only executed once if everything works fine
  142. while (n > 21 && soft > 0){
  143. n -= 10;
  144. soft--;
  145. }
  146. return (soft)?(-n):(n);
  147. };
  148. // inline on purpose
  149. bool blackjack() {
  150. return (std::abs(total()) == 21 && cards.size() == 2);
  151. };
  152. // inline on purpose
  153. bool busted() {
  154. return (std::abs(total()) > 21);
  155. }
  156. };
  157. class PlayerHand : public Hand {
  158. public:
  159. int bet = 0;
  160. int id = 0;
  161. bool insured = false;
  162. bool doubled = false;
  163. };
  164. class Player {
  165. public:
  166. Player() = default;
  167. virtual ~Player() = default;
  168. // delete copy and move constructors
  169. Player(Player&) = delete;
  170. Player(const Player&) = delete;
  171. Player(Player &&) = delete;
  172. Player(const Player &&) = delete;
  173. virtual int play() = 0;
  174. virtual void info(Info = Info::None, int = 0) = 0;
  175. PlayerActionRequired actionRequired = PlayerActionRequired::None;
  176. PlayerActionTaken actionTaken = PlayerActionTaken::None;
  177. bool bustedAllHands = false;
  178. unsigned int currentSplits = 0;
  179. unsigned int currentBet = 0;
  180. unsigned int n_hands = 0; // this is different from the dealer's due to splitting
  181. unsigned int handsInsured = 0;
  182. unsigned int handsDoubled = 0;
  183. unsigned int blackjacksPlayer = 0;
  184. unsigned int blackjacksDealer = 0;
  185. unsigned int bustsPlayer = 0;
  186. unsigned int bustsDealer = 0;
  187. unsigned int wins = 0;
  188. unsigned int winsInsured = 0;
  189. unsigned int winsDoubled = 0;
  190. unsigned int winsBlackjack = 0;
  191. unsigned int pushes = 0;
  192. unsigned int losses = 0;
  193. // TODO: blackjack_pushes?
  194. unsigned int flat_bet = 1;
  195. bool no_insurance = false;
  196. bool always_insure = false;
  197. double bankroll = 0;
  198. double worst_bankroll = 0;
  199. double total_money_waged = 0;
  200. double current_result = 0;
  201. double mean = 0;
  202. double M2 = 0;
  203. double variance = 0;
  204. std::list<PlayerHand> hands;
  205. std::list<PlayerHand>::iterator currentHand;
  206. Hand dealerHand;
  207. };
  208. class Dealer {
  209. public:
  210. Dealer() = default;
  211. virtual ~Dealer() = default;
  212. // delete copy and move constructors
  213. Dealer(Dealer&) = delete;
  214. Dealer(const Dealer&) = delete;
  215. Dealer(Dealer &&) = delete;
  216. Dealer(const Dealer &&) = delete;
  217. // maybe this first one does not need to be deleted
  218. virtual void shuffle() = 0;
  219. virtual void deal(Player *) = 0;
  220. virtual unsigned int drawCard(Hand * = nullptr) = 0;
  221. virtual int process(Player *) = 0;
  222. /*
  223. void setNextAction(DealerAction a) {
  224. next_action = a;
  225. }
  226. void getNextAction(DealerAction a) {
  227. next_action = a;
  228. }
  229. */
  230. bool finished(void) {
  231. return done;
  232. }
  233. bool finished(bool d) {
  234. return (done = d);
  235. }
  236. bool done = false;
  237. DealerAction nextAction = DealerAction::None;
  238. // TODO: most of the games will have a single element, but maybe
  239. // there are games where the dealer has more than one hand
  240. // std::list <Hand> hands;
  241. Hand hand;
  242. };
  243. #endif