你好,我是在哥。
众所周知,扑克是家庭旅行、桌面朋友的必备单品。今天可以用python玩扑克游戏,比如炸金币。让我们来看看基本的游戏规则。(大卫亚设)。
炸(诈)金币又叫三张牌,是全国广泛传播的民间多卡游戏。游戏使用一副去除大小王的扑克,总共使用4个图案和52张牌,每个玩家从其中抽取3张牌来比较大小。各种牌型的大小顺序如下。(根据电热组合,出现的概率越低,败型分数奖就越大。):1、同花顺:3张相同花纹和圆点的连续卡片(如HART 2、HART 3、HART 4;2、豹:AAA、222等三分卡;3、顺子:3分连续卡,如心形2、黑桃3、方块4;4.金币:三张相同颜色的卡片,心形2,心形5,心形8;5.对:两个点的牌,如心形2、黑桃2;6、传单:2 ~ 10j q k a .下一个概率被百度百科截断。
注:本文介绍的游戏规则与实际不同,主要是基于不同卡类型的比较而设计的。
一、实施游戏过程
1、准备扑克。
在开始游戏之前,老师需要满足要求的扑克。卡片朋友都知道有以下四种图案。分别有A、2~10、J、Q、K等13张卡片。
suit=[‘黑桃’,‘HART’,‘盒子’,‘梅花’]
Num=[str (I) for I in range (2,11)] ['j ',' q ',' k ',' a']
为了便于后续计算,首先给每张传单相应的点数。
Score_map={} #单点映射表
For s in suit:
Count=2
For n in num:
Score_map[f'{s}{n}']=count
Count=1
扑克积分预览如下。
score _ map={ ' SPAD 2 ' : 2、' SPAD 3 ' : 3、' SPAD 4 ' : 4、' SPAD 5 ' : 5、' SPAD 6 ' :}
2、玩家入场。
用P1、p2等名字区分玩家,首先邀请5名玩家入场。
Players=[f' p {I}' for I in range (1,6)]
3、许可证。
使用玩家和扑克清单作为参数,传递给发卡商。发卡机不从扑克中再次取出,而是对每个玩家随机抽取3张卡片,写下玩家姓名和相应的卡片组。
Def get_pk_lst(pls、pks):
Result=[]
For p in pls:
Pk=样例(pks,3)
For _pk in pk:
(_pk)
Re ({'name' :p,' poker' :pk})
Return result
Pokers=li()) #移除大小国王的扑克
Poker _ grp=get _ PK _ lst (players,pokers) #许可证
许可预览如下:
Result=[{'name' :' P1 ',poker' : ['框5 ','梅花3 ','框a']},{'name
J']}, {'name': 'p5', 'poker': ['红心5', '梅花10', '黑桃A']}]4、判断牌型及算分
在算分之前先按之前的映射字典,将 pk_lst 里的 3 张扑克牌转换成对应的点数。
n_lst = list(map(lambda x: score_map[x], pk_lst)) # 点数映射
接下来截取花色部分的文本,利用集合去重后判断是否为三张同花。
same_suit = len(set([pk[:2] for pk in pk_lst])) == 1 # 是否同花色
再对点数部分进行排序,与依靠点数的最值生成的顺序列表进行比较,判断是否为连续的点数。要注意的是,A23 与 QKA 一样被视作顺子。
continuity = sorted(n_lst) == [i for i in range(min(n_lst), max(n_lst) + 1)] or set(n_lst) == {14, 2, 3} # 是否连续
别忘了考虑对子和豹子的检查方式。
check = len(set(n_lst)) # 重复情况
那么正式开始判断牌型和算分吧!首先是单张,非同花、非顺子、三张点数不一。得分以 3 个单张点数相加。
if not same_suit and not continuity and check == 3:
return sum(n_lst), "单张"
其次是对子,非同花,有且仅有两张点数一致。得分中对于构成对子的部分给予 2 倍奖励。
if not same_suit and check == 2:
w = [i for i in n_lst if n_l(i) == 2][0]
single = [i for i in n_lst if i != w][0]
return w*2*2 + single, "对子"
金花,即同花而非顺子,给予 9 倍奖励。
if same_suit and not continuity:
return sum(n_lst)*9, "金花"
顺子,即点数连续而非同花,给予 81 倍奖励。
if continuity and not same_suit:
return sum(n_lst)*81, "顺子"
豹子,即三张点数一致,这不得刷个 666 嘛。
if check == 1:
return sum(n_lst)*666, "豹子"
同花顺,同花色且点数连续,绝了,赌神一个技能 999 伤害。
if continuity and same_suit:
return sum(n_lst)*999, "同花顺"
5、决出胜负
一组玩家、抽牌、算分、牌型记录如下:
pk_grp = [{'name': 'p1', 'poker': ['方块5', '梅花3', '方块A'], 'score': 22, 'type': '单张'}, {'name': 'p2', 'poker': ['黑桃4', '方块8', '黑桃J'], 'score': 23, 'type': '单张'}, {'name': 'p3', 'poker': ['红心10', '红心K', '方块7'], 'score': 30, 'type': '单张'}, {'name': 'p4', 'poker': ['方块4', '梅花6', '方块J'], 'score': 21, 'type': '单张'}, {'name': 'p5', 'poker': ['红心5', '梅花10', '黑桃A'], 'score': 29, 'type': '单张'}]
利用 max 函数找出来谁是最棒的,公布名字!
best = max(pk_grp, key=lambda x: x["score"])["name"]
赢家是------ p3
好啦,又可以开始下一场愉快的游戏了~
二、统计及源码
1、牌型统计
进行了 10 万场游戏并对各类牌型进行频率统计,可见与前述排列组合的计算所得概率基本一致。
Counter({'单张': 371856, '对子': 84773, '金花': 24833, '顺子': 16239, '豹子': 1179, '同花顺': 1120})
单张频率:74.37%
对子频率:16.95%
金花频率:4.97%
顺子频率:3.25%
豹子频率:0.24%
同花顺频率:0.22%
2、牌局案例
各类牌型的局面和结果如下:
开牌结果------
{'name': 'p1', 'poker': ['方块5', '梅花3', '方块A'], 'score': 22, 'type': '单张'}
{'name': 'p2', 'poker': ['黑桃4', '方块8', '黑桃J'], 'score': 23, 'type': '单张'}
{'name': 'p3', 'poker': ['红心10', '红心K', '方块7'], 'score': 30, 'type': '单张'}
{'name': 'p4', 'poker': ['方块4', '梅花6', '方块J'], 'score': 21, 'type': '单张'}
{'name': 'p5', 'poker': ['红心5', '梅花10', '黑桃A'], 'score': 29, 'type': '单张'}
赢家是------
p3
开牌结果------
{'name': 'p1', 'poker': ['方块Q', '黑桃5', '黑桃K'], 'score': 30, 'type': '单张'}
{'name': 'p2', 'poker': ['黑桃2', '方块2', '红心10'], 'score': 18, 'type': '对子'}
{'name': 'p3', 'poker': ['梅花2', '黑桃4', '梅花J'], 'score': 17, 'type': '单张'}
{'name': 'p4', 'poker': ['红心K', '梅花7', '红心6'], 'score': 26, 'type': '单张'}
{'name': 'p5', 'poker': ['方块A', '方块6', '红心4'], 'score': 24, 'type': '单张'}
赢家是------
p1
开牌结果------
{'name': 'p1', 'poker': ['黑桃J', '黑桃5', '黑桃4'], 'score': 180, 'type': '金花'}
{'name': 'p2', 'poker': ['梅花7', '红心4', '梅花5'], 'score': 16, 'type': '单张'}
{'name': 'p3', 'poker': ['方块5', '黑桃9', '梅花10'], 'score': 24, 'type': '单张'}
{'name': 'p4', 'poker': ['黑桃Q', '梅花9', '黑桃10'], 'score': 31, 'type': '单张'}
{'name': 'p5', 'poker': ['红心9', '方块9', '红心A'], 'score': 50, 'type': '对子'}
赢家是------
p1
开牌结果------
{'name': 'p1', 'poker': ['方块8', '黑桃10', '方块9'], 'score': 2187, 'type': '顺子'}
{'name': 'p2', 'poker': ['梅花9', '红心Q', '黑桃3'], 'score': 24, 'type': '单张'}
{'name': 'p3', 'poker': ['方块A', '梅花K', '黑桃4'], 'score': 31, 'type': '单张'}
{'name': 'p4', 'poker': ['方块J', '红心J', '红心6'], 'score': 50, 'type': '对子'}
{'name': 'p5', 'poker': ['梅花5', '黑桃K', '方块3'], 'score': 21, 'type': '单张'}
赢家是------
p1
开牌结果------
{'name': 'p1', 'poker': ['黑桃Q', '黑桃8', '梅花6'], 'score': 26, 'type': '单张'}
{'name': 'p2', 'poker': ['红心3', '梅花3', '黑桃3'], 'score': 5994, 'type': '豹子'}
{'name': 'p3', 'poker': ['红心A', '红心6', '方块5'], 'score': 25, 'type': '单张'}
{'name': 'p4', 'poker': ['黑桃4', '梅花A', '方块2'], 'score': 20, 'type': '单张'}
{'name': 'p5', 'poker': ['梅花7', '黑桃6', '梅花8'], 'score': 1701, 'type': '顺子'}
赢家是------
p2
开牌结果------
{'name': 'p1', 'poker': ['黑桃5', '梅花9', '方块9'], 'score': 41, 'type': '对子'}
{'name': 'p2', 'poker': ['黑桃Q', '黑桃2', '红心Q'], 'score': 50, 'type': '对子'}
{'name': 'p3', 'poker': ['红心2', '黑桃7', '红心5'], 'score': 14, 'type': '单张'}
{'name': 'p4', 'poker': ['梅花3', '方块10', '黑桃A'], 'score': 27, 'type': '单张'}
{'name': 'p5', 'poker': ['黑桃9', '黑桃J', '黑桃10'], 'score': 29970, 'type': '同花顺'}
赢家是------
p5
3、完整代码
# @Seon
# 炸金花
from random import sample
from collections import Counter
def get_pk_lst(pls, pks): # 发牌
result = []
for p in pls:
pk = sample(pks, 3)
for _pk in pk:
(_pk)
re({"name": p, "poker": pk})
return result
def calculate(_score_map, pk_lst): # 返回得分和牌型
n_lst = list(map(lambda x: _score_map[x], pk_lst)) # 点数映射
same_suit = len(set([pk[:2] for pk in pk_lst])) == 1 # 是否同花色
continuity = sorted(n_lst) == [i for i in range(min(n_lst), max(n_lst) + 1)] or set(n_lst) == {14, 2, 3} # 是否连续
check = len(set(n_lst)) # 重复情况
if not same_suit and not continuity and check == 3:
return sum(n_lst), "单张"
if not same_suit and check == 2:
w = [i for i in n_lst if n_l(i) == 2][0]
single = [i for i in n_lst if i != w][0]
return w*2*2 + single, "对子"
if same_suit and not continuity:
return sum(n_lst)*9, "金花"
if continuity and not same_suit:
return sum(n_lst)*81, "顺子"
if check == 1:
return sum(n_lst)*666, "豹子"
if continuity and same_suit:
return sum(n_lst)*999, "同花顺"
def compare(_score_map, pk_grp): # 比大小
for p in pk_grp:
p["score"], p["type"] = calculate(_score_map, p["poker"])
print("开牌结果------")
for p in pk_grp:
print(p)
print("赢家是------")
best = max(pk_grp, key=lambda x: x["score"])["name"]
print(best)
return pk_grp
def show(_score_map, _players): # 开局
pokers = li())
poker_grp = get_pk_lst(_players, pokers)
return compare(_score_map, poker_grp)
def start_game(_score_map, _players, freq=1): # 游戏和统计
type_lst = []
for i in range(freq):
grp = show(_score_map, _players)
type_lst = type_lst + [t["type"] for t in grp]
c = Counter(type_lst)
print(c)
total = sum())
for item in c.items():
print(f"{item[0]}频率:{item[1]/total:.2%}")
if __name__ == '__main__':
# 准备扑克牌
suit = ["黑桃", "红心", "方块", "梅花"]
num = [str(i) for i in range(2, 11)] + ["J", "Q", "K", "A"]
score_map = {} # 单张点数映射表
for s in suit:
count = 2
for n in num:
score_map[f"{s}{n}"] = count
count += 1
# 5个玩家入场
players = [f"p{i}" for i in range(1, 6)]
# 开始游戏
start_game(score_map, players, freq=100000)
这里是水中滑翔者、鱼类按摩师,Seon塞翁,下一篇再见!