| Hit, | Hit, | ||||
| }; | }; | ||||
| enum class Info { | |||||
| None, | |||||
| NewHand, | |||||
| Shuffle, | |||||
| Bye, | |||||
| }; | |||||
| // alphabetically-sorted | // alphabetically-sorted | ||||
| enum class Suit { | enum class Suit { | ||||
| Clubs = 0, | Clubs = 0, | ||||
| std::string singleUTF8; | std::string singleUTF8; | ||||
| }; | }; | ||||
| // TODO: static inside a class | |||||
| extern Card card[52]; | extern Card card[52]; | ||||
| // TODO: base + daugthers, para diferenciar entre dealer y player y otros juegos | |||||
| class Hand { | class Hand { | ||||
| public: | public: | ||||
| std::list<unsigned int> cards; | std::list<unsigned int> cards; | ||||
| } | } | ||||
| */ | */ | ||||
| virtual int play() = 0; | virtual int play() = 0; | ||||
| virtual void info(Info = Info::None, int = 0) = 0; | |||||
| PlayerActionRequired actionRequired = PlayerActionRequired::None; | PlayerActionRequired actionRequired = PlayerActionRequired::None; | ||||
| PlayerActionTaken actionTaken = PlayerActionTaken::None; | PlayerActionTaken actionTaken = PlayerActionTaken::None; |
| bool explicit_seed = conf.set(&rng_seed, {"rng_seed", "seed"}); | bool explicit_seed = conf.set(&rng_seed, {"rng_seed", "seed"}); | ||||
| // TODO: seed instead of dev_random | |||||
| if (explicit_seed) { | if (explicit_seed) { | ||||
| rng = std::mt19937(rng_seed); | rng = std::mt19937(rng_seed); | ||||
| } | } | ||||
| } | } | ||||
| Blackjack::~Blackjack() { | Blackjack::~Blackjack() { | ||||
| std::cout << "Bye bye! We'll play Blackjack again next time." << std::endl; | |||||
| return; | |||||
| } | } | ||||
| void Blackjack::deal(Player *player) { | void Blackjack::deal(Player *player) { | ||||
| // clear dealer's hand | // clear dealer's hand | ||||
| hand.holeCardShown = false; | hand.holeCardShown = false; | ||||
| hand.cards.clear(); | 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 | // erase all the player's hands, create one, add and make it the current one | ||||
| for (auto playerHand : player->hands) { | for (auto playerHand : player->hands) { | ||||
| // player->hasDoubled = 0; | // player->hasDoubled = 0; | ||||
| if (lastPass) { | 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 the cards | ||||
| shuffle(); | shuffle(); | ||||
| // TODO: reset card counting systems | |||||
| // burn as many cards as asked | // burn as many cards as asked | ||||
| for (int i = 0; i < number_of_burnt_cards; i++) { | for (int i = 0; i < number_of_burnt_cards; i++) { | ||||
| // drawCard(); | |||||
| drawCard(); | |||||
| } | } | ||||
| lastPass = false; | lastPass = false; | ||||
| } | } | ||||
| nextAction = DealerAction::AskForBets; | nextAction = DealerAction::AskForBets; | ||||
| } | } | ||||
| std::cout << "new_hand" << std::endl; | |||||
| player->info(Info::NewHand, n_hand); | |||||
| return; | return; | ||||
| break; | break; | ||||
| // ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
| case DealerAction::AskForBets: | case DealerAction::AskForBets: | ||||
| // step 1. ask for bets | // 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; | player->actionRequired = PlayerActionRequired::Bet; | ||||
| return; | return; | ||||
| break; | break; |
| #include "base.h" | #include "base.h" | ||||
| #include "conf.h" | #include "conf.h" | ||||
| class Blackjack : public Dealer { | class Blackjack : public Dealer { | ||||
| public: | public: | ||||
| Blackjack(Configuration &); | Blackjack(Configuration &); | ||||
| ~Blackjack(); | ~Blackjack(); | ||||
| void shuffle() override; | void shuffle() override; | ||||
| unsigned int drawCard(Hand *) override; | |||||
| unsigned int drawCard(Hand * = nullptr) override; | |||||
| void deal(Player *) override; | void deal(Player *) override; | ||||
| int process(Player *) override; | int process(Player *) override; | ||||
| StdInOut::StdInOut(void) { | StdInOut::StdInOut(void) { | ||||
| } | } | ||||
| void StdInOut::info(Info msg, int data) { | |||||
| return; | |||||
| } | |||||
| int StdInOut::play() { | int StdInOut::play() { | ||||
| ~StdInOut() { }; | ~StdInOut() { }; | ||||
| int play(void) override; | int play(void) override; | ||||
| void info(Info = Info::None, int = 0) override; | |||||
| private: | private: | ||||
| std::string input_buffer; | std::string input_buffer; |
| #include <iostream> | #include <iostream> | ||||
| #include <cstring> | #include <cstring> | ||||
| #include <thread> | |||||
| #include <chrono> | |||||
| #ifdef HAVE_LIBREADLINE | #ifdef HAVE_LIBREADLINE | ||||
| #include <readline/readline.h> | #include <readline/readline.h> | ||||
| Tty::Tty(Configuration &conf) { | 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 | #ifdef HAVE_LIBREADLINE | ||||
| prompt = cyan + " > " + reset; | prompt = cyan + " > " + reset; | ||||
| #endif | #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() { | int Tty::play() { | ||||
| #ifdef HAVE_LIBREADLINE | #ifdef HAVE_LIBREADLINE |
| class Tty : public Player { | class Tty : public Player { | ||||
| public: | public: | ||||
| Tty(Configuration &); | Tty(Configuration &); | ||||
| ~Tty() { | |||||
| std::cout << "bye!" << std::endl; | |||||
| }; | |||||
| ~Tty() { }; | |||||
| int play() override; | int play() override; | ||||
| void info(Info = Info::None, int = 0) override; | |||||
| private: | private: | ||||
| #else | #else | ||||
| std::string input_buffer; | std::string input_buffer; | ||||
| #endif | #endif | ||||
| std::string arrow; | |||||
| std::string prompt; | std::string prompt; | ||||
| int delay = 200; | |||||
| std::string black = "\x1B[0m"; | std::string black = "\x1B[0m"; | ||||
| std::string red = "\x1B[31m"; | std::string red = "\x1B[31m"; |