2012-09-11 29 views
2

所以,我一直在研究John Zelle编程的一个问题。问题在于设计一个基本的21点游戏程序,该程序演示了一个二十一点经销商在超过17岁之前必须击中的规则会占多大比例。该程序旨在显示每张初始卡的可能性百分比,因为经销商经常透露他的第一张牌。大酒杯回馈错误的经销商百分比

我遇到的问题是,程序似乎给我很好的百分比,除了Ace和十,当我交叉引用他们与二十一点表。

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 = 100万,我得到〜11.5%和21.2%,从17%相差23%,网上表格显著保持。有人可以让我知道问题是什么吗?

+1

你有什么试图找出问题的原因?计算应该是什么? – Marcin

+0

可能是因为您只使用经销商手中的一套房而不移除使用的卡? (不知道这是否是实际问题......但它可能是......) –

+0

@JoranBeasley--这也是我的想法。虽然...差异似乎过高... – mgilson

回答

0

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

话虽如此,谢谢你的帮助。当然Jonathan Vanasco解决问题的方法更好,更具可扩展性。我是一个新手,所以它非常有教育意义。

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

+0

记得接受解决你的问题的答案:) – Landric

+0

@Landric:22小时内! :) –

1

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

它也看起来建立在这样的想法上,你可以有一个并且只有一个案例。但是,如果鞋子有4副甲板,你可以在理论上 - 但不太可能 - 可以得到24点王牌。我已经多次处理过多次A,每次都给你一种不同的方式来得分甲板。

我认为它没有处理一套从一定数量的套牌(即,消费卡)的卡。

反正,我可能会用更多的面向对象的风格有点重做这个解决王牌问题:

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) 

与someth计算就像...

(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 

那里可能还有其他问题,但对我来说最大的明显问题是你的代码不支持王牌。

+2

我的想法是我不需要支持多个王牌,因为你永远不会想要两个王牌等于十一。 (因为这本质上是一场暴跌。) –

+0

废话是正确的。 –