| @@ -69,6 +69,13 @@ enum class PlayerActionTaken { | |||
| Hit, | |||
| }; | |||
| enum class Info { | |||
| None, | |||
| NewHand, | |||
| Shuffle, | |||
| Bye, | |||
| }; | |||
| // alphabetically-sorted | |||
| enum class Suit { | |||
| Clubs = 0, | |||
| @@ -112,11 +119,9 @@ class Card { | |||
| std::string singleUTF8; | |||
| }; | |||
| // TODO: static inside a class | |||
| extern Card card[52]; | |||
| // TODO: base + daugthers, para diferenciar entre dealer y player y otros juegos | |||
| class Hand { | |||
| public: | |||
| std::list<unsigned int> cards; | |||
| @@ -189,6 +194,7 @@ class Player { | |||
| } | |||
| */ | |||
| virtual int play() = 0; | |||
| virtual void info(Info = Info::None, int = 0) = 0; | |||
| PlayerActionRequired actionRequired = PlayerActionRequired::None; | |||
| PlayerActionTaken actionTaken = PlayerActionTaken::None; | |||
| @@ -65,14 +65,13 @@ Blackjack::Blackjack(Configuration &conf) : rng(dev_random()), fiftyTwoCards(0, | |||
| bool explicit_seed = conf.set(&rng_seed, {"rng_seed", "seed"}); | |||
| // TODO: seed instead of dev_random | |||
| if (explicit_seed) { | |||
| rng = std::mt19937(rng_seed); | |||
| } | |||
| } | |||
| Blackjack::~Blackjack() { | |||
| std::cout << "Bye bye! We'll play Blackjack again next time." << std::endl; | |||
| return; | |||
| } | |||
| void Blackjack::deal(Player *player) { | |||
| @@ -110,10 +109,6 @@ void Blackjack::deal(Player *player) { | |||
| // clear dealer's hand | |||
| hand.holeCardShown = false; | |||
| hand.cards.clear(); | |||
| for (auto card : hand.cards) { | |||
| std::cout << card << std::endl; | |||
| } | |||
| std::cout << hand.cards.size() << std::endl; | |||
| // erase all the player's hands, create one, add and make it the current one | |||
| for (auto playerHand : player->hands) { | |||
| @@ -129,17 +124,14 @@ void Blackjack::deal(Player *player) { | |||
| // player->hasDoubled = 0; | |||
| if (lastPass) { | |||
| // TODO: send informative messages to the player | |||
| // tell people we are shuffling | |||
| // bjcall (blackjack.current_player->write (player, "shuffling")); | |||
| player->info(Info::Shuffle); | |||
| // shuffle the cards | |||
| shuffle(); | |||
| // TODO: reset card counting systems | |||
| // burn as many cards as asked | |||
| for (int i = 0; i < number_of_burnt_cards; i++) { | |||
| // drawCard(); | |||
| drawCard(); | |||
| } | |||
| lastPass = false; | |||
| } | |||
| @@ -151,7 +143,7 @@ void Blackjack::deal(Player *player) { | |||
| nextAction = DealerAction::AskForBets; | |||
| } | |||
| std::cout << "new_hand" << std::endl; | |||
| player->info(Info::NewHand, n_hand); | |||
| return; | |||
| break; | |||
| @@ -160,9 +152,6 @@ void Blackjack::deal(Player *player) { | |||
| // ------------------------------------------------------------------------- | |||
| case DealerAction::AskForBets: | |||
| // step 1. ask for bets | |||
| // TODO: use an output buffer to re-ask in case no number comes back | |||
| std::cout << "bet?" << std::endl; | |||
| // TODO: setter | |||
| player->actionRequired = PlayerActionRequired::Bet; | |||
| return; | |||
| break; | |||
| @@ -26,13 +26,14 @@ | |||
| #include "base.h" | |||
| #include "conf.h" | |||
| class Blackjack : public Dealer { | |||
| public: | |||
| Blackjack(Configuration &); | |||
| ~Blackjack(); | |||
| void shuffle() override; | |||
| unsigned int drawCard(Hand *) override; | |||
| unsigned int drawCard(Hand * = nullptr) override; | |||
| void deal(Player *) override; | |||
| int process(Player *) override; | |||
| @@ -12,6 +12,9 @@ | |||
| StdInOut::StdInOut(void) { | |||
| } | |||
| void StdInOut::info(Info msg, int data) { | |||
| return; | |||
| } | |||
| int StdInOut::play() { | |||
| @@ -8,6 +8,7 @@ class StdInOut : public Player { | |||
| ~StdInOut() { }; | |||
| int play(void) override; | |||
| void info(Info = Info::None, int = 0) override; | |||
| private: | |||
| std::string input_buffer; | |||
| @@ -1,5 +1,7 @@ | |||
| #include <iostream> | |||
| #include <cstring> | |||
| #include <thread> | |||
| #include <chrono> | |||
| #ifdef HAVE_LIBREADLINE | |||
| #include <readline/readline.h> | |||
| @@ -12,17 +14,38 @@ | |||
| Tty::Tty(Configuration &conf) { | |||
| if (conf.exists("flat_bet")) { | |||
| flat_bet = conf.getInt("flat_bet"); | |||
| } else if (conf.exists("flat_bet")) { | |||
| flat_bet = conf.getInt("flat_bet"); | |||
| } | |||
| conf.set(&flat_bet, {"flat_bet", "flatbet"}); | |||
| conf.set(&no_insurance, {"no_insurance", "dont_insure"}); | |||
| #ifdef HAVE_LIBREADLINE | |||
| prompt = cyan + " > " + reset; | |||
| #endif | |||
| } | |||
| void Tty::info(Info msg, int intData) { | |||
| std::string s; | |||
| switch (msg) { | |||
| case Info::NewHand: | |||
| // s = "new_hand"; | |||
| s = "Starting new hand #" + std::to_string(intData); | |||
| break; | |||
| case Info::Shuffle: | |||
| // s = "shuffle"; | |||
| s = "Deck needs to be shuffled."; | |||
| break; | |||
| case Info::Bye: | |||
| // s = "bye"; | |||
| s = "Bye bye! We'll play Blackjack again next time."; | |||
| break; | |||
| } | |||
| if (delay > 0) { | |||
| std::this_thread::sleep_for(std::chrono::milliseconds(delay)); | |||
| } | |||
| std::cout << green << s << reset << std::endl; | |||
| return; | |||
| } | |||
| int Tty::play() { | |||
| #ifdef HAVE_LIBREADLINE | |||
| @@ -5,11 +5,11 @@ | |||
| class Tty : public Player { | |||
| public: | |||
| Tty(Configuration &); | |||
| ~Tty() { | |||
| std::cout << "bye!" << std::endl; | |||
| }; | |||
| ~Tty() { }; | |||
| int play() override; | |||
| void info(Info = Info::None, int = 0) override; | |||
| private: | |||
| @@ -18,8 +18,11 @@ class Tty : public Player { | |||
| #else | |||
| std::string input_buffer; | |||
| #endif | |||
| std::string arrow; | |||
| std::string prompt; | |||
| int delay = 200; | |||
| std::string black = "\x1B[0m"; | |||
| std::string red = "\x1B[31m"; | |||