一.说明
经常刷视频,看到一个有意思的项目,非常适合练手,今天这里我们实现炸金花的底层模拟。
二.游戏规则
- 1.一副扑克牌去掉大小王,剩下52张牌
- 2.参与游戏的玩家每人发三张牌
- 3.比较每个人手中牌的大小
- 4.若三张牌相同,则是豹子,豹子最大
- 5.若三张牌是同花顺,其次
- 6.若三张牌是顺子,但不是同花顺,再其次
- 7.若有两张牌相同,则是对子
- 8.若以上都没有,则是单子,单子中A最大
三.分析思路
实现炸金花的思路可以分为以下几个步骤:
- 定义扑克牌
首先需要定义一副扑克牌,包括52张牌,每张牌由花色和点数组成。可以使用列表或字典等数据结构来存储牌的信息。
- 洗牌
将牌洗乱,打乱顺序,保证每个人得到的牌是随机的。可以使用random库中的shuffle函数来实现洗牌。
- 发牌
将洗好的牌分发给玩家,可以根据玩家人数平均分配,每个玩家得到3张牌。
- 牌型判断
判断每个玩家手中的牌的牌型,例如三条、同花、顺子、同花顺、炸弹等。可以使用if语句和循环来实现牌型判断。
- 比较大小
比较每个玩家手中牌的大小,确定最终胜负。可以使用牌型和点数大小来进行比较。
- 结束游戏
当有一名玩家赢得游戏后,游戏结束,输出胜者信息。
以上就是实现炸金花的大致思路,具体实现过程中还需要考虑很多细节问题,如输入输出、异常处理等。
四.重要部分原理及实现
.构造牌
每张牌由两个部分:花色和数值构成,这样可以分别使用两个列表存储
list_colour=['♥','♣','♠','♦'] #构造花色 list_num=[2,3,4,5,6,7,8,9,10,'J','Q','K','A'] #构造值 list_card=[] #构造牌 def create_card(): for i in list_colour: for j in list_num: card=f"{i}{j}" list_card.append(card) return list_card
2.比对牌
炸金花中比对牌大小的函数需要考虑以下几个因素:
- 牌型:不同的牌型有着不同的大小关系,例如豹子最大,依次为顺金、金花、顺子、对子、单牌。
- 点数和花色:对于同一种牌型,点数和花色也有着大小的区别。如顺子和同花顺,若两人都是同样的顺子,则比较顺子的最大点数,点数大者胜;若两人都是同花顺,则比较花色,黑桃最大,方块最小。
- 牌面点数:在对子和单牌的情况下,需要比较牌面点数大小,点数大者胜出。
- 特殊牌型:特殊的情况下有特殊的大小关系。如三张2可以打过任意其他的牌型,但是仅三张2之间还存在大小关系。
因此,比对牌大小的函数可以通过以下步骤来实现:
- 判断两张牌的牌型,若不同则直接返回比较结果。若相同则进入下一步。
- 根据牌型的大小关系确定胜负。例如豹子最大,对子和单牌需要比较牌面点数,而顺子和同花顺需要比较最大点数和花色。
- 若牌型相同、点数或花色相同,则需要继续比较下一张牌的大小。这个过程可以使用递归来实现。
- 如果两手牌都是特殊牌型,则需要按照特殊牌型的大小关系来比较。
里面最难的问题就是怎么判断牌的大小,因为每种的牌不一致,我们这里采用权值的方式来实现。
#判断单子 def danzi(list): result=0.1*list[0]+1*list[1]+10*list[2] #[2,3,A]=143.2 [10,Q,K]=143 return result #判断对子 def duizi(list): if len(set(list))==2: #说明有对子 counts = Counter(list) most_common_element = counts.most_common(1)[0][0] #要知道重复的是哪个元素,这里元素的最大次数肯定是2 least_common_element = counts.most_common()[-1][0] #最少的元素既是单独的哪个元素 result=most_common_element*100+least_common_element*1 #最大单子:[J,K,A]=143.2,最小对子:[2,2,3]=203 return result else: return 0 #判断顺子 def shunzi(list): if (list[1]-list[0]==1) and (list[2]-list[1]==1): #说明有顺子 result=list[2]*300+list[1]*100+list[0]*10 #最小顺子:[2,3,4]=1520,最大对子:[K,A,A]=1413 return result else: return 0 #判断同花顺 def simlar_colour_shunzi(list1,list2): if (list1[1]-list1[0]==1)and(list1[2]-list1[1]==1): if list2[0]==list2[1]==list2[2]: reslut=list1[2]*1000+list1[1]*500+list1[0]*100 return reslut else: return 0 else: return 0 #判断豹子 def baozi(list): if list[0]==list[1]==list[2]: #最大同花顺:[Q,K,A]=21700,最小豹子:[2,2,2]=30000 result=list[0]*15000 return result else: return 0
五.python实现
import random from collections import Counter list_colour=['♥','♣','♠','♦'] #构造花色 list_num=[2,3,4,5,6,7,8,9,10,'J','Q','K','A'] #构造值 list_card=[] #构造牌 def create_card(): for i in list_colour: for j in list_num: card=f"{i}{j}" list_card.append(card) return list_card list_user=["张三","李四","王五","赵六"] #构造用户 #发牌 def fapai(): random.shuffle(list_card) #洗牌,打乱列表的顺序 user_cards = {} #可以使用字典存储每个用户的组 for i in list_user: cards = [] #值是一个列表对象 for _ in range(3): card = list_card.pop() #取出列表里面的最后一个元素并从列表删除 cards.append(card) user_cards[i] = cards #存放到值的列表中 return user_cards #改变部分牌的值 def change(a): if a=='J': a=11 if a=='Q': a=12 if a=='K': a=13 if a=='A': a=14 return a #判断单子 def danzi(list): result=0.1*list[0]+1*list[1]+10*list[2] #[2,3,A]=143.2 [10,Q,K]=143 return result #判断对子 def duizi(list): if len(set(list))==2: #说明有对子 counts = Counter(list) most_common_element = counts.most_common(1)[0][0] #要知道重复的是哪个元素,这里元素的最大次数肯定是2 least_common_element = counts.most_common()[-1][0] #最少的元素既是单独的哪个元素 result=most_common_element*100+least_common_element*1 #最大单子:[J,K,A]=143.2,最小对子:[2,2,3]=203 return result else: return 0 #判断顺子 def shunzi(list): if (list[1]-list[0]==1) and (list[2]-list[1]==1): #说明有顺子 result=list[2]*300+list[1]*100+list[0]*10 #最小顺子:[2,3,4]=1520,最大对子:[K,A,A]=1413 return result else: return 0 #判断同花顺 def simlar_colour_shunzi(list1,list2): if (list1[1]-list1[0]==1)and(list1[2]-list1[1]==1): if list2[0]==list2[1]==list2[2]: reslut=list1[2]*1000+list1[1]*500+list1[0]*100 return reslut else: return 0 else: return 0 #判断豹子 def baozi(list): if list[0]==list[1]==list[2]: #最大同花顺:[Q,K,A]=21700,最小豹子:[2,2,2]=30000 result=list[0]*15000 return result else: return 0 #测试代码 create_card() #初始化,生成牌 user_cards = {} user_cards = fapai() #发牌 print(user_cards) zuihou=[] for i in list_user: list=user_cards.get(i) #取出每张牌 a=list[0] b=list[1] c=list[2] card_a=(a[1:]) card_b=(b[1:]) card_c=(c[1:]) card_a = change(card_a) card_b = change(card_b) card_c = change(card_c) value=[int(card_a),int(card_b),int(card_c)] sorted_value=sorted(value) colour_a = (a[0:1]) colour_b = (b[0:1]) colour_c = (c[0:1]) colour=[colour_a,colour_b,colour_c] result1=danzi(sorted_value) result2=duizi(sorted_value) result3=shunzi(sorted_value) result4=simlar_colour_shunzi(sorted_value,colour) result5=baozi(sorted_value) result=[result1,result2,result3,result4,result5] zuihou.append(result) print(zuihou) jieguo1=sorted(zuihou[0]) jieguo2=sorted(zuihou[1]) jieguo3=sorted(zuihou[2]) jieguo4=sorted(zuihou[3]) a=jieguo1[4] b=jieguo2[4] c=jieguo3[4] d=jieguo4[4] value=sorted([a,b,c,d]) print(value) if value[3]==a: print(f"{list_user[0]}赢了") if value[3]==b: print(f"{list_user[1]}赢了") if value[3]==c: print(f"{list_user[2]}赢了") if value[3]==d: print(f"{list_user[3]}赢了")
六.实验结果