Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python(tkinter)21点绘制卡片_Python_Canvas_Tkinter_Blackjack - Fatal编程技术网

用python(tkinter)21点绘制卡片

用python(tkinter)21点绘制卡片,python,canvas,tkinter,blackjack,Python,Canvas,Tkinter,Blackjack,我在画布上画卡片有问题。当我按下交易按钮时,什么也没发生。我不知道我在哪里犯了错误。我试图在所有画布的末尾添加.pack()函数。创建\u图像。。。。然后我得到一张卡片,错误是:“int”对象没有属性“pack” 请帮忙 这是我目前的代码: from Tkinter import * from PIL import Image, ImageTk import random HEIGHT = 860 WIDTH = 1024 CARD_SIZE = (73, 98) CARD_BACK_S

我在画布上画卡片有问题。当我按下交易按钮时,什么也没发生。我不知道我在哪里犯了错误。我试图在所有画布的末尾添加.pack()函数。创建\u图像。。。。然后我得到一张卡片,错误是:“int”对象没有属性“pack”

请帮忙

这是我目前的代码:

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()
从Tkinter导入*
从PIL导入图像,ImageTk
随机输入
高度=860
宽度=1024
卡片大小=(73,98)
卡片背面尺寸=(71,96)
甲板位置=[400800]
播放器位置=[宽度/2700]
经销商位置=[宽度/2,90]
玩家手=[]
经销商手=[]
甲板=[]
正在播放=错误
结果=“”
分数=0
套装=['C'、'S'、'H'、'D']
排名=['A','2','3','4','5','6','7','8','9','10','J','Q','K']
值={'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}
班级卡:
定义初始(自我、西装、军衔):
西服
self.rank=等级
def get_套装(自我):
自诉
def get_等级(自我):
返回自我等级
定义(自我):
返回self.suit+self.rank
def牵引(自身、位置):
CARD=Image.open(“C:\Users\Petar\Desktop\cards.png”)
box=[RANKS.index(self.rank)*卡牌大小[0],套装.index(self.suit)*卡牌大小[1],卡牌大小[0]*(RANKS.index(self.rank)+1),卡牌大小[1]*(套装.index(self.suit)+1)]
裁剪=卡片。裁剪(框)
karta=ImageTk.PhotoImage(裁剪)
canvas.create_image(位置,image=karta)
班主任:
定义初始化(自):
self.card_list=[]
def添加卡(自身,卡):
self.card\u list.append(卡片)
def get_值(自身):
全球价值
self.hand_值=0
ACE=0
对于自助卡列表中的c:
self.hand\u value+=VALUES.get(c.get\u rank())
如果c.get_rank()=“A”:
ACE+=1
如果aces==0:
返回self.hand\u值
其他:
如果self.hand_值+10 21:
结果=“对不起,你被抓到了!”
#打印结果
正在播放=错误
分数-=1
牌手手抽签(牌手位置)
def stand():
全球比赛、球员手牌、庄家手牌、结果、得分
如果不在游戏中:
结果=“太晚了,你的手已经断了。”
返回
其他:
当经销商手拿时,获取值()<17:
庄家牌。添加牌(游戏牌组。发牌()
打印“经销商”,经销商
如果经销商手动获取值()>21:
结果=“经销商破产!你赢了!”
正在播放=错误
分数+=1
其他:
玩家\值=玩家\手。获取\值()
经销商\值=经销商\手。获取\值()
打印“玩家拥有”,玩家价值,“经销商拥有”,经销商价值

如果玩家的值我看到的一个问题是
卡。draw
方法

使用
Tkinter
PhotoImage
类有一个小技巧。必须保留对每个
PhotoImage
实例的引用,否则python的垃圾收集器会将其销毁。我想这就是为什么当你按下“交易”按钮时,你永远看不到你的卡片出现的原因

要解决此问题,请将其添加到您的
卡中。\uuuu init\uuuu
方法:

class Cards:
    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank  
        self.karta = None
#       ^^^^^^^^^^^^^^^^^
    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) 
#                                           ^^^^^
并对您的
卡进行以下更改。绘制方法:

class Cards:
    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank  
        self.karta = None
#       ^^^^^^^^^^^^^^^^^
    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) 
#                                           ^^^^^

这样,您的
对象将维护对其
PhotoImage
实例的引用,python不会对其进行垃圾收集。

请注意,在代码末尾,变量
交易
命中
站立
都是对
的引用,因为您已经将它们设置为
pack
函数的输出,该函数返回
None
。你需要先保存对按钮的引用,然后调用pack,如果你想使用对按钮的引用,像这样?是的,就是这个。非常感谢:)嗯,但是现在不确定为什么卡片会移到右边?即使是在交易方法上。我猜这里的def draw(self,position)是错误的:对于self.card_列表中的c:pos_h=position c.draw(pos_h)pos_h[0]+=card_SIZE[0]+3修复了这个问题,将position创建为元组,然后将其作为列表分配给pos_h