python 图形界面“诈金花”游戏,更新了!附完整代码_python把52张扑克图片转为界面

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

Ask if operation should be retried; return true if the answer is yes
    
    askyesno(title=None, message=None, **options)
        Ask a question; return true if the answer is yes
    
    askyesnocancel(title=None, message=None, **options)
        Ask a question; return true if the answer is yes, None if cancelled.
    
    showerror(title=None, message=None, **options)
        Show an error message
    
    showinfo(title=None, message=None, **options)
        Show an info message
    
    showwarning(title=None, message=None, **options)
        Show a warning message

DATA
    ABORT = ‘abort’
    ABORTRETRYIGNORE = ‘abortretryignore’
    CANCEL = ‘cancel’
    ERROR = ‘error’
    IGNORE = ‘ignore’
    INFO = ‘info’
    NO = ‘no’
    OK = ‘ok’
    OKCANCEL = ‘okcancel’
    QUESTION = ‘question’
    RETRY = ‘retry’
    RETRYCANCEL = ‘retrycancel’
    WARNING = ‘warning’
    YES = ‘yes’
    YESNO = ‘yesno’
    YESNOCANCEL = ‘yesnocancel’

:发牌、开牌、洗牌按钮可否点击,由两个全局变量控制,当不能使用时弹出提示信息框。但更好方式通常是设置按钮的state状态,在 tk.DISABLED 和 tk.NORMAL 之间切换,用以下代码:

if btn[0]['state'] == tk.DISABLED:
	btn[0]['state'] = tk.NORMAL
else:
	btn[0]['state'] = tk.DISABLED  #使得按钮灰化,无法被按下

#或者在初始按钮时使用:
tk.Button(root,text="点不了",command=test,width=10,state=tk.DISABLED)
“诈金花”完整源代码
import tkinter as tk
import tkinter.messagebox as msg
from PIL import Image,ImageTk
from time import sleep
from random import shuffle as DealCards
#代码中所有print()语句行测试用都可删除
#Written by Hann@CSDN,2022.12.06
#https://hannyang.blog.csdn.net/
def loadCards():
    PngList = []
    infile = Image.open("pokers.png") 
    for k in range(4):
        box = 0,0,1500,1500 #设置正方形区域存放图片旋转后的状态
        box = infile.crop(box).rotate(90*k) #图片逆时间旋转90度的整数倍
        if   k==0: rng = (0,0,1500,600)
        elif k==1: rng = (0,0,600,1500)
        elif k==2: rng = (0,900,1500,1500)
        elif k==3: rng = (900,0,1500,1500)
        box = box.crop(rng) #截取掉旋转产生的黑色背景
        images = []
        for j in range(4): #分割所有纸牌的图像存入三维列表
            image = []
            for i in range(15):
                if k%2:
                    rng = (j*150,i*100,j*150+150,i*100+100)
                else:
                    rng = (i*100,j*150,i*100+100,j*150+150)
                img = ImageTk.PhotoImage(image=box.crop(rng))
                image.append(img)
            images.append(image)
        PngList.append(images)
    '''调整并统一各方向上的纸牌图像顺序'''
    PngList[0],PngList[2] = PngList[2],PngList[0]
    for i in range(4):
        for j in range(2):
            PngList[j][i]=PngList[j][i][::-1]
    for i in range(0,4,3):
        PngList[i]=PngList[i][::-1]
    infile.close()
    return PngList
 
def initCards():
    global P
    P = [f+v for f in F for v in V]
    DealCards(P)
    print('洗牌结果:\n',P)

def clearCards():
    global cv
    cv.itemconfig(txt1, text="")
    cv.itemconfig(txt2, text="")
    if len(Pokers):
        for j in range(3):
            for i in range(4):
                cv.itemconfig(cards[i][j], image=Cards[i][0][0])
                cv.update()
        sleep(0.3)

def dealCards():
    global cv,isReady1,isReady2
    if not isReady1:
        showInfo('不要重复发牌,发牌结束后请开牌!')
        return
    clearCards()
    isReady1 = False
    for j in range(3):
        for i in range(4):
            cv.itemconfig(cards[i][j], image=Cards[i][1][0])
            cv.update()
            sleep(0.2)
    if len(P)<12: initCards()
    isReady2 = False
 
def playCards():
    global cv,isReady1,isReady2,P,Pokers
    if isReady1:
        showInfo('还没发牌,请发牌或者洗牌!')
    elif isReady2:
        showInfo('发牌还未结束,请勿开牌!')
    else:
        P = Result(P)
        isReady1,isReady2 = True,True
        for i,pok in enumerate(Pokers):
            for j,p in enumerate(pok):
                x,y = F.index(p[0]), V.index(p[1])
                cv.itemconfig(cards[i][j], image=Cards[i][x][y+2])
                cv.update()
        for i in range(4):
            cv.itemconfig(txt[i], text=str(Money[i])) #修改各方的筹码值
            cv.update()
        if min(Money)<=0: #统计输赢成绩
            zero = [f'Player{i}' for i,j in enumerate(Money,1) if j<=0]
            winner = [f'Player{i}({j})' for i,j in enumerate(Money,1) if j>ALL]
            info = '、'.join(zero)+'已输光筹码,点击确定重新开始!\n\n'
            info += f'本轮胜者(筹码多于初始值):'+'、'.join(winner)
            sleep(1)
            msg.showinfo(title = '提示',message=info)
            for i in range(4):
                Money[i] = ALL #重置各方筹码初始值
                cv.itemconfig(txt[i], text=str(Money[i])) 
                cv.update()
            clearCards()
            initCards()
            isReady1,isReady2 = True,False
 
def Scores(pokers):
    f,p = [],[]
    for poker in pokers:
        f.append(F.index(poker[0])+1)
        p.append(V.index(poker[1])+2)
    t = sorted(p)
    intSame = len(set(t))
    isFlush = int(len(set(f))==1)
    isStraight = t[0]+1==t[1]==t[2]-1
    if intSame==1:
        return 500_0000+t[0] #豹子
    elif intSame==2: #对子一样大比较剩下的单张
        return (100+t[1])*10000+(t[2] if t[0]==t[1] else t[0])
    else: #顺金(同花顺)顺子 else #单张或金花
        Straight = 200_0000*(1+isFlush)+t[2]
        Flush = ((300*isFlush+t[2])*100+t[1])*100+t[0] 
        return Straight if isStraight else Flush
 
def Result(P):
    global cv,Pokers
    Pokers,Winner = [],[]
    for i in range(0,3*4,3):
        Pokers.append(P[i:i+3])
    for i,p in enumerate(Pokers,1):
        win = Scores(p)
        idx = win//100_0000
        print(f"Player{i}: {*p,} - {W[idx]}".replace('T','10'))
        Winner.append(win)
    win = max(Winner) #没有判断“一样大”,如是则谁在前谁为大
    idx = Winner.index(win)
    big = win//10000
    win = big//100
    per = X[win] if win else Y[big-5]
    pok = W[win] if win else '单'+V[big-2]
    text1 = f"【Player{idx+1} win!】"
    text2 = f"{pok}{*Pokers[idx],} {per}%\n".replace('T','10')
    print(text1,'--> ',text2)
    cv.itemconfig(txt1, text=text1)
    cv.itemconfig(txt2, text=text2)
    Money[idx] += ONE*4 #每次赢ONE*3,多加自己的一份
    for i in range(4): Money[i] -= ONE #多加的在此扣减
    return P[3*4:] #去掉一局已发的牌
 
def Shuffle():
    global isReady1
    if isReady1:
        clearCards()
        initCards()
        showInfo('已重新洗牌,请发牌!')
    else:
        showInfo('还没开牌呢,请勿洗牌!')

def showInfo(info):
    msg.showinfo(title='提示',message=info)

def ExitApp():
    if msg.askokcancel(title='确认',message='确定要退出吗?'):
        root.destroy()  #关闭窗口退出程序

if __name__ == '__main__':
    W = "单张","对子","顺子","金花","顺金","豹子" #牌型
    X = 74.38, 16.94, 3.26, 4.96, 0.22, 0.24  #各牌型出现概率
    Y = 0.54, 1.36, 2.44, 3.8, 5.43, 7.33, 9.5, 11.95, 14.66, 17.38 #单张概率
    V = *(str(i) for i in range(2,10)),*'TJQKA' #T代表10
    F = '♠', '♥', '♣', '♦'
    ALL, ONE = 1000, 200 #筹码初始值、单次输赢值
    Money = [ALL]*4 #设置各方筹码初始值
    '''Written by HannYang@CSDN, 2022.12.03'''
    root = tk.Tk()
    root.title('诈金花')
    root.geometry('1024x768')
    root.resizable(0,0) #禁止窗体改变大小
    cv = tk.Canvas(root, width=1024, height=680, bg='darkgreen')
    cv.pack()
    Pokers = []
    initCards()
    Cards = loadCards()
    isReady1,isReady2 = True,True #发牌、开牌的准备标记
    cards = [[None]*3 for _ in range(4)]
    '''设置发牌区域'''
    x1, x2, x3, dx = 400, 180, 830, 105
    y1, y2, y3 = 100, 550, 220 #调整坐标,使左右两家的牌横向显示
    imgxy = [[(x1,y1),(x1+dx,y1),(x1+2*dx,y1)],
             [(x3,y3),(x3,y3+dx),(x3,y3+2*dx)],
             [(x1,y2),(x1+dx,y2),(x1+2*dx,y2)],
             [(x2,y3),(x2,y3+dx),(x2,y3+2*dx)]]
    btn,txt = [],[]
    for x,lst in enumerate(imgxy):
        for y,coord in enumerate(lst):
            cards[x][y] = cv.create_image(coord, image=Cards[x][0][0])
            x1,y1,x2,y2 = coord[0]-50,coord[1]-50,coord[0]+50,coord[1]+50
            if x%2:
                cv.create_rectangle(x1-25,y1,x2+25,y2) #纸牌外框
            else:
                cv.create_rectangle(x1,y1-25,x2,y2+25)
        if x%2:
            tx,ty = coord[0]-25,coord[1]+65 #玩家、筹码的显示坐标
        else:
            tx,ty = coord[0]-130,coord[1]+90
        cv.create_text(tx,ty, text=f'Player{x+1}', fill='white') #玩家1-4显示文本框
        txt.append(cv.create_text(tx+60,ty, fill='gold',text=Money[x])) #筹码显示框
    '''设置显示每次开牌的胜者、牌型和出现概率的文本框'''
    txt1 = cv.create_text(510,300, fill='tomato', font=("宋体", 24))
    txt2 = cv.create_text(510,360, fill='yellow', font=("宋体", 12))
    '''设置命令按钮和菜单'''
    btnCmd = '发牌',dealCards,'开牌',playCards,'洗牌',Shuffle
    for i in range(3):
        btn.append(tk.Button(root,text=btnCmd[i*2],command=btnCmd[i*2+1],width=10))
        btn[i].place(y=710, x=350+i*110)
    Menu = tk.Menu(root)
    menu = tk.Menu(Menu, tearoff = False)
    for t,cmd in zip(btnCmd[::2],btnCmd[1::2]):
        menu.add_radiobutton(label = t, command = cmd)
    menu.add_separator() #菜单分割线
    menu.add_command(label = "退出", command = ExitApp)
    Menu.add_cascade(label="菜单",menu = menu)
    root.config(menu = Menu)
    ''''''
    root.mainloop()

运行结果:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Menu)
‘’‘’‘’
root.mainloop()


运行结果:



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
[外链图片转存中...(img-vGz2XXOh-1713317197182)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值