| flat_bet = 1 | |||||
| no_insurance = true | |||||
| delay = 0 | |||||
| ; flat_bet = 1 | |||||
| ; no_insurance = true | |||||
| ; delay = 0 | |||||
| ; arranged_cards = 2,1,11 | ; arranged_cards = 2,1,11 | ||||
| ; rng_seed = 1 | ; rng_seed = 1 |
| # | # | ||||
| import sys | import sys | ||||
| import fileinput | |||||
| max_bet = 32 | max_bet = 32 | ||||
| debug = False | |||||
| n_player_cards = 0 | n_player_cards = 0 | ||||
| count = 0 | count = 0 | ||||
| bet = 1 | bet = 1 | ||||
| import fileinput | |||||
| for linenl in fileinput.input(): | for linenl in fileinput.input(): | ||||
| line = linenl.rstrip() | line = linenl.rstrip() | ||||
| #print("<- %s" % line, file = sys.stderr) | |||||
| if debug: | |||||
| print("<- %s" % line, file = sys.stderr) | |||||
| if line == "bye": | if line == "bye": | ||||
| sys.exit(0) | sys.exit(0) | ||||
| elif line == "insurance?": | elif line == "insurance?": | ||||
| print("no", flush = True) | print("no", flush = True) | ||||
| if debug: | |||||
| print("<- no", file = sys.stderr) | |||||
| elif line == "bet?": | elif line == "bet?": | ||||
| #if count <= 1: | |||||
| #bet = 1 | |||||
| #elif bet < max_bet: | |||||
| #bet *= 2 | |||||
| #print(bet, flush = True) | |||||
| print("1", flush = True) | |||||
| if count <= 1: | |||||
| bet = 1 | |||||
| elif bet < max_bet: | |||||
| bet *= 2 | |||||
| print(bet, flush = True) | |||||
| #print("1", flush = True) | |||||
| elif line[:15] == "player_split_ok": | elif line[:15] == "player_split_ok": | ||||
| n_player_cards = 1 | n_player_cards = 1 | ||||
| if (len(tokens) > 1): | if (len(tokens) > 1): | ||||
| card = tokens[1][0] | card = tokens[1][0] | ||||
| else: | else: | ||||
| card = "" | |||||
| card = "" # the dealer's hole card | |||||
| # count aces and fives | # count aces and fives | ||||
| if card == "A": | if card == "A": | ||||
| count -= 1 | count -= 1 | ||||
| if debug: | |||||
| print("ACE, count is %d" % count, file = sys.stderr) | |||||
| elif card == "5": | elif card == "5": | ||||
| count += 1 | count += 1 | ||||
| if debug: | |||||
| print("FIVE, count is %d" % count, file = sys.stderr) | |||||
| if line[:11] == "card_player": | if line[:11] == "card_player": | ||||
| n_player_cards += 1 | n_player_cards += 1 | ||||
| dealer = abs(int(tokens[2])) | dealer = abs(int(tokens[2])) | ||||
| action = "quit" | action = "quit" | ||||
| #print("player_cards %d" % n_player_cards, file = sys.stderr) | |||||
| #print("card_player_first %s" % card_player_first, file = sys.stderr) | |||||
| #print("card_player_second %s" % card_player_second, file = sys.stderr) | |||||
| if n_player_cards == 2 and card_player_first == card_player_second and \ | if n_player_cards == 2 and card_player_first == card_player_second and \ | ||||
| ((card_player_first == "8" or card_player_first == "A") or \ | ((card_player_first == "8" or card_player_first == "A") or \ | ||||
| (dealer < 7 and \ | (dealer < 7 and \ | ||||
| action = "hit" # hit soft 16 to 18 against 7 to A | action = "hit" # hit soft 16 to 18 against 7 to A | ||||
| else: | else: | ||||
| action = "stand" # stand with soft 19 or more | action = "stand" # stand with soft 19 or more | ||||
| print(action, flush = True) | print(action, flush = True) | ||||
| #print("-> %s" % action, file = sys.stderr) | |||||
| if debug: | |||||
| print("-> %s" % action, file = sys.stderr) | |||||
| elif line == "invalid_command": | elif line == "invalid_command": | ||||
| print("I sent an invalid command!", file = sys.stderr) | print("I sent an invalid command!", file = sys.stderr) |
| if test ! -e fifo; then | |||||
| mkfifo fifo | |||||
| # if test ! -e fifo; then | |||||
| # mkfifo fifo | |||||
| # fi | |||||
| # blackjack --decks=4 --player=stdio --verbose=true -n2e4 < fifo | ./ace-five.py > fifo | |||||
| if test ! -e A; then | |||||
| mkfifo A | |||||
| mkfifo B | |||||
| fi | fi | ||||
| blackjack --player=stdio --verbose=true -n10000 < fifo | ./ace-five.py > fifo | |||||
| python3 ace-five.py < A > B & | |||||
| blackjack --decks=4 --player=stdio --verbose=true -n1e6 > A < B |
| rng = std::mt19937(rng_seed); | rng = std::mt19937(rng_seed); | ||||
| } | } | ||||
| // initialize shoe and perform initial shuffle | |||||
| if (n_decks > 0) { | if (n_decks > 0) { | ||||
| shoe.resize(52*n_decks); | |||||
| shoe.reserve(52*n_decks); | |||||
| for (unsigned int deck = 0; deck < n_decks; deck++) { | for (unsigned int deck = 0; deck < n_decks; deck++) { | ||||
| for (unsigned int c = 1; c <= 52; c++) { | |||||
| shoe.push_back(c); | |||||
| for (unsigned int tag = 1; tag <= 52; tag++) { | |||||
| shoe.push_back(tag); | |||||
| } | } | ||||
| } | } | ||||
| shuffle(); | |||||
| cutCardPos = static_cast<int>(penetration * 52 * n_decks); | |||||
| } | } | ||||
| } | } | ||||
| bool playerBlackjack = false; | bool playerBlackjack = false; | ||||
| // let's start by assuming the player does not need to do anything | // let's start by assuming the player does not need to do anything | ||||
| player->actionRequired = Libreblackjack::PlayerActionRequired::None; | player->actionRequired = Libreblackjack::PlayerActionRequired::None; | ||||
| // std::list<PlayerHand>::iterator playerHand; | |||||
| switch(nextAction) { | switch(nextAction) { | ||||
| // ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
| if (lastPass) { | if (lastPass) { | ||||
| info(Libreblackjack::Info::Shuffle); | info(Libreblackjack::Info::Shuffle); | ||||
| // shuffle the cards | |||||
| // shuffle the shoe | |||||
| shuffle(); | shuffle(); | ||||
| // burn as many cards as asked | // burn as many cards as asked | ||||
| for (unsigned int i = 0; i < number_of_burnt_cards; i++) { | |||||
| drawCard(); | |||||
| } | |||||
| pos += number_of_burnt_cards; | |||||
| lastPass = false; | lastPass = false; | ||||
| } | } | ||||
| // we just pick a random card when we need to deal and that's it | // we just pick a random card when we need to deal and that's it | ||||
| if (n_decks > 0) { | if (n_decks > 0) { | ||||
| std::shuffle(shoe.begin(), shoe.end(), rng); | std::shuffle(shoe.begin(), shoe.end(), rng); | ||||
| pos = 0; | |||||
| n_shuffles++; | n_shuffles++; | ||||
| } | } | ||||
| unsigned int tag = 0; | unsigned int tag = 0; | ||||
| if (n_decks == 0) { | if (n_decks == 0) { | ||||
| if (n_arranged_cards != 0 && i_arranged_cards < n_arranged_cards) { | if (n_arranged_cards != 0 && i_arranged_cards < n_arranged_cards) { | ||||
| // negative (or invalid) values are placeholder for random cards | // negative (or invalid) values are placeholder for random cards | ||||
| if ((tag = arranged_cards[i_arranged_cards++]) <= 0 || tag > 52) { | if ((tag = arranged_cards[i_arranged_cards++]) <= 0 || tag > 52) { | ||||
| } | } | ||||
| } else { | } else { | ||||
| lastPass = (pos >= cutCardPos) || shuffle_every_hand; | |||||
| if (pos >= 52 * n_decks) { | if (pos >= 52 * n_decks) { | ||||
| return 0; | |||||
| shuffle(); | |||||
| } | } | ||||
| // lastPass = pos >= cutCardPos || shuffle_every_hand; | |||||
| tag = shoe[pos++]; | tag = shoe[pos++]; | ||||
| } | } | ||||
| std::mt19937 rng; | std::mt19937 rng; | ||||
| std::uniform_int_distribution<unsigned int> fiftyTwoCards; | std::uniform_int_distribution<unsigned int> fiftyTwoCards; | ||||
| bool lastPass = false; | |||||
| std::vector<unsigned int> shoe; | std::vector<unsigned int> shoe; | ||||
| size_t pos; | |||||
| size_t pos = 0; | |||||
| size_t cutCardPos = 0; | |||||
| bool lastPass = false; | |||||
| unsigned int upCard; | unsigned int upCard; | ||||
| unsigned int holeCard; | unsigned int holeCard; |
| case Libreblackjack::Info::Shuffle: | case Libreblackjack::Info::Shuffle: | ||||
| // TODO: ask the user to cut | // TODO: ask the user to cut | ||||
| s = "shuffle"; | |||||
| s = "shuffling"; | |||||
| break; | break; | ||||
| case Libreblackjack::Info::CardPlayer: | case Libreblackjack::Info::CardPlayer: |