Edward Henry Brenner
Edward Henry Brenner

Reputation: 157

Making python blackjack code more efficent

I wrote a piece of blackjack code - for dealer dealing cards to himself (python). My question is how can I make it more efficient, faster and neater. I ran it for 1.000.000 iterations and it took 14.7 second which is quite slow, I believe.

import random
deck = 4 * [2,3,4,5,6,7,8,9,10,10,10,10,11]
random.shuffle(deck)


dealer_hand = []
dealer_hand.append(deck.pop(0))
dealer_hand.append(deck.pop(0))
hit_on_soft_17 = True
exit = False

while not exit:
    if sum(dealer_hand) == 17 and hit_on_soft_17:
        exit = True
        for i, card in enumerate(dealer_hand):
            if card == 11:
                exit = False
                dealer_hand.append(deck.pop(0))
                break
    if sum(dealer_hand) < 17:
        exit = False
        dealer_hand.append(deck.pop(0))
    if sum(dealer_hand) > 21: 
        exit = True
        for i, card in enumerate(dealer_hand):
            if card == 11:
                exit = False
                dealer_hand[i] = 1
                break
    if sum(dealer_hand) < 22 and sum(dealer_hand) > 17:
        exit = True

print(dealer_hand)

Upvotes: 0

Views: 246

Answers (2)

Ben Grossmann
Ben Grossmann

Reputation: 4782

I've made a few changes. First, dealing from the end of the array instead of the beginning is faster, so I've changed all pop statements accordingly. I've also neatened up the check for a soft 17, removed redundant exit = False statements, and replaced ifs with elifs.

import random
deck = 4 * [2,3,4,5,6,7,8,9,10,10,10,10,11]
random.shuffle(deck)


dealer_hand = []
dealer_hand.append(deck.pop())
dealer_hand.append(deck.pop())
hit_on_soft_17 = True
exit = False

while not exit:
    if sum(dealer_hand) == 17 and hit_on_soft_17:
        if 11 in dealer_hand:
            dealer_hand.append(deck.pop())
        else:
            exit = True
    elif sum(dealer_hand) < 17:
        dealer_hand.append(deck.pop())
    elif sum(dealer_hand) > 21: 
        for i, card in enumerate(dealer_hand):
            if card == 11:
                dealer_hand[i] = 1
                break
        else:
            exit = True
    elif sum(dealer_hand) < 22 and sum(dealer_hand) > 17:
        exit = True

print(dealer_hand)

Upvotes: 2

code-lukas
code-lukas

Reputation: 1651

The reason for your performance are your if clauses and for loops. A step in the right direction would be to use elif. If you use 3.10 or higher this is a good use case for Structural Pattern Matching (SPM). In > 3.10 you can use match & case. You may also not need some of the for loops. The first one can be reduced to if 11 in dealer_hand... But since your list size is only ever 2, this won't do much.

Edit: Since you are looking for the ace in your if statements it might make sense to keep the dealer hand sorted. With 11 being the largest expectable value, you'd know it's always at index 0 / 1 in descending / ascending order.

Upvotes: 2

Related Questions