Python设计诈金花游戏

诈金花游戏也叫做炸三张或者是三张牌,是风靡全球的一种比较流行的扑克牌游戏玩法,这种玩法比较简单,老少皆宜,受到了广大网友的喜爱。在诈金花游戏中,玩家想要取得胜利,要凭借自己的智慧和判断力。

一、规则

不同地区会有所不同。本篇以如下规则编写。

1、牌点大小

从大到小依次为:

A、K、Q、J、10、9、8、7、6、5、4、3、2

2、牌型

诈金花游戏中的牌型一般有6种,从大到小依次为:

1.豹子。也就是三张完全一样的牌,其中三个A是最大的,三个2是最小的。

2.顺金。即同花顺,指的是三张牌,上面的点数是连续排列的,而且花色相同。最大的牌型是AKQ,最小的牌型是A23。注意A使用了两次,AKQ中A权值最大,A23中的A权值最小(此时当1用)。

3.同花。指的是三张牌,花色完全相同。其中牌型最大的是AKQ,最小的是352。

4.顺子。指的是三张牌牌面上的点数是连续的,但是花色不同。其中AKQ最大,A23最小,A与顺金处理相同。

5.对子。指的是三张牌中有两张牌是一对,也就是点数相同。盘面最大的是AAK,最小的是223。当对子相当时比较单张。

6.单张牌。出现单张牌的情况下,最大的牌是AKJ,最小的是352。

7.当牌型和点数相同,以花式大小作为比较依据,花式从大到小依次为:

♦、

扑克牌花式输入码如下:

图1 Python处理扑克牌花式符号

也可以从Word中输入复制到Python。

插入→符号→“字体”选“Arial”然后选“子集”为“其他符号”,从中选取扑克牌花式符号(见图2)。

图2 在Word中输入扑克牌花式符号

二、玩法

1、诈金花游戏通常参与的玩家有2~6个人不等(一般5人)。

2、游戏所使用的扑克牌为一副扑克牌,除了大小王之外的52张牌,从庄家开始发牌,每名玩家三张牌。

3、按规则确定牌的大小,最大的为“赢”家。

三、思路

针对诈金花游戏这个问题,首先需要构造一副扑克牌,然后是发牌(本例是给每位玩家随机发三张,而不是按玩家发三轮)。

牌面排序,按'2'~'A'赋权值2~14,按权值排倒序,排序后的3张牌第1张赋权值100,第2张赋权值10,第3张权值为1。

牌面相同时按花式,牌面权值大于花式,所以花式权值赋小数,乘100后仍小于1,故取''为0.001, ''为0.002, ''为0.003, ''为0.004。

一级排序为牌型,按牌型大小赋值,'单张'为1, '对子'为2, '顺子'为3, '同花'为4, '顺金'为5, '豹子'为6。

各种排序权值保存在字典sort_dic中。

sort_dic = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14,

            '': 0.001, '': 0.002, '': 0.003, '': 0.004,

            '单张': 1, '对子': 2, '顺子': 3, '同花': 4, '顺金': 5, '豹子': 6}

四、解决方案

用13张牌和四个花式生成一副52张牌,然后用随机数模块的sample ()方法:

random.sample(puke, 3)

生成每位玩家的3张牌。

然后按牌面点数值+花式值生成牌面值,再按牌面值排倒序,对三张牌进行排序(此时按点数排、点数相同按花式排)。

需要对特殊的A32进行调整,原因是A32是最小顺子,此时A当1用,调整为32A,A的牌面点数值由14调整为1(A的牌面点数值-13)。

然后判断牌型,对于“对子”,如后2张为“对子”,需将单张调整到最后。

由于“同花”高于“对子”,所以先判是否为“同花”再着判“对子”,即“对子同花”按“同花”论。

最后以一位“牌型”+“第1张牌牌面值*100+第2张牌牌面值*10+第3张牌牌面值”生成排序码,以排序码排倒序,确定玩家排序,求出“赢”家。

具体代码如下:

#############################################
# 设计 Zhang Ruilin   创建 2022-11-29 17:21 #
# 诈金花:一位玩家3张牌,分豹子、同花顺 (顺 #
# 金)、同花、顺子、对子和单张,A最大,2最小 #
#############################################
import random

puke = []		# 存储扑克牌
num_lst = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
hua_lst = '♣♦♥♠'	# ['梅花', '方块', '红桃', '黑桃']

sort_dic = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,
            '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14,
            '♣': 0.001, '♦': 0.002, '♥': 0.003, '♠': 0.004,
            '单张': 1, '对子': 2, '顺子': 3, '同花': 4, '顺金': 5, '豹子': 6}
count_dic = {}		# 存储玩家排名

# 生成52张扑克牌
for hua in hua_lst:
    for num in num_lst:
        puke.append(hua + num)
player_dic = {'玩家1': [], '玩家2': [], '玩家3': [], '玩家4': [], '玩家5': []}

# 随机给五个玩家发牌
for key, value in player_dic.items():
    plate = random.sample(puke, 3)	# 从52张扑克中随机抽3张
    player_dic[key] = plate		# 发给指定玩家 
    for i in plate:
        puke.remove(i)			# 删除已发牌,以免重发

def sort_ret(_value):			# 对玩家的牌进行分析,生成排序码
    _lst = []				# 排序:第1个为排序码,后为(牌面, 分值)元组
    for i in _value: # i[1:]为点数,i[:1]为花式
        rec = sort_dic[i[:1]]+sort_dic[i[1:]]
        _lst.append((i,rec))
    _lst.sort(key=lambda x: x[1],reverse=True)
    if _lst[0][0][1:]+_lst[1][0][1:]+_lst[2][0][1:]=='A32':	# 最小顺子,A当1
        l = _lst[1:]
        l.append((_lst[0][0],float(f'{_lst[0][1]-13:.1f}')))
        _lst = l
    if _lst[0][0][1:] == _lst[1][0][1:] and _lst[1][0][1:] == _lst[2][0][1:]:
        _lst.insert(0,('豹子',sort_dic['豹子']))
    elif int(_lst[0][1]) == int(_lst[1][1])+1 and int(_lst[1][1]) == int(_lst[2][1])+1:
        if _lst[0][0][:1]==_lst[1][0][:1]==_lst[2][0][:1]:	# 顺金=同花顺
            _lst.insert(0,('顺金',sort_dic['顺金']))
        else:
            _lst.insert(0,('顺子',sort_dic['顺子']))
    elif _lst[0][0][:1]==_lst[1][0][:1]==_lst[2][0][:1]:
        _lst.insert(0,('同花',sort_dic['同花']))
    elif _lst[0][0][1:]==_lst[1][0][1:] or _lst[1][0][1:]==_lst[2][0][1:]:
        if _lst[1][0][1:]==_lst[2][0][1:]:	# 对子放前,单张调后
            l = _lst[1:]
            l.append(_lst[0])
            _lst = l    
        _lst.insert(0,('对子',sort_dic['对子']))
    else:
        _lst.insert(0,('单张',sort_dic['单张']))
    #s_result=f'{_lst[0][1]}{int(_lst[1][1]*10):03}{int(_lst[2][1]*10):03}{int(_lst[3][1]*10):03}'
    s_result=f'{_lst[0][1]}{int((_lst[1][1]*100+_lst[2][1]*10+_lst[3][1])*1000+0.5):07}'
    _lst.insert(0,s_result)		# 插入排序码,牌型+三张牌大小(同点按花式) 
    return _lst

if __name__ == '__main__':
    for key, value in player_dic.items():
        count_dic[key] = sort_ret(value)# 对牌面进行牌型分析和生成排序码
        print(key + "的牌为:", value)	# 输出各玩家的牌面
        # 对玩家按排序码进行排序,排序依据为sort_dic
        count_lst = sorted(count_dic.items(),key=lambda x: x[1], reverse=True)
    print("最终排名:")			# 输出玩家排名、牌型、排序后的牌面
    for i, v in enumerate(count_lst):
        print(v[0] + '\t', v[1][1][0] + '\t', v[1][2][0],v[1][3][0],v[1][4][0],
              '\t赢' if i == 0 else '')

部分运行实例见图3。

图3 部分运行实例

猜你喜欢

转载自blog.csdn.net/hz_zhangrl/article/details/130256105