2012-09-11 297 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

廢話是正確的。 –