• Tkinter模拟扑克牌和狼人杀发牌


    今天我们用tkinter的canvas画布实现扑克牌的随机发牌:将54张牌随机发给四位牌手,在屏幕上显示每位牌手的牌,利用Canvas将发牌结果显示出来。

    需要准备的是54张扑克牌的图片(gif或者png,jpg的话要经过额外的转换),为了保证最终的牌序是按照由小到大排列的,图片编号要按照AAAA、2222……KKKK、大小王来排列(也许A和2应该更大,但是请忽略这一点)。

    下面是完整代码:

    from tkinter import *
    import random
    
    n=54
    (player1,player2,player3,player4)=([],[],[],[])
    (p1,p2,p3,p4)=([],[],[],[])
    pocker=[i for i in range(n)]
    imgs=[]
    root=Tk()
    cv=Canvas(root,bg="White",width=700,height=600)
    
    #洗牌(用随机交换打乱牌序)
    def gen_pocker(n):
        x=100
        while(x>0):
            x=x-1
            p1=random.randint(0,n-1)
            p2=random.randint(0,n-1)
            t=pocker[p1]
            pocker[p1]=pocker[p2]
            pocker[p2]=t
        return pocker
        
    pocker=gen_pocker(n)  #打乱后的牌组编号
    #将图片放入imgs列表
    for i in range(1,55):
        imgs.insert(i,PhotoImage(file="imgs/"+str(i)+".gif"))
    #发牌,
    for m in range(0,54,4):
        try:
            p1.append(pocker[m])
            p2.append(pocker[m+1])
            p3.append(pocker[m+2])
            p4.append(pocker[m+3])
        except:
            break
    #由小到大排序
    p1.sort()
    p2.sort()
    p3.sort()
    p4.sort()
    #逐一显示图片,其中1号和2号会发到14张牌
    for x in range(0,14):
        try:
            img=imgs[p1[x]]
            player1.append(cv.create_image((230+20*x,80),image=img))  #参数控制图片的位置和间隔
            img=imgs[p2[x]]
            player2.append(cv.create_image((100,150+25*x), image=img))
            img = imgs[p3[x]]
            player3.append(cv.create_image((230+20*x,500), image=img))
            img = imgs[p4[x]]
            player4.append(cv.create_image((600,150+25*x), image=img))
        except:
            pass    
    
    cv.pack()
    root.mainloop()
    

    图片在百度网盘

    链接: https://pan.baidu.com/s/1yHoQCTZ1sde-J3d3qnb4DQ?pwd=m28h 
    提取码: m28h  

    模拟结果如图:

    稍微改一改也可以用来模拟斗地主:

    再改一改也可以模拟狼人杀,逻辑比扑克牌简单多了,不需要排序,而且通常只有12张牌。成果如下:

    还可以改变一下布局,既然用的是网易的图片,那就和网易狼人杀的位置一样吧:

    如果想看发牌的动画效果,请参考下面的代码:

    from tkinter import *
    import random
    from PIL import Image, ImageTk
    import time
    n=12
    player2,player4=[],[],[],[]
    p1,p2,p3,p4=[],[],[],[]
    pocker=[i for i in range(n)]
    imgs=[]
    root=Tk()
    cv=Canvas(root,bg="White",width=400,height=600)
    for i in range(1,13):
        imgs.insert(i,ImageTk.PhotoImage(file="img/"+str(i)+".gif"))
    
    #洗牌(用随机交换打乱牌序)
    def gen_pocker(n):
        x=10
        while(x>0):
            x=x-1
            p1=random.randint(0,n-1)
            p2=random.randint(0,n-1)
            t=pocker[p1]
            pocker[p1]=pocker[p2]
            pocker[p2]=t
        return pocker
    #发牌    
    def mm():
        global p2,p4  #list本身虽然是全局变量,但如果不用global仅能修改元素,不能重新定义列表
        cv.deldete('all')
        p2,p4=[],[]
        pocker=gen_pocker(n)  #打乱后的牌组编号
        for m in range(0,12,2):
            try:
                p2.append(pocker[m])
                p4.append(pocker[m+1])
            except:
                break
    
    #先更新左边一列
    def ks(x):	    
        if x==0:
            mm()  	
        img=imgs[p2[x]]
        player2.append(cv.create_image((100,50+100*x), image=img))
        x+=1
        #从第七张开始更新右边一列
        if x==6:
            x2=0
            root.after(500,ks2,x2)
            return
        root.after(500,ks,x)
    #更新右侧一列
    def ks2(x2):
        img = imgs[p4[x2]]
        player4.append(cv.create_image((320,50+100*x2), image=img))
        x2+=1
        #最后一张之后结束
        if x2==6:
            return
        root.after(500,ks2,x2)
    
    button = Button(root, text ="发牌", width=10,height=1,command = lambda:ks(0))
    button.place(x=170, y=260) 
    
    cv.pack()
    root.mainloop()
    

      

    这样就能实现动态发牌的效果了:

     

    什么?边角位真的总有狼?

    有了这个程序,手上没牌也能模拟发牌、研究位置学了。

     

    删除canvas创建的组件方法:在定义时加一个tags属性,然后用delete删除,例如:

    cv.create_image((100,100), image=img,tags='o')
    cv.delete('o')
    

      

    最后为喜欢玩狼人杀的小伙伴们送上一则位置学攻略吧——

    好好听发言。

  • 相关阅读:
    建表
    第5讲:控制语句
    第4讲:函数
    第1讲:面向对象
    野路子小白安装黑苹果 OpenCore引导 @a.宏万
    野路子学习esp32(十九)ESP32-Arduino 第二篇 智能孵化器 @a.宏万
    野路子学习esp32(十八)ESP32-Arduino 第一篇 @a.宏万
    野路子学习esp32(十七)ESP32-MicroPython OLED AND DHT11 @a.宏万
    野路子学习esp32(十六) MQTT与ESP32-MicroPython @a.宏万
    野路子学习esp32(十五) 1z实验室 EMP项目@a.宏万
  • 原文地址:https://www.cnblogs.com/Skypeduty1225/p/16259293.html
Copyright © 2020-2023  润新知