예제 #1
0
def run_sims(num_hands, params, num_decks=1, print_results=True, file=None):
    dealer_hits_on_soft_17 = params['Dealer Hits on Soft 17']
    double_after_split = params['Double Allowed After Split']
    surrender_allowed = params['Surrender Allowed']
    double_allowed = params['Double Allowed']
    blackjack_return = params['Blackjack Payout']

    total_return = 0
    total_wagers = 0
    total_squared = 0

    shoe = Shoe(num_decks)

    for i in range(num_hands):
        player_hand = Hand(shoe.get_random_card(), shoe.get_random_card())
        dealer_hand = Hand(shoe.get_random_card())
        dealer_hand.dealer_hit(shoe, replace=True, hit_on_soft_17=False)

        new_wagers, new_winnings = analyze_hand(player_hand, dealer_hand, 1,
                                                shoe, blackjack_return,
                                                dealer_hits_on_soft_17,
                                                double_after_split,
                                                surrender_allowed,
                                                double_allowed)
        total_wagers += new_wagers
        total_return += new_winnings
        total_squared += new_winnings * new_winnings

    if print_results:
        print_values(total_wagers, total_return, num_hands, total_squared,
                     params, file)
    return get_values(total_wagers, total_return, num_hands, total_squared)
예제 #2
0
def calc_hard_strategy(decks):

    shoe = Shoe(decks)
    rows = 10
    cols = 10
    bs_hard = [ [0] * cols for _ in range(rows)]

    #Hard table
    for row in range(0, rows):
        for col in range(0, cols):
            d_rank = Rank(col+1)

            if d_rank == 10:
                d_rank = Rank.Ace

            # player values 8 - 11
            if row < 4:
                p1 = Card(Rank.Six, Suit.Spade)
                p2 = Card(Rank(row+1), Suit.Spade)
            # Player values 12 - 18
            elif row >= 4:
                p1 = Card(Rank.Ten, Suit.Spade)
                p2 = Card(Rank(row-3), Suit.Spade)

            upcard = Card(d_rank, Suit.Spade)

            p_hand = Hand([p1,p2])

            game = Game(p_hand, upcard, shoe)

            optimal = optimal_action(game)
            bs_hard[row][col] = optimal
            shoe.reset_shoe()

    print(DataFrame(bs_hard))
예제 #3
0
 def __init__(self):
     self.DECKS = 8
     self.shoe = Shoe(8)
     self.p1 = Player("Complete_Strategy", 10000)
     self.p2 = Player("Basic_Strategy", 10000)
     self.dealer = Dealer(self.shoe)
     self.sims = 0
예제 #4
0
def calc_split_strategy(decks):
    # Split Table
    shoe = Shoe(8)
    rows = 9
    cols = 10
    bs_split = [ [0] * cols for _ in range(rows)]

    for row in range(0, rows):
        for col in range(0, cols):
            assert(shoe.cards_in_shoe == 52*shoe.DECKS)
            d_rank = Rank(col+1)
            p_rank = Rank(row+1)

            if d_rank == 10:
                d_rank = Rank.Ace
            if p_rank == 10:
                p_rank = Rank.Ace

            p1 = Card(p_rank, Suit.Spade)
            p2 = Card(p_rank, Suit.Spade)
            p_hand = Hand([p1,p2])
            upcard = Card(d_rank, Suit.Spade)

            game = Game(p_hand, upcard, shoe)

            optimal = optimal_action(game)
            shoe.reset_shoe()
            bs_split[row][col] = optimal

    print(DataFrame(bs_split))
예제 #5
0
 def __init__(self, name = 'Bob the dealer', money = 1000000, delay = 1, verbose = True):
     super().__init__(name, money)
     self._playingPlayers = []
     self._playersWithInsurance = []
     self._shoe = Shoe()
     self.delay = delay
     self.isVerbose = verbose
예제 #6
0
def calc_soft_strategy(decks):

    shoe = Shoe(decks)

    rows = 7 # S13 - S19
    cols = 10
    bs_soft = [ [0] * cols for _ in range(rows)]

    #Soft Table
    for row in range(0, rows):
        for col in range(0, cols):
            assert(shoe.cards_in_shoe == 52*shoe.DECKS)
            d_rank = Rank(col+1) # dealer's up card rank

            if d_rank == 10:
                d_rank = Rank.Ace

            upcard = Card(d_rank, Suit.Spade)
            p1 = Card(Rank.Ace, Suit.Spade)
            p2 = Card(Rank(row+1), Suit.Spade)
            p_hand = Hand([p1,p2])

            game = Game(p_hand, upcard, shoe)
            optimal = optimal_action(game)
            bs_soft[row][col] = optimal
            shoe.reset_shoe()

    print(DataFrame(bs_soft))
예제 #7
0
class Sim():
    def __init__(self):
        self.DECKS = 8
        self.shoe = Shoe(8)
        self.p1 = Player("Complete_Strategy", 10000)
        self.p2 = Player("Basic_Strategy", 10000)
        self.dealer = Dealer(self.shoe)
        self.sims = 0

    def run(self):
        for x in range(10000):

            print(f"*** Hand {self.sims+1}***")
            self.sims += 1

            print(self.p1)
            print(self.p2)

            self.p1.bet()
            self.p2.bet()

            self.deal_cards()

            while not self.p1.is_done() or not self.p2.is_done():
                card = Card(Rank(random.randint(Rank.Ace, Rank.King)),
                            Suit.Spade)
                action_b = strategy.infinite_basic_action(
                    self.p1.hand, self.dealer)
                action_c = strategy.infinite_complete_action(
                    self.p2.hand, self.dealer)
                self.p1.process_action(action_b, card)
                self.p2.process_action(action_c, card)

            self.dealer.playout_hand()

            self.p1.payout(self.dealer.hand)
            self.p2.payout(self.dealer.hand)

            self.dealer.reset()
            self.shoe.reset_shoe(
            )  # why am I reseting shoe everytime yet still calculating deal probs every hand?

            print("\n")

    def deal_cards(self):
        players_hand = self.random_hand(2)
        self.p1.add_hand(players_hand)
        self.p2.add_hand(deepcopy(players_hand))
        self.dealer.deal_card(
            Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade))

    def random_hand(self, size):
        cards = []
        for _ in range(size):
            card = Card(Rank(random.randint(Rank.Ace, Rank.King)), Suit.Spade)
            cards.append(card)
            self.shoe.draw(card)

        return Hand(cards)
예제 #8
0
 def __init__(self, name, money):
     super().__init__(name, money)
     self.shoe = Shoe()
     self.players = []
     # Holds bets before hands have been dealt
     # We could make this a dictionary with the player's name as the key,
     # but that assumes the player names are unique. Better solution would
     # probably be to set bets on the Player object
     self.playerBets = []
예제 #9
0
 def test_deal(self):
     shoe = Shoe(1)
     self.assertEqual(len(shoe._cards), 52)
     card1 = shoe.draw()
     card2 = shoe.draw()
     self.assertEqual(len(shoe._cards), 50)
     self.assertNotIn(card1, shoe._cards)
     self.assertNotIn(card2, shoe._cards)
     shoe.receive([card1, card2])
     self.assertEqual(len(shoe._cards), 52)
예제 #10
0
파일: game.py 프로젝트: jackarendt/casino
  def __init__(self, agents, print_desc=False):
    # A typical shoe has 6 decks and reshuffles when roughly 5/6 decks are used.
    self.shoe = Shoe(6, 0.8)
    self.dealer = DealerActor()
    self.agents = []
    self.player_count = len(agents) + 1
    self.print_desc = print_desc

    # Add the agents.
    self.agents = agents
예제 #11
0
    def testStandStrategy(self):
        print("")
        runs = GameParser.parse('../Games/strategy-stand.csv')
        game = Game(Strategy(), { 'debug': True })

        for run in runs:
            print("")
            print(run)
            shoe = Shoe(run['cards'])
            self.assertEquals(game.play(shoe), run['result'])
            self.assertTrue(shoe.isEmpty())
예제 #12
0
 def __init__(self):
     self.chairs = []
     self.shoe = Shoe(6)
     self.dealer = Dealer()
     self.insurance = True
     self.blackjack_payout = 1.5
     self.shoe_size = 6
예제 #13
0
def test_probability_class():
    shoe = Shoe(8)
    prob = Probability(shoe)

    hand = Hand([c9, c4])
    dealer = Hand([c6])

    prob1 = prob.probability_of_hand(hand, 0)
    exp1 = 0.0059314179796107515
    prob2 = prob.probability_of_card(c0)
    exp2 = 0.07692307692307693

    if prob1 == exp1:
        print("SUCCESS: probability class return correct probability")
    else:
        print(
            f"FAIL: probability return '{prob1}' probability expected '{exp1}'"
        )

    if prob2 == exp2:
        print("SUCCESS: probability class return correct probability")
    else:
        print(
            f"FAIL: probability return '{prob2}' probability expected '{exp2}'"
        )
예제 #14
0
class Dealer(Player):
    def __init__(self):
        super().__init__()
        self._shoe = Shoe(1)

    def hit(self, player, facedown=False):
        card = self._shoe.draw()
        card.facedown = facedown
        player.receive(card)

    def collect(self, cards):
        self._shoe.receive(self.dispose() + cards)

    def deal(self, player):
        self.hit(player)
        self.hit(self)
        self.hit(player)
        self.hit(self)
예제 #15
0
def main(path):
    shoe_file = open(path, 'r').readlines()

    matchers = ['heel', 'toe', 'padded']
    matching = [s for s in shoe_file if any(xs in s for xs in matchers)]
    materials = shoe_file[shoe_file.index('Materials\n') + 1]

    #Length is static just for the challenge
    #Can change it to apply to many cases
    if (len(matching) == 3):
        shoe = Shoe(matching[0].strip('-'), matching[1].strip('-'),
                    materials.strip('\n'))
        print(shoe)

    if (len(matching) == 4):
        shoe = Shoe(matching[0].strip('-'), matching[2].strip('-'), materials,
                    matching[1].strip('-').strip('\n'))
        print(shoe)
예제 #16
0
 def switch_all_shoes(self):
     """
     When any table calls this method, give a new, identical shoe to each
     table in the simulation.
     :return:
     """
     shoe = Shoe()
     for table in self.tables:
         if table.has_active_players():
             table._dealer.switch_shoe(deepcopy(shoe))
예제 #17
0
def main(DECKS):

    shoe = Shoe(DECKS)

    while True:

        choice = input("n - new hand, q - quit: ").upper()

        if choice == "Q":
            break
        elif choice == "N":

            p1 = input("Your first card: ").upper()
            du = input("Dealer up card: ").upper()
            p2 = input("Your second card: ").upper()

            h = Hand(p1, p2, du)
            shoe.remove(p1)
            shoe.remove(p2)
            shoe.remove(du)
            print(h)

            while True:

                choice2 = input("h - hit, p - split, s - stand: ").upper()
                if choice2[0] == "S":
                    break

                elif choice2[0] == "H":
                    choicesplit = choice2.split(" ")
                    try:
                        handindex = int(choicesplit[2])
                    except:
                        handindex = 1

                    h.hit(choicesplit[1], handindex=handindex)
                    shoe.remove(choicesplit[1])
                    print(h)

                elif choice2[0] == "P":

                    choicesplit = choice2.split(" ")
                    try:
                        handindex = int(choicesplit[1])
                    except:
                        handindex = 1

                    h.split(handindex=handindex)
                    print(h)

            print(shoe.count)
예제 #18
0
def main():
    shoes = []
    shoes.append(
        Shoe("Yeezreel RF Size 12", "https://stockx.com/adidas-yeezy-boost-350-v2-yeezreel-reflective?size=12", 350))
    shoes.append(
        Shoe("Yeezreel RF Size 13", "https://stockx.com/adidas-yeezy-boost-350-v2-yeezreel-reflective?size=13", 350))
    shoes.append(Shoe("Yechiel NRF Size 12.5", "https://stockx.com/adidas-yeezy-boost-350-v2-yecheil?size=12.5", 350))

    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36', }

    message = ""
    for shoe in shoes:
        res = requests.get(shoe.url, headers=headers)
        parser = BeautifulSoup(res.text, features="html.parser")
        shoe.price = parser.find('div', attrs={'class': 'sale-value'}).text
        # print("Name: {}\tPrice: {}\n".format(shoe.name, shoe.price))
        message = message + "Name: {}\tPrice: {}\n".format(shoe.name, shoe.price)

    # message = message + "SENT ON AWS"
    return send_sms(message)
예제 #19
0
def informal_hand_test():
    from shoe import Shoe
    s = Shoe()
    h = Hand(10)
    h.isVerbose = True
    print(h)
    c = s.draw()
    c.flip()
    print(c)
    if h.can_hit():
        h.hit(c)
        print(h)
    c = s.draw()
    c.flip()
    print(c)
    if h.can_hit():
        h.hit(c)
        print(h)
    print('Can double:', h.can_double())
    print('Can hit:', h.can_hit())
    print('Can split:', h.can_split())
    c = s.draw()
    c.flip()
    h.double_down(c, h.bet)
    print(h)
    #should be busted now
    try:
        c = s.draw()
        c.flip()
        h.hit(c)
    except RuleError as error:
        print(error)
        print("tried and failed to hit a busted hand.")
예제 #20
0
def main():
    decks_of_cards = 6
    shoe = Shoe(decks_of_cards)
    stats = Stats()
    running = True
    while running:
        try:
            game = Game(shoe)
            game.play()
            stats.games.append(game)
        except OutOfCardsException:
            running = False
    stats.print_game_stats()
예제 #21
0
    def __init__(self, log, bankroll, rules_section="Blackjack"):
        # Logger
        self.log = log

        # Required objects
        self.rules = BlackjackRules(log, rules_section)
        self.shoe = Shoe(log, self.rules.get_decks())
        self.event_listener = EventListener(log)

        # Variables
        self.bankroll = bankroll
        self.original_bet = 0
        self.need_to_shuffle = False
        self.split_hand_number = 1
        self.insurance = 0

        # Dealer hand related variables
        self.dealer_hand = []
        self.dealer_bust = False

        # Player hand related variables
        self.player_hand = self.new_player_hand()
        self.split_hands = []
예제 #22
0
    def __init__(self,
                 players,
                 shoe_size=4,
                 debug=False,
                 verbose=False,
                 min_bet=1,
                 max_bet=10,
                 shoe=None):
        if verbose:
            #       print(chr(27) + "[2J")
            print("-" * 80)
        self.verbose = verbose
        self.debug = debug
        self.rules = self.Rules(shoe_size=shoe_size,
                                min_bet=min_bet,
                                max_bet=max_bet)
        self.shoe = Shoe(shoe_size)
        if shoe != None:
            self.shoe = shoe
        self.shoe.shuffle()
        self.state = [self.PlayerState(Dealer())
                      ] + [self.PlayerState(p) for p in players]

        self.done = False
예제 #23
0
 def play_round(self):
     if len(self.shoe.cards) < (self.shoe_size * 13):
         self.shoe = Shoe(self.shoe_size)
         for chair in self.chairs:
             chair.player.count = 0
     decks_left = len(self.shoe.cards) / 52
     self.dealer.hand = Hand()
     for chair in self.chairs:
         chair.hands = []
         chair.active = True
         chair.splits = False
         hand = Hand()
         chair.add_hand({
             'hand': hand,
             'bet': chair.player.make_bet(decks_left),
             'active': True
         })
     self.dealer.deal_round(self)
     if len(self.dealer.hand.cards) > 0:
         if self.dealer.hand.is_dealer_blackjack():
             for chair in self.chairs:
                 if chair.hands[0]['hand'].is_blackjack():
                     chair.player.blackjacks += 1
                     self.dealer.refund_player(chair.hands[0], chair)
                 chair.active = False
         elif self.dealer.showing() is 11:
             if self.insurance:
                 for chair in self.chairs:
                     if chair.player.insurance and chair.active:
                         chair.player.pay_insurance()
             if self.dealer.hand.is_blackjack():
                 for chair in self.chairs:
                     if chair.player.insurance:
                         if self.insurance:
                             self.dealer.refund_player(
                                 chair.hands[0], chair)
                     elif chair.hands[0]['hand'].is_blackjack():
                         chair.player.blackjacks += 1
                         self.dealer.refund_player(chair.hands[0], chair)
                     chair.active = False
             else:
                 self.resolve_chairs()
                 self.dealer.resolve_round(self)
         else:
             self.resolve_chairs()
             self.dealer.resolve_round(self)
예제 #24
0
def dealer_class_test(card, exp):

    shoe = Shoe(8)
    prob = Probability(shoe)
    dealer = Dealer(shoe, prob)
    dealer.deal_card(card)
    probs = dealer.dealer_outcome_probs()

    # make sure probability isn't greated than one
    if round(sum(probs), 2) != 1.0:
        print(f"FAIL: dealer outcome probabilites < or > 1 : '{sum(probs)}'")
        return

    if exp == probs:
        print("\tSUCCESS: dealer outcome probabilites as expected")
    else:
        print("\tFAIL: dealer outcome probabilites NOT as expected")
예제 #25
0
class Dealer(Player):
    def __init__(self,
                 name='Bob the dealer',
                 money=1000000,
                 delay=1,
                 verbose=True):
        super().__init__(name, money)
        self._playingPlayers = []
        self._playersWithInsurance = []
        self._shoe = Shoe()
        self.delay = delay
        self.isVerbose = verbose

    def sit(self, table):
        """Override the player sit method. so that the dealer sits on the right side of the table."""
        self._table = table
        table.add_dealer(self)

    def bet_or_leave(self):
        """
        At the start of each round the player can either bet by entering an amount
        to bet, sit this hand out by entering 0 for a bet, or leave the table by
        entering -1.
        """
        #
        # The dealer will not be in the list of players, so this method will not be
        # called on the dealer.
        #
        pass

    def wants_insurance(self):
        """
        Returns True if the player should buy insurance else return False.

        This procedure is called by the dealer after all players have bet and
        receives their cards and after the dealer has received his cards. It is
        only called if the dealer is showing an ace (the dealer might have blackjack).
        """
        #
        # The dealer will not be in the list of players, so this method will not be
        # called on the dealer.
        #
        pass

    def play(self, hand, dealerShowing):
        """
        Returns the player's action for this hand. The dealer calls this method
        repeatedly for each of the player's hands until all hands are completed.
        Valid return values are listed below. Note that two values are returned:

        choice: one of the plays listeded below
        additionalBet: the amount to "double down" by

        additionalBet is discarded by the caller in all other cases.

        allPlays = {'s': '[S]tand',
                    'h': '[H]it',
                    'd': '[D]ouble down',
                    'p': 's[P]lit',
                    'u': 's[U]rrender'}
        return choice, additionalBet
        """
        if hand.value() < 17:
            choice = 'h'  #hit
        else:
            choice = 's'  #stand
        additionalBet = None
        return choice, additionalBet

    def switch_shoe(self, shoe):
        """
        When we run a simulation instead of a game, we want to make sure that all of
        dealers are using the same shoe and switching shoes at the same time.

        :param shoe: a preshuffled shoe, ready to be delt from.
        :type shoe: Shoe
        :return:
        """
        self._shoe = shoe
        for player in self._table.players:
            player.reset_count()

    def take_bets(self):
        sleep(self.delay)
        if self.isVerbose: print('\n---betting---')
        self._playingPlayers = []
        leavingPlayers = []
        for player in self._table.players:
            #
            # = -1: player is leaving the table
            # =  0: players is sitting this hand out
            # >  0: player is betting this amount
            #
            if self.isVerbose: print(f'\n{player}')
            betAmount = player.bet_or_leave()
            name = player.name.capitalize()
            minimumBet = 1
            if betAmount == -1 or player.money < 1:  # leaving table
                leavingPlayers.append(player)
                if self.isVerbose:
                    print(
                        f"{name} is leaving the table with ${player.money:0.2f}."
                    )
            elif betAmount == 0:
                if self.isVerbose: print(f"{name} is sitting this hand out.")
            elif betAmount > 0 and player.money >= betAmount:
                if betAmount < minimumBet:
                    betAmount = minimumBet
                if betAmount > player.money:
                    betAmount = player.money
                self._playingPlayers.append(player)
                player.rake_out(betAmount)
                self.rake_in(betAmount)
                player.add_hand(Hand(betAmount))
                player.handsPlayed += 1
                player.totalWagers += betAmount
                if self.isVerbose:
                    print(f"{name} is betting ${betAmount:0.2f}.")
            else:
                raise ValueError(
                    f"{player} doesn't have enough money to bet ${betAmount:0.2f}."
                )
            for player in leavingPlayers:
                self._table.leave_table(player)

    def show_card_to_players(self, card):
        """
        Make sure that players who might be counting cards get to see
        every card that is delt, not just the ones in their hands.
        """
        for player in self._playingPlayers:
            player.count(card)

    def deal(self):
        """
        Deal an initial 2 cards to each player and to the dealer.
        """
        #
        # Shuffle the cards if we need to.
        #
        if self._shoe.should_shuffle():
            self._shoe.shuffle()
            for player in self._table.players:
                player.reset_count()
            self._table.shuffling_shoe()
        #
        # Deal cards to each player.
        #
        cardsToDeal = 2
        for _ in range(cardsToDeal):
            for player in self._playingPlayers:
                card = self._shoe.draw().flip()
                player.hands[0].hit(card)
                self.show_card_to_players(card)
        #
        # Deal yourself some cards.
        #
        bet = 0
        self.add_hand(Hand(bet))
        card = self._shoe.draw().flip()

        self.hands[0].hit(card)
        self.show_card_to_players(card)
        self.hands[0].hit(self._shoe.draw().flip())

    def offer_insurance(self):
        if self.isVerbose: print('\n')
        self._playersWithInsurance = []
        if self.hands[0][1].name == 'ace':
            for player in self._playingPlayers:
                if player.wants_insurance():
                    self._playersWithInsurance.append(player)
                    player.insurance = player.hands[0].bet / 2
                    player.timesInsurance += 1

    def play_hands(self):
        """
        Loop through the players and let them choose what they want to do. Then
        process that decision.
        """
        playerOptions = {
            's': self.player_stand,
            'h': self.player_hit,
            'p': self.player_split,
            'd': self.player_double_down,
            'u': self.player_surrender
        }
        if self.isVerbose: print('\n---players are playing---')
        dealerShowing = self.hands[0][1]
        for player in self._playingPlayers:
            for hand in player.hands:
                if hand.isBlackJack:
                    if self.isVerbose:
                        print(f"{player.name} has Blackjack! {hand}.")
                while hand.can_hit():
                    sleep(self.delay)
                    playerDecision, additionalBet = player.play(
                        hand, dealerShowing)
                    if playerDecision.lower() in playerOptions:
                        which_option = playerOptions[playerDecision.lower()]
                        which_option(player, hand, additionalBet)
                    else:
                        if self.isVerbose:
                            print(
                                f"I'm sorry, I don't know what '{playerDecision}' means."
                            )

    def player_stand(self, player, hand, *args):
        hand.stand()
        if self.isVerbose: print(f"{player.name} stands with {hand}.")

    def player_hit(self, player, hand, *args):
        card = self._shoe.draw().flip()
        self.show_card_to_players(card)
        hand.hit(card)
        if self.isVerbose:
            print(f"{player.name} hit and received a {card} {hand}.")
        player.timesHit += 1

    def player_split(self, player, hand, *args):
        if hand.can_split() and player.money >= hand.bet:
            self.rake_in(player.rake_out(hand.bet))
            newHand = Hand(hand.bet)
            newHand.hit(hand.split())
            card = self._shoe.draw().flip()
            self.show_card_to_players(card)
            newHand.hit(card)
            player.add_hand(newHand)
            card = self._shoe.draw().flip()
            self.show_card_to_players(card)
            hand.hit(card)
            if self.isVerbose:
                print(
                    f"{player.name} split and now has: \n   {hand}\n   {newHand}"
                )
            player.timesSplit += 1
            player.handsPlayed += 1
            player.totalWagers += hand.bet
        else:
            if self.isVerbose:
                print("Sorry, you can't split this hand (standing instead).")
            self.player_stand(player, hand)

    def player_double_down(self, player, hand, additionalBet):
        if hand.can_double() and is_number(
                additionalBet) and player.money >= additionalBet:
            card = self._shoe.draw().flip()
            self.show_card_to_players(card)
            hand.double_down(card, additionalBet)
            self.rake_in(player.rake_out(additionalBet))
            if self.isVerbose:
                print(
                    f"{player.name} doubled down and received a {card} {hand}."
                )
            player.timesDoubled += 1
            player.totalWagers += additionalBet
        else:
            if self.isVerbose:
                print("Sorry, you can't double this hand (hitting instead).")
            self.player_hit(player, hand)

    def player_surrender(self, player, hand, *args):
        print('Sorry, surrender is not implemented (pick again).')
        player.timesSurrendered += 1

    #TODO Make sure dealer shows hole card to players somewhere for counting.
    def play_own_hand(self):
        if self.isVerbose: print('\n---dealer is playing---')
        playerOptions = {'s': self.player_stand, 'h': self.player_hit}
        hand = self.hands[0]
        dealerShowing = hand[0]
        while hand.can_hit():
            playerDecision, additionalBet = self.play(hand, dealerShowing)
            which_option = playerOptions[playerDecision]
            which_option(self, hand, additionalBet)

    def payout_hands(self):
        if self.isVerbose: print('\n---results---')
        dealerHand = self.hands[0]
        for player in self._playingPlayers:
            sleep(self.delay * 2)
            for hand in player.hands:
                if hand.isBusted:
                    winnings = 0
                    text = 'lost'
                    player.timesBusted += 1
                    player.timesLost += 1
                    player.lastHand = 'lost'
                elif hand.isBlackJack and not dealerHand.isBlackJack:
                    winnings = hand.bet * 2.5
                    text = 'won (Blackjack!)'
                    player.timesWon += 1
                    player.timesBlackjack += 1
                    player.lastHand = 'won'
                elif hand.isBlackJack and dealerHand.isBlackJack:
                    winnings = hand.bet
                    text = 'pushed (blackjack) and lost'
                    player.timesPushed += 1
                    player.timesBlackjack += 1
                    player.lastHand = 'pushed'
                elif not hand.isBlackJack and dealerHand.isBlackJack:
                    winnings = 0
                    text = 'lost'
                    player.timesLost += 1
                    player.lastHand = 'lost'
                elif hand.value() == dealerHand.value():
                    winnings = hand.bet
                    text = 'pushed and lost'
                    player.timesPushed += 1
                    player.lastHand = 'pushed'
                elif dealerHand.isBusted:
                    winnings = hand.bet * 2
                    text = 'won (dealer busted)'
                    player.timesWon += 1
                    player.lastHand = 'won'
                elif hand.value() > dealerHand.value():
                    winnings = hand.bet * 2
                    text = 'won'
                    player.timesWon += 1
                    player.lastHand = 'won'
                elif hand.value() < dealerHand.value():
                    winnings = 0
                    text = 'lost'
                    player.timesLost += 1
                    player.lastHand = 'lost'
                player.rake_in(winnings)
                self.rake_out(winnings)
                winnings = abs(winnings - hand.bet)
                if self.isVerbose:
                    print(f"{player.name} {text} ${winnings:0.2f} on {hand}.")
        #
        # Payout any insurance bets.
        #
        for player in self._playersWithInsurance:
            if dealerHand.isBlackJack:
                winnings = player.insurance * 2
                player.rake_in(winnings)
                self.rake_out(winnings)
                if self.isVerbose:
                    print(
                        f"{player.name} won ${player.insurance:0.2f} on the insurance bet."
                    )
            else:
                if self.isVerbose:
                    print(
                        f"{player.name} lost ${player.insurance:0.2f} on the insurance bet."
                    )
        #
        # Clear the table and get ready for the next round.
        #
        for player in self._playingPlayers:
            player.discard_hands()
            player.insurance = 0
            if player._chips > player.maxMoney:
                player.maxMoney = player._chips
        self.discard_hands()
        if self.isVerbose: print('---results complete---')
예제 #26
0
class Simulation:

	MIN_BET = 15

	#go through the tables in this sequence

	#[a,b] where a is the dealer's face up card and b is the player's paired card
	PAIRED_TABLE = [
		['U' for i in range(11)], #dealer card == 0
		['U', 'P', 'H', 'H', 'H', 'H', 'H', 'H', 'P', 'S', 'S'], #1
		['U', 'P', 'P', 'P', 'H', 'D', 'P', 'P', 'P', 'P', 'S'], #2
		['U', 'P', 'P', 'P', 'H', 'D', 'P', 'P', 'P', 'P', 'S'], #3
		['U', 'P', 'P', 'P', 'H', 'D', 'P', 'P', 'P', 'P', 'S'], #4
		['U', 'P', 'P', 'P', 'P', 'D', 'P', 'P', 'P', 'P', 'S'], #5
		['U', 'P', 'P', 'P', 'P', 'D', 'P', 'P', 'P', 'P', 'S'], #6
		['U', 'P', 'P', 'P', 'H', 'D', 'H', 'P', 'P', 'S', 'S'], #7
		['U', 'P', 'H', 'H', 'H', 'D', 'H', 'H', 'P', 'P', 'S'], #8
		['U', 'P', 'H', 'H', 'H', 'D', 'H', 'H', 'P', 'P', 'S'], #9
		['U', 'P', 'H', 'H', 'H', 'H', 'H', 'H', 'P', 'S', 'S'], #10
	]

	#[a,b] where a is the dealer's face up card and b is the player's non-ace card
	#note: if hitting a card creates an equivalent situation, we need to consider that
	ACE_TABLE = [
		['U' for i in range(11)], #dealer card == 0
		['U', 'U', 'H', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S'], #1
		['U', 'U', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S'], #2
		['U', 'U', 'H', 'H', 'H', 'H', 'D', 'D', 'S', 'S', 'S'], #3
		['U', 'U', 'H', 'H', 'D', 'D', 'D', 'D', 'S', 'S', 'S'], #4
		['U', 'U', 'D', 'D', 'D', 'D', 'D', 'D', 'S', 'S', 'S'], #5
		['U', 'U', 'D', 'D', 'D', 'D', 'D', 'D', 'S', 'S', 'S'], #6
		['U', 'U', 'H', 'H', 'H', 'D', 'H', 'S', 'S', 'S', 'S'], #7
		['U', 'U', 'H', 'H', 'H', 'D', 'H', 'S', 'S', 'S', 'S'], #8
		['U', 'U', 'H', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S'], #9
		['U', 'U', 'H', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S'], #10
	]

	#[a,b] where a is the dealer's face up card and b is the player's hand value
	VALUE_TABLE = [
		['U' for i in range(21)], #dealer card == 0
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S', 'S'], #1
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'D', 'D', 'H', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S'], #2
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'H', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S'], #3
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S'], #4
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S'], #5
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'D', 'D', 'D', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S', 'S'], #6
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'D', 'D', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S', 'S'], #7
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'D', 'D', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S', 'S'], #8
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'D', 'D', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S', 'S'], #9
		['U', 'U', 'U', 'U', 'U', 'H', 'H', 'H', 'H', 'H', 'H', 'D', 'H', 'H', 'H', 'H', 'H', 'S', 'S', 'S', 'S', 'S'], #10
	]



	def __init__(self, num_decks):
		self.shoe = Shoe(num_decks)
		self.balance = 0
		self.lower_balance = 0
		self.playing = True

	def run(self):
		while not self.shoe.is_finished():
			if self.shoe.true_count() < -1:
				self.playing = False
			elif self.shoe.true_count() > 1:
				self.playing = True

			if self.playing: self.balance += self.play()

			#draw a number of cards for info
			for i in range(10):
				self.shoe.draw()
		return self.balance

	def play(self): #play returns amount of money won/lost
		tc = round(self.shoe.true_count())
		bet = max(self.MIN_BET * round((tc + 1)/2), self.MIN_BET)


		dealer_hand = [self.shoe.draw(), self.shoe.draw()]
		player_hand = [self.shoe.draw(), self.shoe.draw()]
		player_games = [] # for splits

		#check for blackjacks
		dbj = self.blackjack(dealer_hand)
		pbj = self.blackjack(player_hand)
		if dbj and pbj: return 0
		if dbj: return -1 * bet
		if pbj: return bet * 3/2

		#run the player hand and stop if there's a loss
		player_result = self.run_player_hand(dealer_hand, player_hand)
		if player_result == 'P':
			#store each hand and metadata as a tuples
			player_games = map(lambda hand: (hand, 'U', 0), self.expand_hands(player_hand))
			#run each hand
			new_player_games = []
			for game in player_games:
				new_player_games.append((game[0], self.run_player_hand(dealer_hand, game[0]), game[2]))
			player_games = new_player_games
		else:
			player_games = [(player_hand, player_result, 0)]

		#split the busted games and nonbusted games
		bust_games = []
		nonbust_games = []
		for game in player_games:
			if game[1] == 'DB':
				game = (game[0], game[1], -2 * bet)
				bust_games.append(game)
			elif game[1] == 'B':
				game = (game[0], game[1], -1 * bet)
				bust_games.append(game)
			else:
				nonbust_games.append(game)

		#run the dealer hand
		dealer_result = self.run_dealer_hand(dealer_hand)
		#print("Dealer hand: ", dealer_hand)

		#compare against each player hand
		new_nonbust_games = []
		for game in nonbust_games:
			gain = self.hand_result(dealer_result, dealer_hand, game[1], game[0]) * bet
			if game[1] == 'DS': gain *= 2
			new_nonbust_games.append((game[0], game[1], gain))
		nonbust_games = new_nonbust_games

		#cumulate results
		sum = 0
		for game in nonbust_games + bust_games:
			#print("Player hand: ", game[0], "Gain: ", game[2])
			sum += game[2]

		return sum
		

	def blackjack(self, hand):
		if 1 in hand and 10 in hand: return True
		return False


	#returns a list of non-splittable hands, assuming hand is already splittable and its 2 cards
	def expand_hands(self, player_hand):
		if player_hand[0] != player_hand[1]:
			return [player_hand]
		return self.expand_hands([player_hand[0], self.shoe.draw()]) + self.expand_hands([player_hand[0], self.shoe.draw()])

	def hand_result(self, dealer_result, dealer_hand, player_result, player_hand):
		#we'll need these more than once
		soft_value = self.soft_value(player_hand)
		dealer_soft_value = self.soft_value(dealer_hand)
		#finalize winner and return net gain/loss
		if dealer_result == 'B' or dealer_soft_value < soft_value: 
			return 1
		elif dealer_soft_value > soft_value:
			return -1
		else:
			return 0


	def run_player_hand(self, dealer_hand, player_hand):
		next_move = 'U'
		while True:
			#check if last move was double down
			if next_move == 'D':
				if self.hard_value(player_hand) > 21: return 'DB'
				return 'DS'

			#calc next move, including busts from a previous hit
			next_move = self.player_next_move(dealer_hand, player_hand)
			if next_move == 'H' or next_move == 'D':
				player_hand.append(self.shoe.draw())

			if next_move == 'S' or next_move == 'B' or next_move == 'P':
				return next_move

	def run_dealer_hand(self, dealer_hand):
		next_move = 'U'
		while True:
			if self.hard_value(dealer_hand) > 21: return 'B'
			if self.soft_value(dealer_hand) > 17: return 'S'
			dealer_hand.append(self.shoe.draw())

	def player_next_move(self, dealer_hand, player_hand):
		move = 'U'
		hard_value = self.hard_value(player_hand)
		if hard_value > 21: return 'B'
		if hard_value >= 17: return 'S' #unnecessary but improves performance

		if len(player_hand) == 2 and player_hand[0] == player_hand[1]:
			return Simulation.PAIRED_TABLE[dealer_hand[0]][player_hand[0]]

		if 1 in player_hand and hard_value <= 11:
			return Simulation.ACE_TABLE[dealer_hand[0]][hard_value - 1]

		return Simulation.VALUE_TABLE[dealer_hand[0]][hard_value]

	def hard_value(self, hand):
		sum = 0
		for card in hand:
			sum += card
		return sum

	def soft_value(self, hand):
		ace = False
		sum = 0
		for card in hand:
			sum += card
			if card == 1:
				ace = True
		if ace and sum <= 11:
			return sum + 10
		return sum
		
예제 #27
0
 def __init__(self):
     super().__init__()
     self._shoe = Shoe(1)
예제 #28
0
	def __init__(self, num_decks):
		self.shoe = Shoe(num_decks)
		self.balance = 0
		self.lower_balance = 0
		self.playing = True
예제 #29
0
 def set_table_style(self, insurance, blackjack_payout, shoe_size):
     self.insurance = insurance
     self.blackjack_payout = blackjack_payout
     self.shoe_size = shoe_size
     self.shoe = Shoe(shoe_size)
예제 #30
0
#!/usr/bin/python
from game import Game
from shoe import Shoe
from strategy import Strategy

shoe = Shoe(Shoe.DECK)
shoe.shuffle();
game = Game(Strategy(), { 'debug': True })
#game.debug()
#print(game.status)
print(game.play(shoe))
예제 #31
0
    def test_basic(self):
        shoe = Shoe()
        self.assertEquals(shoe.size(), 0)
        self.assertTrue(shoe.isEmpty())
        
        shoe = Shoe([ 1, 2, 3])
        self.assertEquals(shoe.size(), 3)
        self.assertFalse(shoe.isEmpty())
        self.assertEquals(shoe.get(), 1)
        self.assertEquals(shoe.size(), 3)
        shoe.pop()
        self.assertEquals(shoe.size(), 2)

        shoe = Shoe(Shoe.DECK)
        self.assertEquals(shoe.size(), 52)
        self.assertEquals(shoe.get(), 1)
예제 #32
0
 def test_four_of_each_face(self):
     shoe = Shoe(1)
     for face in Face:
         self.assertEqual(len([x for x in shoe._cards if x.face == face]), 4)
예제 #33
0
 def __init__(self, log, decks):
     Shoe.__init__(self, log, decks)
예제 #34
0
# %load main.py
from player import Player
from shoe import Shoe
from utilities import hit, newHand, deal, getReward, getAction, getUpdatedQsa
from collections import defaultdict
from IPython.display import clear_output

#import logging
#logging.basicConfig(filename='LearningPolicy.log', filemode='w', level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

# Initialize
shoe = Shoe(1)
dealer = Player()
player = Player()
Q = defaultdict(float)
N = defaultdict(float)
RTG = []  # Reward to Go function
CR = []  # Cumulative reward function
LOSS = []  # Loss function
ACTIONS = (
    'HIT',
    'STAND',
)
epsilon = 10
lr = 0.08
discount = 0.99
예제 #35
0
class BlackjackGame:
    HAND_KEY = "hand"
    BUST_KEY = "bust"
    DONE_KEY = "done"
    NUMBER_KEY = "number"
    BET_KEY = "bet"
    SURRENDER_KEY = "surrender"

    def __init__(self, log, bankroll, rules_section="Blackjack"):
        # Logger
        self.log = log

        # Required objects
        self.rules = BlackjackRules(log, rules_section)
        self.shoe = Shoe(log, self.rules.get_decks())
        self.event_listener = EventListener(log)

        # Variables
        self.bankroll = bankroll
        self.original_bet = 0
        self.need_to_shuffle = False
        self.split_hand_number = 1
        self.insurance = 0

        # Dealer hand related variables
        self.dealer_hand = []
        self.dealer_bust = False

        # Player hand related variables
        self.player_hand = self.new_player_hand()
        self.split_hands = []

    def get_rules(self):
        return self.rules

    def get_bankroll(self):
        return self.bankroll

    def get_dealer_hand(self):
        return self.dealer_hand

    def get_player_hand(self):
        return self.player_hand[self.HAND_KEY]

    def get_player_hand_number(self):
        return self.player_hand[self.NUMBER_KEY]

    def set_event_listener(self, event_listener):
        self.event_listener = event_listener

    def can_double_down(self, hand, bet):
        can = False
        if len(hand) == 2 and self.calc_total_bets() + bet <= self.bankroll:
            if self.rules.can_double_down_on_all() == True:
                can = True
            else:
                total = self.calc_highest_total(hand)
                if total >= 9 and total <= 11:
                    can = True
        return can

    def can_split(self, hand, bet):
        can = False
        if len(hand) == 2 and hand[0][0] == hand[1][
                0] and self.calc_total_bets() + bet <= self.bankroll:
            can = True
        return can

    def can_surrender(self):
        can = False
        if self.rules.is_surrender_allowed() and len(
                self.player_hand[self.HAND_KEY]) == 2 and len(
                    self.split_hands) == 0:
            can = True
        return can

    def can_buy_insurance(self):
        can = False
        if self.rules.is_insurance_allowed() and self.calc_rank(
                self.dealer_hand[1]
        ) == 1 and self.calc_total_bets() < self.bankroll:
            can = True
        return can

    def calc_rank(self, card):
        rank = 0
        char = card[0]
        if char.isdigit():
            rank = int(char)
        elif char == 'A':
            rank = 1
        elif char == 'T' or char == 'J' or char == 'Q' or char == 'K':
            rank = 10
        return rank

    def calc_highest_total(self, hand):
        total = 0
        aces = 0
        for card in hand:
            rank = self.calc_rank(card)
            #self.log.finest("card: " + card + ", rank: " + str(rank))
            if rank == 1:
                aces = aces + 1
            total = total + rank
        while total <= 11 and aces > 0:
            total = total + 10
            aces = aces - 1
        return total

    def calc_lowest_total(self, hand):
        total = 0
        for card in hand:
            rank = self.calc_rank(card)
            total = total + rank
        return total

    def calc_total_bets(self):
        total = self.player_hand[self.BET_KEY]
        for hand in self.split_hands:
            total = total + hand[self.BET_KEY]
        return total

    def is_blackjack(self, hand):
        blackjack = False
        if self.calc_highest_total(hand) == 21 and len(hand) == 2:
            blackjack = True
        return blackjack

    def has_splits(self):
        if len(self.split_hands) > 0:
            return True
        return False

    def new_player_hand(self):
        new_hand = {
            self.HAND_KEY: [],
            self.BUST_KEY: False,
            self.DONE_KEY: False,
            self.BET_KEY: self.original_bet,
            self.NUMBER_KEY: self.split_hand_number,
            self.SURRENDER_KEY: False
        }
        self.split_hand_number = self.split_hand_number + 1
        return new_hand

    def double_bet(self):
        self.player_hand[self.BET_KEY] = self.player_hand[self.BET_KEY] * 2
        self.player_hand[self.DONE_KEY] = True

    def surrender_hand(self):
        self.player_hand[self.SURRENDER_KEY] = True
        self.player_hand[self.DONE_KEY] = True

    def buy_insurance(self, insurance):
        if insurance >= 0 and insurance <= self.original_bet / 2 and self.calc_total_bets(
        ) + insurance <= self.bankroll:
            self.insurance = insurance
            return True
        return False

    def make_dealer_hole_card_visible(self):
        self.event_listener.event("card", self.dealer_hand[0])

    def deal_card(self, visible=True):
        card = self.shoe.deal()
        if card == "":
            self.need_to_shuffle = True
            card = self.shoe.deal()
            if card == "":
                self.log.warning("Shoe empty! Shuffling when not supposed to!")
                self.shoe.shuffle()
                self.event_listener.event("shuffle", "")
                card = self.shoe.deal()
        if visible == True:
            self.event_listener.event("card", card)
        return card

    def deal_card_to_dealer(self):
        self.dealer_hand.append(self.deal_card())
        if self.calc_highest_total(self.dealer_hand) > 21:
            self.dealer_bust = True

    def deal_card_to_player(self):
        self.player_hand[self.HAND_KEY].append(self.deal_card())
        if self.calc_highest_total(self.player_hand[self.HAND_KEY]) > 21:
            self.player_hand[self.BUST_KEY] = True

    def deal_hand(self, bet):
        # Save original bet
        self.original_bet = bet

        # Shuffle if need be
        if self.need_to_shuffle:
            self.need_to_shuffle = False
            self.shoe.shuffle()
            self.event_listener.event("shuffle", "")

        # Setup hands
        self.dealer_hand = []
        self.dealer_bust = False
        self.split_hands = []
        self.split_hand_number = 1
        self.player_hand = self.new_player_hand()
        self.insurance = 0

        # Deal hands
        self.player_hand[self.HAND_KEY].append(self.deal_card())
        self.dealer_hand.append(self.deal_card(False))
        self.player_hand[self.HAND_KEY].append(self.deal_card())
        self.dealer_hand.append(self.deal_card())

    def split_hand(self):
        self.log.finer("Before split: " + str(self.player_hand[self.HAND_KEY]))
        new_hand = self.new_player_hand()
        card = self.player_hand[self.HAND_KEY].pop()
        new_hand[self.HAND_KEY].append(card)
        self.player_hand[self.HAND_KEY].append(self.deal_card())
        new_hand[self.HAND_KEY].append(self.deal_card())
        self.split_hands.append(new_hand)
        self.log.finer("After split: " + str(self.player_hand[self.HAND_KEY]) +
                       str(new_hand[self.HAND_KEY]))

    def next_hand(self):
        next = False
        self.player_hand[self.DONE_KEY] = True
        for i in range(len(self.split_hands)):
            #print(self.split_hands[i])
            if self.split_hands[i][self.DONE_KEY] == False:
                next = True

                # Append current hand at the end of the split list
                self.split_hands.append(self.player_hand)

                # Pop the next not done hand and make it the current hand
                self.player_hand = self.split_hands.pop(i)

                break
        return next

    def is_player_hand_over(self):
        done = self.player_hand[self.DONE_KEY]
        if done == False:
            if self.player_hand[self.BUST_KEY] == True:
                done = True
            elif self.is_blackjack(self.player_hand[self.HAND_KEY]) == True:
                done = True
            self.player_hand[self.DONE_KEY] = done
        return done

    def is_dealer_hand_over(self):
        if self.is_blackjack(self.dealer_hand) == True:
            return True
        dealer_total = self.calc_highest_total(self.dealer_hand)
        if dealer_total > 17:
            return True
        if dealer_total == 17 and self.rules.does_dealer_hits_on_soft_17(
        ) == False:
            return True
        return False

    def finish_hand(self):
        result = []

        # Handle insurance bet
        dealer_blackjack = self.is_blackjack(self.dealer_hand)
        if self.insurance > 0:
            if dealer_blackjack:
                self.bankroll = self.bankroll + self.insurance * 2
            else:
                self.bankroll = self.bankroll - self.insurance

        # Go through hands
        while True:
            if self.player_hand[self.SURRENDER_KEY] == True:
                # Surrender, bet should be halved
                player_won = SURRENDER_RESULT
                self.bankroll = self.bankroll - self.player_hand[
                    self.BET_KEY] / 2
            else:
                player_won = PUSH_RESULT
                dealer_total = self.calc_highest_total(self.dealer_hand)
                player_total = self.calc_highest_total(
                    self.player_hand[self.HAND_KEY])

                # First, test for blackjacks
                player_blackjack = self.is_blackjack(
                    self.player_hand[self.HAND_KEY])
                if player_blackjack == True:
                    # Player blackjack! If dealer has blackjack too, push
                    if dealer_blackjack == False:
                        # No dealer black jack, pay out for blackjack
                        self.bankroll = self.bankroll + self.player_hand[
                            self.BET_KEY] * self.rules.get_blackjack_payout()
                        player_won = BLACKJACK_RESULT
                else:
                    # Next, test for dealer blackjack
                    if dealer_blackjack == True:
                        player_won = LOSS_RESULT
                    # Now, test for busts
                    elif self.player_hand[self.BUST_KEY] == True:
                        player_won = LOSS_RESULT
                    elif self.dealer_bust == True:
                        player_won = WIN_RESULT
                    else:
                        # Now, compare hands
                        if dealer_total == player_total:
                            if self.rules.does_push_goes_to_dealer() == True:
                                player_won = LOSS_RESULT
                        elif dealer_total > player_total:
                            player_won = LOSS_RESULT
                        else:
                            player_won = WIN_RESULT

                    # Payout
                    if player_won == WIN_RESULT:
                        self.bankroll = self.bankroll + self.player_hand[
                            self.BET_KEY]
                    elif player_won == LOSS_RESULT:
                        self.bankroll = self.bankroll - self.player_hand[
                            self.BET_KEY]
            result.append(player_won)

            if len(self.split_hands) > 0:
                # Pop the next hand and make it the current hand
                self.player_hand = self.split_hands.pop(0)
            else:
                break
        return result