質問

So, I've been working on a problem from Python Programming by John Zelle. The problem is to design a basic Blackjack program that demonstrates what percentage of the time a blackjack dealer will bust given the rule that he must hit until he has greater than 17. The program was designed to show the percentage likelihood for each initial card, since the dealer often reveals his first card.

The problem I have run into is that the program seems to give me good percentages for every value except Ace and Ten, when I cross reference them with Blackjack tables.

from random import randrange

def main():
    printIntro()
    n = getInput()
    busts = simBlackjack(n)
    printSummary(n, busts)

def printIntro():
    print "Hello, and welcome to Blackjack.py."
    print "This program simulates the likelihood"
    print "for a dealer to bust."

def getInput():
    n = input("How many games do you wish to simulate: ")
    return n

def simBlackjack(n):
    busts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for b in range(10):
        for i in range(n):
            x = b + 1
            if b == 0:
                handAce = True
            else: handAce = False
            while x < 17:
                add = randrange(1,14)
                if add == 11:
                    add = 10
                elif add == 12:
                    add = 10
                elif add == 13:
                    add = 10
                elif add == 1:
                    handAce = True
                x = x + add
                if handAce:
                    if x + 10 >= 17 and x + 10 <= 21:
                        x = x + 10

            if x > 21:
                busts[b] = busts[b] + 1

    return busts

def printSummary(n, busts):
    for b in range(10):
        if b == 0:
            print "When the initial card was Ace, the dealer busted %d times in %d games. (%0.1f%%)" % (busts[0], n, (busts[0]) / float(n) * 100)
        else:
            print "When the initial value was %d, the dealer busted %d times in %d games. (%0.1f%%)" % ((b + 1), busts[b], n, (busts[b]) / float(n) * 100)

if __name__ == "__main__": main()

If n = 1,000,000, I get ~ 11.5% and 21.2% respectively, which differs from the 17% and 23% that online tables keep significantly. Can anybody let me know what the problem is?

役に立ちましたか?

解決 2

The answer was that my program's percentages are based on infinitely large deck shoes, which alter the percentage tables. The original tables I was looking at were for single decks. I found lots of sites with precisely my values after further research.

Having said that, thank you for all of your help. Certainly Jonathan Vanasco's method of approaching the problem was better and more scalable. I am a newbie so it was very educational.

I do think it is interesting that the infinitely large deck shoe affects the fringes of the probability tables the most.

他のヒント

The big issue i see is the scoring logic calculates the Ace at the end of the loop into a hard value of 'x', and it persists. once you have an ace, that "if handAce" line runs every time.

It also looks to be built on the idea that you can have one and only one case. But you could theoretically - but unlikely - be dealt 24 Aces if the shoe has 4 decks. I've been dealt multiple Aces many times, and each one gives you a different way to score the deck.

i think its fine not dealing with a set of cards from a set number of decks (ie, consuming the cards).

anyways, i would probably redo this with a bit more of an oop style to solve the ace issue:

class BlackjackHand(object):
    cards= None

    def __init__(self):
        self.cards = []

    def autoplay(self,initial_card=None):
        if initial_card:
            self.cards.append(initial_card)
        return self.calculate()

    def calculate(self):
        total = 0
        for card in self.cards:
            ## compute!
        return total

i also would probably deal with the faces themselves , just to keep things clean looking:

faces = [ str(i) for i in (1,2,3,4,5,6,7,8,9,10,'j','q','k','a') ]
def facevalue(face):
    if face.isdigit():
        return ( int(face) , 0 )
    if face in ('j','q','k'):
        return ( 10 , 0 )
    if face == 'a':
        return ( 1 , 1 )

this way you could do...

def simBlackjack(n):
    for face in faces:
        for i in range(n):
            hand = BlackjackHand()
            score = hand.autoplay(initial_card=face)

and calculate with something like...

( hand , aces ) = facevalue( face )
while True:
    new_card  = random.choice( faces )
    ( new_card_value , new_card_is_ace ) = facevalue( new_card )
    hand += new_card_value
    aces += new_card_is_ace
    # calculate the multiple different scoring possibilities 
    # if all of them bust, then break

there might be other issues in there, but the big obvious problem to me is that your code doesn't support Aces very well.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top