炸金花
题目很简单:就是自己写一个程序,实现诈金花游戏的发牌、判断输赢。
(资料图片仅供参考)
规则:
一付扑克牌,去掉大小王,每个玩家发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=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炸金花游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?