2

所以,我一直在研究 John Zelle 的 Python Programming 中的一个问题。问题是设计一个基本的二十一点程序,该程序演示二十一点经销商在给定规则他必须击中直到他大于 17 的情况下将失败的时间百分比。该程序旨在显示每张初始牌的可能性百分比,因为庄家经常亮出他的第一张牌。

我遇到的问题是,当我将它们与二十一点表交叉引用时,该程序似乎为除了 A 和十之外的每个值都提供了很好的百分比。

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()

如果 n = 1,000,000,我分别得到 ~ 11.5% 和 21.2%,这与在线表格保持的 17% 和 23% 显着不同。谁能让我知道问题是什么?

4

2 回答 2

1

我看到的最大问题是评分逻辑将循环结束时的 Ace 计算为硬值“x”,并且它仍然存在。一旦你有一张王牌,“if handAce”这条线每次都会运行。

它看起来也建立在您可以拥有一个且只有一个案例的想法之上。但是,如果鞋子有 4 副牌,理论上你可以 - 但不太可能 - 得到 24 个 A。我已经多次获得多个 A,每一个都为你提供了不同的方式来得分。

我认为不处理一组套牌中的一组卡片(即消耗卡片)很好。

无论如何,我可能会用更多的 oop 风格重做这个来解决 ace 问题:

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

我也可能会自己处理面孔,只是为了保持整洁:

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 )

这样你可以做...

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

并用类似的东西计算...

( 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

那里可能还有其他问题,但对我来说最明显的问题是您的代码不能很好地支持 Aces。

于 2012-09-12T01:21:12.883 回答
0

答案是我的程序的百分比是基于无限大的甲板鞋,这会改变百分比表。我正在查看的原始表是用于单层的。经过进一步研究,我发现了很多符合我价值观的网站。

话虽如此,感谢您的所有帮助。当然,乔纳森·瓦纳斯科解决问题的方法更好,更具可扩展性。我是新手,所以很有教育意义。

我确实认为有趣的是,无限大的甲板鞋对概率表边缘的影响最大。

于 2012-09-12T12:48:46.623 回答