四川麻将胡牌算法

一、写在前面
川麻菜鸟(没错就是在下)打牌不行,弱点之一就是当牌型复杂(尤其是清一色)时不知道胡什么牌。这里用Python练习一下,判断给定的牌型是否听牌,以及听哪些牌。
二、不多BB,代码注释也懒得写,反正看不懂你也打不着我

wan = [int(i) for i in input('请输入"万"(以逗号间隔,若无请输入"0"):').split(',')]
tiao = [int(i) + 10 for i in input('请输入"条"(以逗号间隔,若无请输入"0"):').split(',')]
tong = [int(i) + 20 for i in input('请输入"筒"(以逗号间隔,若无请输入"0"):').split(',')]
#如果上面的交互输入方式太麻烦,改下面的列表中的数字吧。这样测试起来方便好多O(∩_∩)O~
'''
wan = [2,2,2,4,4,4,5,6,6,6,7,8,9]
tiao = [i + 10 for i in [0]]
tong  = [i + 20 for i in [0]]
'''
mahjong_1 = wan + tiao + tong
mahjong = [i for i in mahjong_1 if i not in [0,10,20]]
mahjong.sort()

class Mahjong:
    def __init__(self,mahjong,mahjong_1):
        self.mahjong = mahjong
        self.mahjong_1 = mahjong_1
    #判断输入的牌是否合法
    def Is_valid(self):
        if len(self.mahjong) % 3 != 1:
            return '你是怎么做到手里剩{}张牌的?'.format(len(self.mahjong))
        elif all([(0 not in self.mahjong_1), (10 not in self.mahjong_1),(20 not in self.mahjong_1)]):
            return "花猪了!"
        else:
            for x in set(self.mahjong):
                if self.mahjong.count(x) > 4:
                    return '你家麻将有{}张一样的牌?'.format(self.mahjong.count(x))
            else:
                pass
        return '老铁没毛病'
    #判断牌型是否胡牌
    def Judge(self,mahjong):
        double = [x for x in set(mahjong) if mahjong.count(x) >= 2]
        if len(double) == 0:
            return False
        if len(double) == 7:
            return True
        for i in double:
            mahjong_copy = mahjong.copy()
            mahjong_copy.remove(i)
            mahjong_copy.remove(i)
            for j in mahjong_copy:    
                if j != -1 and mahjong_copy.count(j) >= 3:
                    mahjong_copy[mahjong_copy.index(j)] = -1
                    mahjong_copy[mahjong_copy.index(j)] = -1
                    mahjong_copy[mahjong_copy.index(j)] = -1                
                elif ((j + 1) in mahjong_copy) and ((j + 2) in mahjong_copy):
                    mahjong_copy[mahjong_copy.index(j)] = -1
                    mahjong_copy[mahjong_copy.index(j + 1)] = -1
                    mahjong_copy[mahjong_copy.index(j + 2)] = -1
                else:
                    pass
            mahjong_copy = [i for i in mahjong_copy if i != -1]
            if mahjong_copy == []:
                return True
        return False
    #寻找在听的牌
    def Find_solution(self):
        self.solutions = []
        for i in range(1,30):
            if i not in [0,10,20,30]:
                mahjong_copy = self.mahjong.copy()
                mahjong_copy.append(i)
                if self.Judge(mahjong_copy) == True:
                    self.solutions.append(i)
	#前面将条、筒转化为了11-19,21-29区间的数字,便于判断,这里把他们变回来
    def Translate(self,mahjong):
        translate = []
        for i in mahjong:
            if 0 < i < 10:
                translate.append('{}万'.format(i))
            elif 10 < i < 20:
                translate.append('{}条'.format(i - 10))
            else:
                translate.append('{}筒'.format(i - 20))
        return translate
        
demo = Mahjong(mahjong, mahjong_1)
if demo.Is_valid() == '老铁没毛病':
    demo.Find_solution()
    print('您输入的牌是:')
    print(demo.Translate(mahjong))
    print('='*80)
    if len(demo.solutions) > 0:
        print('您可以胡的牌是:')
        print(demo.Translate(demo.solutions))
    else:
        print('还没有听牌!')
else:
    print('您输入的牌是:')
    print(demo.Translate(mahjong))    
    print('='*80)
    print(demo.Is_valid())

三、运行结果
把几个特殊情况都输一遍,测试正确!代码是写出来了,然而牌型复杂时我还是会不知道该胡什么牌,真是一个悲伤的故事。

您输入的牌是:
['2万', '2万', '2万', '4万', '4万', '4万', '5万', '6万', '6万', '6万', '7万', '8万']
================================================================================
你是怎么做到手里剩12张牌的?
您输入的牌是:
['2万', '2万', '2万', '4万', '4万', '4万', '5万', '6万', '6万', '6万', '8条', '3筒', '4筒']
================================================================================
花猪了!
您输入的牌是:
['2万', '2万', '2万', '2万', '2万', '4万', '5万', '6万', '6万', '6万', '7万', '8万', '9万']
================================================================================
你家麻将有5张一样的牌?
您输入的牌是:
['2万', '2万', '2万', '4万', '4万', '4万', '5万', '5万', '6万', '6万', '7万', '3筒', '3筒']
================================================================================
您可以胡的牌是:
['4万', '7万', '3筒']
您输入的牌是:
['2万', '2万', '2万', '4万', '4万', '4万', '5万', '6万', '6万', '6万', '7万', '8万', '9万']
================================================================================
您可以胡的牌是:
['3万', '4万', '5万', '6万', '7万']
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值