<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
炸金花
題目很簡單:就是自己寫一個程式,實現詐金花遊戲的發牌、判斷輸贏。
規則:
一付撲克牌,去掉大小王,每個玩家發3張牌,最後比大小,看誰贏。
牌型:
豹子:三張一樣的牌,如3張6.
順金:又稱同花順,即3張同樣花色的順子, 如紅桃 5、6、7
順子:又稱拖拉機,花色不同,但是順子,如紅桃5、方片6、黑桃7,組成的順子
對子:2張牌一樣
單張:單張最大的是A
版型大小順序: 豹子>順金>順子>對子>單張
從網上百科到的詐金花各種牌型的出現概率,一起放程序式碼中增加一點趣味小知識。你可能不知道豹子出現的概率比同花順大,實際打牌時同花順反而比豹子小;順子出現的概率比金花小,實際打牌時順子反而比金花小;最大牌為5、6、7的單張牌型出現的概率都要比金花和順子小,所以有的地方額外規定同一局中拿到“235”三張牌要比同局的豹子大。
回到正題,直接上程式碼,主要2個函數:一個計分、一個比大小
from random import shuffle as DealCards Players = 5 #人數 pkPacks = 1 #撲克副數 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 = '♠', '♥', '♣', '♦' P = [f+v for f in F for v in V]*pkPacks 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) if len(set(t))==1: return 500_0000+t[0] #豹子 elif len(set(t))==2: #對子 if t[0]==t[1]: #對子一樣大比較剩下的單張 return (100+t[1])*10000+t[2] else: return (100+t[1])*10000+t[0] else: if t[0]+1==t[1]==t[2]-1: if len(set(f))==1: return 400_0000+t[2] #順金(同花順) else: return 200_0000+t[2] #順子 else: if len(set(f))==1: return ((300+t[2])*100+t[1])*100+t[0] #金花 else: return (t[2]*100+t[1])*100+t[0] #單張 def WhoWins(P): Pokers,Winner = [],[] for i in range(0,3*Players,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]}") 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] print(f"【Player{idx+1} win!】--> {*Pokers[idx],} {pok}({per}%)n") return P[3*Players:] #去掉每一局已發的牌 if __name__ == '__main__': DealCards(P) #以隨機洗牌來模擬發牌 #Players = int(input('請輸入參加的人數?')) PlayersMax = 52*pkPacks//3+1 if not 0<Players<PlayersMax: print(f'請注意:參與人數的範圍 0 < Players < {PlayersMax} !') else: count = 1 while len(P)>=3*Players: #所有牌(52*PokerPairs)發不夠一局為止 print(f'第{count}局:') count += 1 P = WhoWins(P)
執行結果:
第1局:
Player1: ('♥Q', '♣2', '♣8') - 單張
Player2: ('♦T', '♥7', '♠6') - 單張
Player3: ('♣4', '♠4', '♦2') - 對子
Player4: ('♠5', '♠9', '♥6') - 單張
Player5: ('♠7', '♠3', '♣5') - 單張
【Player3 win!】--> ('♣4', '♠4', '♦2') 對子(16.94%)
第2局:
Player1: ('♥2', '♥8', '♦4') - 單張
Player2: ('♦9', '♦3', '♥A') - 單張
Player3: ('♠J', '♣A', '♦K') - 單張
Player4: ('♠8', '♥9', '♥T') - 順子
Player5: ('♣7', '♣9', '♣T') - 金花
【Player5 win!】--> ('♣7', '♣9', '♣T') 金花(4.96%)
第3局:
Player1: ('♦7', '♦J', '♠2') - 單張
Player2: ('♥J', '♦A', '♥K') - 單張
Player3: ('♥4', '♥5', '♦6') - 順子
Player4: ('♣Q', '♣J', '♠T') - 順子
Player5: ('♣K', '♦8', '♦5') - 單張
【Player4 win!】--> ('♣Q', '♣J', '♠T') 順子(3.26%)
擴充套件
學習要舉一反三,做完題目想到把這個程式的介面圖形化。無非就是把牌型對應列表下標從下圖中索引取出相應的圖片來對應到Image控制元件上;想要輸出的文字對應到text控制元件上;再整2個button控制元件繫結對應的事件動作。(程式碼中有第3個button是我測試用的)
牌型圖: Pokers.png
初始介面:
發牌介面:
開牌介面:
PokersV1.py 完整原始碼:
import tkinter as tk from PIL import Image,ImageTk from time import sleep from random import shuffle as DealCards Players = 4 #人數 pkPacks = 1 #撲克副數 isReady = True 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 = '♠', '♥', '♣', '♦' def loadCards(): infile = Image.open("pokers.png") Images = [] for j in range(4): image = [] for i in range(15): box = infile.crop((i*100,j*150,i*100+100,j*150+150)) img = ImageTk.PhotoImage(image=box) image.append(img) Images.append(image) infile.close() return Images def dealCards(): global cv,cards,isReady,P,Pokers if not isReady: return 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[0][0]) cv.update() sleep(0.5) for j in range(3): for i in range(4): cv.itemconfig(cards[i][j], image=Cards[1][0]) cv.update() sleep(0.3) if len(P)==0 or len(P)<12: P = [f+v for f in F for v in V]*pkPacks DealCards(P) isReady = False def playCards(): global cv,isReady,P,Pokers,cards,Cards if isReady: return P = WhoWins(P) for i,pok in enumerate(Pokers): for j,p in enumerate(pok): x = F.index(p[0]) y = V.index(p[1]) #print(x,y,'-',i,j) cv.itemconfig(cards[i][j], image=Cards[x][y+2]) cv.update() isReady = True 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) if len(set(t))==1: return 500_0000+t[0] #豹子 elif len(set(t))==2: #對子 if t[0]==t[1]: #對子一樣大比較剩下的單張 return (100+t[1])*10000+t[2] else: return (100+t[1])*10000+t[0] else: if t[0]+1==t[1]==t[2]-1: if len(set(f))==1: return 400_0000+t[2] #順金(同花順) else: return 200_0000+t[2] #順子 else: if len(set(f))==1: return ((300+t[2])*100+t[1])*100+t[0] #金花 else: return (t[2]*100+t[1])*100+t[0] #單張 def WhoWins(P): global cv,txt1,txt2,Pokers Pokers,Winner = [],[] for i in range(0,3*Players,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]}") 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" print(text1,'--> ',text2) cv.itemconfig(txt1, text=text1) cv.itemconfig(txt2, text=text2) return P[3*Players:] #去掉每一局已發的牌 def test(): global Pokers print("測試:",Pokers) if __name__ == '__main__': root = tk.Tk() root.geometry('1024x768') root.title('詐金花') cv = tk.Canvas(root, width=1024, height=680, bg='darkgreen') cv.pack() Pokers = [] Cards = loadCards() cards = [[None]*3 for _ in range(4)] P = [f+v for f in F for v in V]*pkPacks DealCards(P) x1, x2, x3 = 400, 80, 730 y1, y2, y3 = 100, 550, 320 dx1,dx2,dy = 105, 105, 0 imgxy = [[(x1,y1),(x1+dx1,y1),(x1+2*dx1,y1)],[(x3,y3),(x3+dx2,y3+dy),(x3+2*dx2,y3+dy*2)], [(x1,y2),(x1+dx1,y2),(x1+2*dx1,y2)],[(x2,y3),(x2+dx2,y3+dy),(x2+2*dx2,y3+dy*2)]] for x,lst in enumerate(imgxy): for y,coord in enumerate(lst): cards[x][y] = cv.create_image(coord, image=Cards[0][0]) cv.create_rectangle(coord[0]-50,coord[1]-75,coord[0]+50,coord[1]+75) tx,ty = coord[0]-100,coord[1]+92 cv.create_text(tx,ty, text=f'Player{x+1}', fill='white') btn = [None]*3 btn[0] = tk.Button(root,text='發牌',command=dealCards,width=10) btn[1] = tk.Button(root,text='開牌',command=playCards,width=10) btn[2] = tk.Button(root,text='測試',command=test,width=10) for i in range(3): btn[i].place(y=710, x=350+i*110) txt1 = cv.create_text(510,300, fill='red', font=("宋體", 16)) txt2 = cv.create_text(510,360, fill='red', font=("宋體", 10)) root.mainloop()
【編譯程式】
Windows的Cmd視窗中執行如下命令,Mac系統自行百度:
pyinstaller -F exam.py --noconsole
注意:記得把上面的牌型圖儲存為Pokers.png和程式碼放一起執行。
到此這篇關於Python實現帶圖形介面的炸金花遊戲的文章就介紹到這了,更多相關Python炸金花遊戲內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45