今天我們用tkinter的canvas畫布實現(xiàn)撲克牌的隨機發(fā)牌:將54張牌隨機發(fā)給四位牌手,在屏幕上顯示每位牌手的牌,利用Canvas將發(fā)牌結(jié)果顯示出來。
需要準備的是54張撲克牌的圖片(gif或者png,jpg的話要經(jīng)過額外的轉(zhuǎn)換),為了保證最終的牌序是按照由小到大排列的,圖片編號要按照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"))
#發(fā)牌,
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號會發(fā)到14張牌
for x in range(0,14):
try:
img=imgs[p1[x]]
player1.append(cv.create_image((230+20*x,80),image=img)) #參數(shù)控制圖片的位置和間隔
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()
圖片在百度網(wǎng)盤
鏈接: https://pan.baidu.com/s/1yHoQCTZ1sde-J3d3qnb4DQ?pwd=m28h 提取碼: m28h
模擬結(jié)果如圖:
稍微改一改也可以用來模擬斗地主:
再改一改也可以模擬狼人殺,邏輯比撲克牌簡單多了,不需要排序,而且通常只有12張牌。成果如下:
還可以改變一下布局,既然用的是網(wǎng)易的圖片,那就和網(wǎng)易狼人殺的位置一樣吧:
如果想看發(fā)牌的動畫效果,請參考下面的代碼:
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
#發(fā)牌
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)
#更新右側(cè)一列
def ks2(x2):
img = imgs[p4[x2]]
player4.append(cv.create_image((320,50+100*x2), image=img))
x2+=1
#最后一張之后結(jié)束
if x2==6:
return
root.after(500,ks2,x2)
button = Button(root, text ="發(fā)牌", width=10,height=1,command = lambda:ks(0))
button.place(x=170, y=260)
cv.pack()
root.mainloop()
這樣就能實現(xiàn)動態(tài)發(fā)牌的效果了:
什么?邊角位真的總有狼?
有了這個程序,手上沒牌也能模擬發(fā)牌、研究位置學了。
刪除canvas創(chuàng)建的組件方法:在定義時加一個tags屬性,然后用delete刪除,例如:
cv.create_image((100,100), image=img,tags='o')
cv.delete('o')
最后為喜歡玩狼人殺的小伙伴們送上一則位置學攻略吧——