| /*------------ -------------- -------- --- ----- --- -- - - | |||||
| * Libre Blackjack - standard blackjack dealer | |||||
| * | |||||
| * Copyright (C) 2020 jeremy theler | |||||
| * | |||||
| * This file is part of Libre Blackjack. | |||||
| * | |||||
| * Libre Blackjack is free software: you can redistribute it and/or modify | |||||
| * it under the terms of the GNU General Public License as published by | |||||
| * the Free Software Foundation, either version 3 of the License, or | |||||
| * (at your option) any later version. | |||||
| * | |||||
| * Libre Blackjack is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU General Public License | |||||
| * along with Libre Blackjack. If not, see <http://www.gnu.org/licenses/>. | |||||
| *------------------- ------------ ---- -------- -- - - - | |||||
| */ | |||||
| #ifndef BASE_H | |||||
| #define BASE_H | |||||
| enum class DealerAction { | |||||
| None, | |||||
| StartNewHand, | |||||
| AskForBets, | |||||
| DealPlayerFirstCard, | |||||
| DealDealerHoleCard, | |||||
| AskForInsurance, | |||||
| CheckforBlackjacks, | |||||
| PayOrTakeInsuranceBets, | |||||
| AskForPlay, | |||||
| MoveOnToNextHand, | |||||
| HitDealerHand, | |||||
| Payout | |||||
| }; | |||||
| enum class PlayerAction { | |||||
| None, | |||||
| Bet, | |||||
| Insurance, | |||||
| Play | |||||
| }; | |||||
| enum class Command { | |||||
| None, | |||||
| // common | |||||
| Quit, | |||||
| Help, | |||||
| Count, | |||||
| UpcardValue, | |||||
| Bankroll, | |||||
| Hands, | |||||
| Table, | |||||
| // particular | |||||
| Bet, | |||||
| Yes, | |||||
| No, | |||||
| Stand, | |||||
| Double, | |||||
| Split, | |||||
| Hit, | |||||
| }; | |||||
| class Dealer { | |||||
| public: | |||||
| Dealer() {}; | |||||
| ~Dealer() {}; | |||||
| // delete copy and move constructors | |||||
| Dealer(Dealer&) = delete; | |||||
| Dealer(const Dealer&) = delete; | |||||
| Dealer(Dealer &&) = delete; | |||||
| Dealer(const Dealer &&) = delete; | |||||
| virtual void deal() = 0; | |||||
| // virtual void ask() = 0; | |||||
| virtual int process(Command) = 0; | |||||
| void setNextAction(DealerAction a) { | |||||
| next_action = a; | |||||
| } | |||||
| bool getInputNeeded(void) { | |||||
| return input_needed; | |||||
| } | |||||
| void setInputNeeded(bool flag) { | |||||
| input_needed = flag; | |||||
| } | |||||
| bool finished(void) { | |||||
| return done; | |||||
| } | |||||
| bool finished(bool d) { | |||||
| return (done = d); | |||||
| } | |||||
| private: | |||||
| bool done = false; | |||||
| bool input_needed = false; | |||||
| DealerAction next_action = DealerAction::None; | |||||
| PlayerAction player_action = PlayerAction::None; | |||||
| Command player_command = Command::None; | |||||
| double insurance = 0; | |||||
| int bet = 0; | |||||
| }; | |||||
| class Player { | |||||
| public: | |||||
| Player() = default; | |||||
| ~Player() = default; | |||||
| // delete copy and move constructors | |||||
| Player(Player&) = delete; | |||||
| Player(const Player&) = delete; | |||||
| Player(Player &&) = delete; | |||||
| Player(const Player &&) = delete; | |||||
| virtual int play(Command *, int *) = 0; | |||||
| }; | |||||
| #endif |
| #include "blackjack.h" | #include "blackjack.h" | ||||
| Blackjack::Blackjack() { | Blackjack::Blackjack() { | ||||
| std::cout << "I'm your dealer" << std::endl; | |||||
| std::cout << "I'm your Blackjack dealer!" << std::endl; | |||||
| } | } | ||||
| Blackjack::~Blackjack() { | Blackjack::~Blackjack() { | ||||
| std::cout << "Bye bye" << std::endl; | |||||
| std::cout << "Bye bye! We'll play Blackjack again next time." << std::endl; | |||||
| } | } | ||||
| void Blackjack::deal() { | void Blackjack::deal() { | ||||
| std::cout << "here are your cards" << std::endl; | |||||
| std::cout << "Here are your cards" << std::endl; | |||||
| setInputNeeded(true); | setInputNeeded(true); | ||||
| } | } | ||||
| #ifndef BLACKJACK_H | #ifndef BLACKJACK_H | ||||
| #define BLACKJACK_H | #define BLACKJACK_H | ||||
| enum class DealerAction { | |||||
| None, | |||||
| StartNewHand, | |||||
| AskForBets, | |||||
| DealPlayerFirstCard, | |||||
| DealDealerHoleCard, | |||||
| AskForInsurance, | |||||
| CheckforBlackjacks, | |||||
| PayOrTakeInsuranceBets, | |||||
| AskForPlay, | |||||
| MoveOnToNextHand, | |||||
| HitDealerHand, | |||||
| Payout | |||||
| }; | |||||
| enum class PlayerAction { | |||||
| None, | |||||
| Bet, | |||||
| Insurance, | |||||
| Play | |||||
| }; | |||||
| enum class Command { | |||||
| None, | |||||
| // common | |||||
| Quit, | |||||
| Help, | |||||
| Count, | |||||
| UpcardValue, | |||||
| Bankroll, | |||||
| Hands, | |||||
| Table, | |||||
| // particular | |||||
| Bet, | |||||
| Yes, | |||||
| No, | |||||
| Stand, | |||||
| Double, | |||||
| Split, | |||||
| Hit, | |||||
| }; | |||||
| class Blackjack { | |||||
| public: | |||||
| #include "base.h" | |||||
| class Blackjack : public Dealer { | |||||
| public: | |||||
| Blackjack(); | Blackjack(); | ||||
| ~Blackjack(); | ~Blackjack(); | ||||
| // delete copy and move constructors | |||||
| Blackjack(Blackjack&) = delete; | |||||
| Blackjack(const Blackjack&) = delete; | |||||
| Blackjack(Blackjack &&) = delete; | |||||
| Blackjack(const Blackjack &&) = delete; | |||||
| void deal(); | |||||
| void ask(); | |||||
| int process(Command); | |||||
| void setNextAction(DealerAction a) { | |||||
| next_action = a; | |||||
| } | |||||
| bool getInputNeeded(void) { | |||||
| return input_needed; | |||||
| } | |||||
| void setInputNeeded(bool flag) { | |||||
| input_needed = flag; | |||||
| } | |||||
| bool finished(void) { | |||||
| return done; | |||||
| } | |||||
| bool finished(bool d) { | |||||
| return (done = d); | |||||
| } | |||||
| private: | |||||
| bool done = false; | |||||
| bool input_needed = false; | |||||
| DealerAction next_action = DealerAction::None; | |||||
| PlayerAction player_action = PlayerAction::None; | |||||
| Command player_command = Command::None; | |||||
| double insurance = 0; | |||||
| int bet = 0; | |||||
| void deal() override; | |||||
| int process(Command) override; | |||||
| }; | }; | ||||
| class Player { | |||||
| public: | |||||
| Player() = default; | |||||
| ~Player() = default; | |||||
| // delete copy and move constructors | |||||
| Player(Player&) = delete; | |||||
| Player(const Player&) = delete; | |||||
| Player(Player &&) = delete; | |||||
| Player(const Player &&) = delete; | |||||
| virtual int play(Command *, int *) = 0; | |||||
| }; | |||||
| #endif | #endif |
| #include <iostream> | #include <iostream> | ||||
| #include "base.h" | |||||
| #include "blackjack.h" | #include "blackjack.h" | ||||
| #include "stdinout.h" | #include "stdinout.h" | ||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
| // TODO: read args/conf to see what dealer we need to play | |||||
| Dealer *dealer = nullptr; | |||||
| Player *player = nullptr; | |||||
| // TODO: read the args/conf to know what kind of dealer and player we are having | |||||
| // TODO: pass args/conf to the constructor | // TODO: pass args/conf to the constructor | ||||
| Blackjack dealer; | |||||
| StdInOut player; | |||||
| dealer = new Blackjack(); | |||||
| player = new StdInOut(); | |||||
| std::cout << "Let's play" << std::endl; | std::cout << "Let's play" << std::endl; | ||||
| dealer.setNextAction(DealerAction::StartNewHand); | |||||
| dealer->setNextAction(DealerAction::StartNewHand); | |||||
| Command command = Command::None; | |||||
| Command command{Command::None}; | |||||
| while (!dealer.finished()) { | |||||
| dealer.setInputNeeded(false); | |||||
| // TODO: clean buffers | |||||
| dealer.deal(); | |||||
| if (dealer.getInputNeeded()) { | |||||
| while (!dealer->finished()) { | |||||
| dealer->setInputNeeded(false); | |||||
| dealer->deal(); | |||||
| if (dealer->getInputNeeded()) { | |||||
| do { | do { | ||||
| // TODO: check for too many errors meaning dealer and player do not understand each other | // TODO: check for too many errors meaning dealer and player do not understand each other | ||||
| player.play(&command, nullptr); | |||||
| } while (dealer.process(command) <= 0); | |||||
| player->play(&command, nullptr); | |||||
| } while (dealer->process(command) <= 0); | |||||
| } | } | ||||
| } | } | ||||
| // TODO: write report | // TODO: write report | ||||
| delete player; | |||||
| delete dealer; | |||||
| } | } |
| #define STDINOUT_H | #define STDINOUT_H | ||||
| #include "blackjack.h" | #include "blackjack.h" | ||||
| class StdInOut : Player { | |||||
| class StdInOut : public Player { | |||||
| public: | public: | ||||
| StdInOut() { }; | StdInOut() { }; | ||||
| ~StdInOut() { }; | ~StdInOut() { }; |