2013-08-21 23 views
-1

我在畫布上繪製卡有問題。當我按下處理按鈕時沒有任何反應。我不知道我在哪裏犯錯。我嘗試添加.pack()函數在所有canvas.create_image ....結束後,然後我得到一個卡和錯誤:'int'對象沒有屬性'包'在蟒蛇(tkinter)二十一點中繪圖卡

請幫助。

這是我到目前爲止的代碼:

from Tkinter import * 
from PIL import Image, ImageTk 
import random 

HEIGHT = 860 
WIDTH = 1024 

CARD_SIZE = (73, 98) 


CARD_BACK_SIZE = (71, 96) 


DECK_POS = [400,800] 
PLAYER_POS = [WIDTH/2,700] 
DEALER_POS = [WIDTH/2,90] 


player_hand = [] 
dealer_hand = [] 
deck = [] 
in_play = False 
outcome = "" 
score = 0 

SUITS = ['C', 'S', 'H', 'D'] 
RANKS = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'] 
VALUES = {'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':10, 'Q':10, 'K':10} 



class Cards: 
    def __init__(self,suit,rank): 
     self.suit = suit 
     self.rank = rank 

    def get_suit(self): 
     return self.suit 

    def get_rank(self): 
     return self.rank 

    def __str__(self): 
     return self.suit + self.rank 

    def draw(self,position): 
     CARD = Image.open ("C:\Users\Petar\Desktop\cards.png") 
     box = [RANKS.index(self.rank) * CARD_SIZE[0], SUITS.index(self.suit) * CARD_SIZE[1], CARD_SIZE[0] * (RANKS.index(self.rank)+1) , CARD_SIZE[1] * (SUITS.index(self.suit)+1)] 
     cropped = CARD.crop(box) 
     karta = ImageTk.PhotoImage(cropped) 
     canvas.create_image(position, image=karta) 


class Hand: 
    def __init__(self): 
     self.card_list=[] 

    def add_card(self,card): 
     self.card_list.append(card) 

    def get_value(self): 
     global VALUES 
     self.hand_value = 0 
     aces = 0 
     for c in self.card_list: 
      self.hand_value += VALUES.get(c.get_rank()) 
      if c.get_rank() == "A": 
       aces += 1 
     if aces == 0: 
      return self.hand_value 
     else: 
      if self.hand_value +10 <= 21: 
       return self.hand_value +10 
      else: 
       return self.hand_value 

    def __str__(self): 
     self.hand_str = "" 
     for c in self.card_list: 
      self.hand_str += str(c)+" " 
     return "Hand contains " + self.hand_str 


    def draw(self,position): 
     pos_h = position 
     for c in self.card_list: 
      c.draw(pos_h) 
      pos_h[0] = pos_h[0] + CARD_SIZE[0] + 3 




class Deck: 
    def __init__(self): 
     self.deck_list = [] 
     # standard 52 card deck 
     global SUITS 
     global RANKS 
     for s in SUITS: 
      for r in RANKS: 
       self.deck_list.append(Cards(s, r))    

    def shuffle(self): 
     # add cards back to deck and shuffle 
     # self = Deck() 
     return random.shuffle(self.deck_list) 

     #adding back this way did not work 

    def deal_card(self): 
     return self.deck_list.pop(0) 

    def __str__(self): 
     self.deck_str = "" 
     for c in self.deck_list: 
      self.deck_str += str(c)+" " 
     return "Deck contains " + self.deck_str 



def deal(): 
    global outcome, score, in_play 
    global player_hand, dealer_hand, game_deck 
    if in_play: 
     outcome = "You forfeit this hand." 
     in_play = False 
     score -= 1 
     return 

    #shuffle the deck 
    game_deck = Deck() 
    game_deck.shuffle() 

    #create new hands 
    player_hand = Hand() 
    dealer_hand = Hand() 
    #add two cards to each hand 
    player_hand.add_card(game_deck.deal_card()) 
    dealer_hand.add_card(game_deck.deal_card()) 
    player_hand.add_card(game_deck.deal_card()) 
    dealer_hand.add_card(game_deck.deal_card()) 
    in_play = True 
    #print "Player", player_hand 
    #print "Dealer", dealer_hand 
    outcome = "Hit or stand?" 
    draw() 
    player_hand.draw(PLAYER_POS) 
    dealer_hand.draw(DEALER_POS) 

def hit(): 
    global in_play, player_hand, dealer_hand, outcome, score 
    # if the hand is in play, hit the player 
    if in_play: 
     player_hand.add_card(game_deck.deal_card()) 
     #print "Player", player_hand 

    # if busted, assign a message to outcome, update in_play and score 
     if player_hand.get_value() > 21: 
      outcome = "Sorry, you busted!" 
      #print outcome 
      in_play = False 
      score -= 1 
    player_hand.draw(PLAYER_POS) 

def stand(): 
    global in_play, player_hand, dealer_hand, outcome, score 
    if not in_play: 
     outcome = "Too, late, your hand is already busted." 
     return 
    else: 
     while dealer_hand.get_value() < 17: 
      dealer_hand.add_card(game_deck.deal_card()) 
      print "Dealer", dealer_hand 
    if dealer_hand.get_value() > 21: 
     outcome = "Dealer busted! You win!" 
     in_play = False 
     score += 1 
    else: 
     player_value = player_hand.get_value() 
     dealer_value = dealer_hand.get_value() 
     print "Player has ",player_value, "Dealer has ",dealer_value 
     if player_value <= dealer_value: 
      outcome = "Dealer wins!" 
      score -= 1 
     else: 
      outcome = "Player wins!" 
      score += 1 
     in_play = False 
    print player_hand.get_value() 
    print dealer_hand.get_value() 


def draw(): 
    if in_play: 
     back = Image.open("C:\Users\Petar\Desktop\card_back.png") 
     CARD_BACK = ImageTk.PhotoImage(back) 
     canvas.create_image(DEALER_POS,image=CARD_BACK) 





root=Tk() 

canvas=Canvas(root,height=HEIGHT,width=WIDTH) 
canvas.pack() 


Deal=Button(text="Deal",command=deal).pack() 
Hit=Button(text="Hit",command=hit).pack() 
Stand=Button(text="Stand",command=stand).pack() 



root.mainloop() 
+0

請注意,在代碼結束時,變量'Deal','Hit'和'Stand'都是對'None'的引用,因爲您已將它們設置爲'pack'的輸出。函數,它返回'None'。您需要先保存對這些按鈕的引用,然後在它們上面打電話包,如果您想要使用對它們的引用。 – Brionius

+0

是這樣的? 新政=按鈕(文本= 「新政」,命令=交易) Deal.pack() 命中=按鈕(文本= 「命中」,命令=命中) Hit.pack() 展位=按鈕(text =「Stand」,command = stand) Stand.pack() –

+0

完全正確。 – Brionius

回答

1

的一個問題,我看到的是在Card.draw方法。

使用TkinterPhotoImage類有一個小技巧。你必須保持你自己的參考每個PhotoImage實例,否則python的垃圾收集器將摧毀它。我懷疑這就是爲什麼當你按下「優惠」按鈕時你永遠不會看到你的卡片出現。

要修復它,將它添加到您的Card.__init__方法:

class Cards: 
    def __init__(self,suit,rank): 
     self.suit = suit 
     self.rank = rank 
     self.karta = None 
#  ^^^^^^^^^^^^^^^^^ 

並使這些更改您的Card.draw方法:

def draw(self,position): 
     CARD = Image.open ("C:\Users\Petar\Desktop\cards.png") 
     box = [RANKS.index(self.rank) * CARD_SIZE[0], SUITS.index(self.suit) * CARD_SIZE[1], CARD_SIZE[0] * (RANKS.index(self.rank)+1) , CARD_SIZE[1] * (SUITS.index(self.suit)+1)] 
     cropped = CARD.crop(box) 
     self.karta = ImageTk.PhotoImage(cropped) 
#  ^^^^^ 
     canvas.create_image(position, image=self.karta) 
#                ^^^^^ 

這樣,你的Card對象將保持引用其PhotoImage實例和python不會垃圾收集它們。

+0

是的,就是這樣。非常感謝:) –

+0

嗯,但現在不知道爲什麼卡移動到正確的?即使在交易方式。 –

+0

我這裏想什麼是錯 DEF繪製(個體,位置): 對於C在self.card_list: pos_h =位置 c.draw(pos_h) pos_h [0] + = CARD_SIZE [0] + 3 –