| @@ -1,6 +1,6 @@ | |||
| flat_bet = 1 | |||
| no_insurance = true | |||
| delay = 0 | |||
| ; flat_bet = 1 | |||
| ; no_insurance = true | |||
| ; delay = 0 | |||
| ; arranged_cards = 2,1,11 | |||
| ; rng_seed = 1 | |||
| @@ -35,18 +35,20 @@ | |||
| # | |||
| import sys | |||
| import fileinput | |||
| max_bet = 32 | |||
| debug = False | |||
| n_player_cards = 0 | |||
| count = 0 | |||
| bet = 1 | |||
| import fileinput | |||
| for linenl in fileinput.input(): | |||
| line = linenl.rstrip() | |||
| #print("<- %s" % line, file = sys.stderr) | |||
| if debug: | |||
| print("<- %s" % line, file = sys.stderr) | |||
| if line == "bye": | |||
| sys.exit(0) | |||
| @@ -60,14 +62,16 @@ for linenl in fileinput.input(): | |||
| elif line == "insurance?": | |||
| print("no", flush = True) | |||
| if debug: | |||
| print("<- no", file = sys.stderr) | |||
| 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": | |||
| n_player_cards = 1 | |||
| @@ -77,12 +81,17 @@ for linenl in fileinput.input(): | |||
| if (len(tokens) > 1): | |||
| card = tokens[1][0] | |||
| else: | |||
| card = "" | |||
| card = "" # the dealer's hole card | |||
| # count aces and fives | |||
| if card == "A": | |||
| count -= 1 | |||
| if debug: | |||
| print("ACE, count is %d" % count, file = sys.stderr) | |||
| elif card == "5": | |||
| count += 1 | |||
| if debug: | |||
| print("FIVE, count is %d" % count, file = sys.stderr) | |||
| if line[:11] == "card_player": | |||
| n_player_cards += 1 | |||
| @@ -97,10 +106,6 @@ for linenl in fileinput.input(): | |||
| dealer = abs(int(tokens[2])) | |||
| 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 \ | |||
| ((card_player_first == "8" or card_player_first == "A") or \ | |||
| (dealer < 7 and \ | |||
| @@ -155,8 +160,10 @@ for linenl in fileinput.input(): | |||
| action = "hit" # hit soft 16 to 18 against 7 to A | |||
| else: | |||
| action = "stand" # stand with soft 19 or more | |||
| print(action, flush = True) | |||
| #print("-> %s" % action, file = sys.stderr) | |||
| if debug: | |||
| print("-> %s" % action, file = sys.stderr) | |||
| elif line == "invalid_command": | |||
| print("I sent an invalid command!", file = sys.stderr) | |||
| @@ -1,4 +1,11 @@ | |||
| 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 | |||
| 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 | |||
| @@ -74,13 +74,16 @@ Blackjack::Blackjack(Configuration &conf) : rng(dev_random()), fiftyTwoCards(1, | |||
| rng = std::mt19937(rng_seed); | |||
| } | |||
| // initialize shoe and perform initial shuffle | |||
| 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 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); | |||
| } | |||
| } | |||
| @@ -93,8 +96,6 @@ void Blackjack::deal(void) { | |||
| bool playerBlackjack = false; | |||
| // let's start by assuming the player does not need to do anything | |||
| player->actionRequired = Libreblackjack::PlayerActionRequired::None; | |||
| // std::list<PlayerHand>::iterator playerHand; | |||
| switch(nextAction) { | |||
| // ------------------------------------------------------------------------- | |||
| @@ -131,13 +132,11 @@ void Blackjack::deal(void) { | |||
| if (lastPass) { | |||
| info(Libreblackjack::Info::Shuffle); | |||
| // shuffle the cards | |||
| // shuffle the shoe | |||
| shuffle(); | |||
| // 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; | |||
| } | |||
| @@ -753,6 +752,7 @@ void Blackjack::shuffle() { | |||
| // we just pick a random card when we need to deal and that's it | |||
| if (n_decks > 0) { | |||
| std::shuffle(shoe.begin(), shoe.end(), rng); | |||
| pos = 0; | |||
| n_shuffles++; | |||
| } | |||
| @@ -765,6 +765,7 @@ unsigned int Blackjack::drawCard(Hand *hand) { | |||
| unsigned int tag = 0; | |||
| if (n_decks == 0) { | |||
| 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 > 52) { | |||
| @@ -775,11 +776,12 @@ unsigned int Blackjack::drawCard(Hand *hand) { | |||
| } | |||
| } else { | |||
| lastPass = (pos >= cutCardPos) || shuffle_every_hand; | |||
| if (pos >= 52 * n_decks) { | |||
| return 0; | |||
| shuffle(); | |||
| } | |||
| // lastPass = pos >= cutCardPos || shuffle_every_hand; | |||
| tag = shoe[pos++]; | |||
| } | |||
| @@ -44,9 +44,10 @@ class Blackjack : public Dealer { | |||
| std::mt19937 rng; | |||
| std::uniform_int_distribution<unsigned int> fiftyTwoCards; | |||
| bool lastPass = false; | |||
| std::vector<unsigned int> shoe; | |||
| size_t pos; | |||
| size_t pos = 0; | |||
| size_t cutCardPos = 0; | |||
| bool lastPass = false; | |||
| unsigned int upCard; | |||
| unsigned int holeCard; | |||
| @@ -77,7 +77,7 @@ void StdInOut::info(Libreblackjack::Info msg, int p1, int p2) { | |||
| case Libreblackjack::Info::Shuffle: | |||
| // TODO: ask the user to cut | |||
| s = "shuffle"; | |||
| s = "shuffling"; | |||
| break; | |||
| case Libreblackjack::Info::CardPlayer: | |||