用python(tkinter)21点绘制卡片
我在画布上画卡片有问题。当我按下交易按钮时,什么也没发生。我不知道我在哪里犯了错误。我试图在所有画布的末尾添加.pack()函数。创建\u图像。。。。然后我得到一张卡片,错误是:“int”对象没有属性“pack” 请帮忙 这是我目前的代码:用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
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