| blackjack_SOURCES = \ | blackjack_SOURCES = \ | ||||
| src/main.cpp \ | src/main.cpp \ | ||||
| src/conf.cpp \ | src/conf.cpp \ | ||||
| src/version.cpp \ | |||||
| src/blackjack.cpp \ | src/blackjack.cpp \ | ||||
| src/cards.cpp \ | src/cards.cpp \ | ||||
| src/stdinout.cpp \ | src/stdinout.cpp \ |
| flat_bet = 1 | flat_bet = 1 | ||||
| max_bet = 2 | max_bet = 2 | ||||
| arranged_cards = 5,0,7,10 | |||||
| #include <random> | #include <random> | ||||
| #include <cmath> | #include <cmath> | ||||
| namespace Libreblackjack { | |||||
| void shortversion(void); | |||||
| void help(const char *); | |||||
| void copyright(void); | |||||
| } | |||||
| // TODO: namespace | // TODO: namespace | ||||
| enum class DealerAction { | enum class DealerAction { |
| conf.set(&shuffle_every_hand, {"shuffle_every_hand"}); | conf.set(&shuffle_every_hand, {"shuffle_every_hand"}); | ||||
| if (conf.exists("arranged_cards")) { | if (conf.exists("arranged_cards")) { | ||||
| std::istringstream x(conf.getString("arranged_cads")); | |||||
| std::list<std::string> chunks; | |||||
| std::copy(std::istream_iterator<std::string>(x), std::istream_iterator<std::string>(), std::back_inserter(chunks)); | |||||
| for (auto it : chunks) { | |||||
| arranged_cards.push_back(std::stoi(it)); | |||||
| std::istringstream stream(conf.getString("arranged_cards")); | |||||
| std::string token; | |||||
| while(std::getline(stream, token, ',')) { | |||||
| arranged_cards.push_back(std::stoi(token)); | |||||
| } | } | ||||
| } | } | ||||
| // TODO: what's this? | |||||
| conf.set(&infinite_decks_card_number_for_arranged_ones, {"infinite_decks_card_number_for_arranged_ones"}); | |||||
| n_arranged_cards = arranged_cards.size(); | |||||
| bool explicit_seed = conf.set(&rng_seed, {"rng_seed", "seed"}); | bool explicit_seed = conf.set(&rng_seed, {"rng_seed", "seed"}); | ||||
| if (explicit_seed) { | if (explicit_seed) { | ||||
| player->variance = player->M2 / (double)(n_hand); | player->variance = player->M2 / (double)(n_hand); | ||||
| } | } | ||||
| infinite_decks_card_number_for_arranged_ones = 0; | |||||
| // reset this index | |||||
| i_arranged_cards = 0; | |||||
| n_hand++; | n_hand++; | ||||
| // clear dealer's hand | // clear dealer's hand | ||||
| nextAction = DealerAction::AskForBets; | nextAction = DealerAction::AskForBets; | ||||
| } | } | ||||
| player->info(Info::NewHand, n_hand); | |||||
| player->info(Info::NewHand, player->bankroll); | |||||
| return; | return; | ||||
| break; | break; | ||||
| unsigned int tag = 0; | unsigned int tag = 0; | ||||
| if (n_decks == -1) { | if (n_decks == -1) { | ||||
| // TODO: arranged cards | |||||
| tag = fiftyTwoCards(rng); | |||||
| if (n_arranged_cards != 0 && i_arranged_cards < n_arranged_cards) { | |||||
| // negative (or invalid) values are placeholder for random cards | |||||
| if ((tag = arranged_cards[i_arranged_cards++]) < 0 || tag > 51) { | |||||
| tag = fiftyTwoCards(rng); | |||||
| } | |||||
| } else { | |||||
| tag = fiftyTwoCards(rng); | |||||
| } | |||||
| } else { | } else { | ||||
| // TODO: shoes | // TODO: shoes |
| bool shuffle_every_hand = false; | bool shuffle_every_hand = false; | ||||
| std::vector<unsigned int> arranged_cards; | std::vector<unsigned int> arranged_cards; | ||||
| unsigned int n_arranged_cards = 0; // just to prevent calling size() each time we draw a card | |||||
| unsigned int i_arranged_cards = 0; | |||||
| unsigned int max_bet = 0; | unsigned int max_bet = 0; | ||||
| unsigned int number_of_burnt_cards = 0; | unsigned int number_of_burnt_cards = 0; | ||||
| unsigned int infinite_decks_card_number_for_arranged_ones = 0; | |||||
| unsigned int hands_per_char = false; | unsigned int hands_per_char = false; | ||||
| double error_standard_deviations; | double error_standard_deviations; | ||||
| bool show_help = false; | |||||
| bool show_version = false; | |||||
| private: | private: | ||||
| std::map<std::string, std::string> data; | std::map<std::string, std::string> data; | ||||
| std::string dealer; | std::string dealer; | ||||
| std::string player; | std::string player; | ||||
| bool show_help = false; | |||||
| bool show_version = false; | |||||
| // bool show_bar = false; | // bool show_bar = false; | ||||
| // bool bar_already_alloced = false; | // bool bar_already_alloced = false; | ||||
| Configuration conf(argc, argv); | Configuration conf(argc, argv); | ||||
| if (conf.show_version) { | |||||
| Libreblackjack::shortversion(); | |||||
| Libreblackjack::copyright(); | |||||
| } | |||||
| if (conf.show_help) { | |||||
| Libreblackjack::help(argv[0]); | |||||
| } | |||||
| if (conf.show_version || conf.show_help) { | |||||
| return 0; | |||||
| } | |||||
| if (conf.getDealerName() == "blackjack") { | if (conf.getDealerName() == "blackjack") { | ||||
| dealer = new Blackjack(conf); | dealer = new Blackjack(conf); | ||||
| } else { | } else { |
| case Info::NewHand: | case Info::NewHand: | ||||
| // s = "new_hand"; | // s = "new_hand"; | ||||
| std::cout << std::endl; | std::cout << std::endl; | ||||
| s = "Starting new hand #" + std::to_string(intData); | |||||
| s = "Starting new hand, bankroll " + std::to_string(intData); | |||||
| dealerHand.cards.clear(); | dealerHand.cards.clear(); | ||||
| break; | break; | ||||
| // s = "card_dealer_hole"; | // s = "card_dealer_hole"; | ||||
| s = "Dealer's hole card was " + card[intData].utf8(); | s = "Dealer's hole card was " + card[intData].utf8(); | ||||
| *(++(dealerHand.cards.begin())) = intData; | *(++(dealerHand.cards.begin())) = intData; | ||||
| renderTable(); | |||||
| // renderTable(); | |||||
| break; | break; | ||||
| case Info::DealerBlackjack: | case Info::DealerBlackjack: | ||||
| // s = "dealer_blackjack"; | // s = "dealer_blackjack"; | ||||
| s = "Dealer has Blackjack"; | s = "Dealer has Blackjack"; | ||||
| // TODO: draw dealer's hand | |||||
| renderTable(); | |||||
| break; | break; | ||||
| case Info::PlayerWinsInsurance: | case Info::PlayerWinsInsurance: | ||||
| // s = "player_wins_insurance"; | // s = "player_wins_insurance"; | ||||
| s = "Player wins insurance"; | s = "Player wins insurance"; | ||||
| renderTable(); | |||||
| break; | break; | ||||
| case Info::PlayerBlackjackAlso: | case Info::PlayerBlackjackAlso: | ||||
| unsigned int i = 0; | unsigned int i = 0; | ||||
| for (auto it : hand->cards) { | for (auto it : hand->cards) { | ||||
| if (it > 0) { | |||||
| if (it >= 0) { | |||||
| std::cout << "|" << card[it].getNumberASCII() << ((card[it].number != 10)?" ":"") << " | "; | std::cout << "|" << card[it].getNumberASCII() << ((card[it].number != 10)?" ":"") << " | "; | ||||
| } else { | } else { | ||||
| std::cout << "|#####| "; | std::cout << "|#####| "; | ||||
| i = 0; | i = 0; | ||||
| for (auto it : hand->cards) { | for (auto it : hand->cards) { | ||||
| if (it > 0) { | |||||
| if (it >= 0) { | |||||
| std::cout << "| | "; | std::cout << "| | "; | ||||
| } else { | } else { | ||||
| std::cout << "|#####| "; | std::cout << "|#####| "; | ||||
| i = 0; | i = 0; | ||||
| for (auto it : hand->cards) { | for (auto it : hand->cards) { | ||||
| if (it > 0) { | |||||
| if (it >= 0) { | |||||
| std::cout << "| " << card[it].getSuitUTF8() << " | "; | std::cout << "| " << card[it].getSuitUTF8() << " | "; | ||||
| } else { | } else { | ||||
| std::cout << "|#####| "; | std::cout << "|#####| "; | ||||
| i = 0; | i = 0; | ||||
| for (auto it : hand->cards) { | for (auto it : hand->cards) { | ||||
| if (it > 0) { | |||||
| if (it >= 0) { | |||||
| std::cout << "| | "; | std::cout << "| | "; | ||||
| } else { | } else { | ||||
| std::cout << "|#####| "; | std::cout << "|#####| "; | ||||
| i = 0; | i = 0; | ||||
| for (auto it : hand->cards) { | for (auto it : hand->cards) { | ||||
| if (it > 0) { | |||||
| if (it >= 0) { | |||||
| std::cout << "|___" << ((card[it].number != 10)?"_":"") << card[it].getNumberASCII() << "| "; | std::cout << "|___" << ((card[it].number != 10)?"_":"") << card[it].getNumberASCII() << "| "; | ||||
| } else { | } else { | ||||
| std::cout << "|#####| "; | std::cout << "|#####| "; |
| /*------------ -------------- -------- --- ----- --- -- - - | |||||
| * Libre Blackjack - version reporting | |||||
| * | |||||
| * 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/>. | |||||
| *------------------- ------------ ---- -------- -- - - - | |||||
| */ | |||||
| #include <iostream> | |||||
| #include "version-vcs.h" | |||||
| #define ENGINE "a free & open blackjack engine\n" | |||||
| namespace Libreblackjack { | |||||
| void shortversion(void) { | |||||
| std::cout << "LibreBlackjack "; | |||||
| #ifdef LIBREBLACKJACK_VCS_BRANCH | |||||
| std::cout << LIBREBLACKJACK_VCS_VERSION << ((LIBREBLACKJACK_VCS_CLEAN == 0) ? "" : "+Δ") << ((LIBREBLACKJACK_VCS_BRANCH != "master") ? LIBREBLACKJACK_VCS_BRANCH : "") << std::endl; | |||||
| #else | |||||
| std::cout << PACKAGE_VERSION << std::endl; | |||||
| #endif | |||||
| // std::cout << (_(ENGINE)) << std::endl; | |||||
| std::cout << ENGINE << std::endl; | |||||
| return; | |||||
| } | |||||
| void help(const char *program_name) { | |||||
| std::cout << "Usage: " << program_name << "[options] [path_to_conf_file]" << std::endl; | |||||
| std::cout << ENGINE << std::endl; | |||||
| std::cout << std::endl; | |||||
| std::cout << "If no configuration file is given, a file named blackjack.conf" << std::endl; | |||||
| std::cout << "in the current directory is used, provided it exists." << std::endl; | |||||
| std::cout << "See the full documentation for the available options and the default values." << std::endl; | |||||
| std::cout << std::endl; | |||||
| std::cout << " -h, --hands=N set the number of hands to play before quiting" << std::endl; | |||||
| std::cout << " -d, --decks=N set the number of decks to use" << std::endl; | |||||
| std::cout << " -f, --flatbet do not ask for the bet before each hand, use a unit flat bet" << std::endl; | |||||
| std::cout << " -i, --internal use the internal player to play against the dealer (not interactive)" << std::endl; | |||||
| std::cout << std::endl; | |||||
| std::cout << " -h, --help display this help and exit" << std::endl; | |||||
| std::cout << " -v --version output version information and exit" << std::endl; | |||||
| return; | |||||
| } | |||||
| void copyright(void) { | |||||
| std::cout << "copyright (c) " << 2016 << "--" << 2020 << " jeremy theler." << std::endl; | |||||
| std::cout << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" << std::endl; | |||||
| std::cout << "This is free software: you are free to change and redistribute it." << std::endl; | |||||
| std::cout << "There is NO WARRANTY, to the extent permitted by law." << std::endl << std::endl; | |||||
| return; | |||||
| } | |||||
| } |