姐姐:你去帮我和闺蜜打麻将?

学霸哥哥:可是我不会打麻将呀!

姐姐:你不是学霸吗?我教你一个麻将公式,我闺蜜可是单身哟!

学霸哥哥:什么公式?

姐姐:麻将胡牌公式: AAA*M+ABC*N+BB,WMN可以为任意数,胡牌里面有且只有一对!

学霸哥哥:原来麻将还可以这样玩。好的 地址微信发给我,马上到!

通过这个对话,我想大家应该都能明白麻将的胡牌公式是怎么样了,如果只是简单的麻将胡牌,我想算法实现起来就比较的简单。

第一步:

我们挑出所有的对子(如果牌中一个对子就没有,那么就不能胡牌

第二步:

一次从牌里面去掉对子

第三步:

每次for循环跳3个数,看这3个数是否为ABC,AAA.如果都满足这样的条件,则这一副牌就可以胡牌。如果不满足这个条件,则没有胡牌。

这个我们用python实现算法就比较的简单,也比较的好理解。下面我们给出python的胡牌实现算法!这个里面多增加了一个7对的胡牌,大家可以看一下,看是否理解这个算法,也可以自己复制一下代码,跑一下看一下效果。

 def hupaiAlgorithm(self,handStr):a =handStr[:]if len(a) % 3 != 2:return Falsedouble = []for x in set(a):if a.count(x) >= 2:double.append(x)if len(double) == 0:return False#7对胡牌qidui = Trueif len(a) == 14:for x in set(a):if a.count(x) not in [2, 4]:qidui = Falsebreakelse:qidui = Falseif qidui:return True       a1 = a.copy()a2 = [] for x in double:a1.remove(x)a1.remove(x)a2.append((x, x))for i in range(int(len(a1) / 3)):if a1.count(a1[0]) == 3:a2.append((a1[0],) * 3)a1 = a1[3:]elif a1[0] in a1 and a1[0] + 1 in a1 and a1[0] + 2 in a1:  a2.append((a1[0], a1[0] + 1, a1[0] + 2))a1.remove(a1[0] + 2)a1.remove(a1[0] + 1)a1.remove(a1[0])else:a1 = a.copy()a2 = []breakelse:return Trueelse:return False

如果上面的胡牌算法理解了,那么恭喜你,你接下来就可以看一下带万能牌的四川麻将胡牌算法了!

最终的测试效果

首先我们来理解一下带万能牌的四川麻将如何才能胡牌,带完成牌的意思就是,万能牌可以代替任何一张麻将牌,只要最后的麻将能,满足那个公式就能胡牌。这个是重点,必须要理解这个重点,才能完成万能牌的胡牌算法!

我们结合上面正常麻将的胡牌思路,大家再想一想,如果正常牌不能胡牌,带万能牌能胡牌,是不是我们万能牌就只能代替下面3种情况才能胡牌:

我们看这手牌:112245777万能万能

1.当有2张牌不能成为ABC时,替换中间一张牌使牌成为ABC,比如45,万能牌变成345或者是456.

2.当牌中的对子>1,且不能满足7对胡牌的时候。万能牌代替牌中的任何一个对子,比如在我们举例的牌里面 万能牌就只能代替1或者是2. 

通过我们2万能牌的替换:

这手牌就变成了下面这种情况

112245777万能万能=》11122345777.

我们通过这样的变化,是不是就可以胡牌了。

3.当牌中没有一个对子的时候,万能牌就只能替换成其中的某一张牌,成为一个对子看是否满足胡牌的公式。

比如:1234567万能

这点万能牌就可以替换成1,4,7其中的任何一张牌,使牌变成:1123456,12344567,12345677.

万能牌能替换的这3种方式,这点大家有没有理解,如果理解了,接下来我们就可以来讨论,具体的算法怎么实现了。如果没有理解的同学,可以反复观看几次,必须要先理解这3点的替换思路才能够更好的理解算法。(这点我们不讨论7对的特殊胡牌算法)。

还有一点就是万能牌使用的次数只能小于等于万能牌的数量,这点也很重要。

通过上面的讲解我们就能很好的实现算法了,我们只需要在正常的胡牌算法里面改动一下就能实现万能牌的胡牌算法了。大体思路还是按照正常的胡牌算法来,只是在需要使用万能牌的时候,我们替换一下万能牌,然后把万能牌的数量-1,最后看使用万能牌的数量使用超过了已有的万能牌数量。里面增加一个7对的万能牌胡牌算法!

def hupaiAlgorithm(self,handStr,laziCnt):a =handStr[:]a2=handStr[:]if (len(a)+laziCnt) % 3 != 2:return False,a2double = []if laziCnt >0:for x in set(a): if x not in double:double.append(x)for x in set(a):if a.count(x) >= 2 and x not in double:double.append(x)if len(double) == 0:# print('和牌失败:无对子')return False,a2if laziCnt == 0:qidui = Trueif len(a) == 14:for x in set(a):if a.count(x) not in [2, 4]:qidui = Falsebreakelse:qidui = Falseif qidui:return True,a2       else:for card in a:cardArr=[[],[],[],[]]for card in a:iCnt = a.count(card)# print("iCnt:",iCnt,"handCards:",a)if card not in cardArr[iCnt-1]:cardArr[iCnt-1].append(card)if len(cardArr[0])+len(cardArr[2]) == laziCnt:huCard=[]for i in range(4):if i==0:huCard = huCard + cardArr[i]*2else:huCard = huCard + cardArr[i]*(i+1)huCard.sort()        return True,huCarda1 = a.copy()a2 = []  # a2用来存放和牌后分组的结果。for x in double:if x in a1:a1.remove(x)if x in a1:a1.remove(x)    a2.append((x, x))nUseLaziCnt =0index = 0isNohuCard = Falsewhile(len(a1)>0 and isNohuCard == False):a1Card = a1[0]if a1.count(a1Card)==3:a2.append((a1Card,) * 3)a1 = a1[3:] elif a1Card in a1 and a1Card + 1 in a1 and a1Card + 2 in a1 and( int(a1Card/10) == int((a1Card+1)/10) and int((a1Card+1)/10) == int((a1Card+2)/10)  ):  # 这里注意,11,2222,33,和牌结果22,123,123,则连续的3个可能不是相邻的。a2.append((a1Card, a1Card + 1, a1Card + 2))a1.remove(a1Card + 2)a1.remove(a1Card + 1)a1.remove(a1Card)elif((a1Card in a1 and a1Card+1 in a1 and (int(a1Card//10) == int((a1Card+1)//10))) or (a1Card in a1 and a1Card+2 in a1 and (int(a1Card//10) == int((a1Card+2)//10)) )) and (nUseLaziCnt<laziCnt):a2.append((a1Card, a1Card + 1, a1Card + 2)) if a1Card in a1: a1.remove(a1Card)if a1Card+1 in a1: a1.remove(a1Card + 1)if a1Card+2 in a1: a1.remove(a1Card + 2)nUseLaziCnt = nUseLaziCnt +1elif a1.count(a1Card)==2 and (nUseLaziCnt<laziCnt):a2.append((a1Card, a1Card, a1Card)) if a1Card in a1: a1.remove(a1Card)if a1Card in a1: a1.remove(a1Card)nUseLaziCnt = nUseLaziCnt +1    else:if len(a1)==1 and (laziCnt -nUseLaziCnt) ==2 :a2.append([a1Card]*3)if a1Card in a1: a1.remove(a1Card)else:   a1 = a.copy()a2 = []   isNohuCard = Trueif isNohuCard == False:return True,a2 else:return False,handStr 

算法里面有一个7对的胡牌算法:

这里来讲解一下如何实现的。7对胡牌,最后胡牌里面就是 全是对子 或者有4条。有且只有这2种牌型。我们就很好实现了,我们定义一个多维数组,一次记录牌出现1,2,3,4张的情况。我们只需要把出现一张牌的数量和3张牌的数量相加。2则是否刚好等于万能麻将的数量就可以了。

    for card in a:cardArr=[[],[],[],[]]for card in a:iCnt = a.count(card)# print("iCnt:",iCnt,"handCards:",a)if card not in cardArr[iCnt-1]:cardArr[iCnt-1].append(card)if len(cardArr[0])+len(cardArr[2]) == laziCnt:huCard=[]for i in range(4):if i==0:huCard = huCard + cardArr[i]*2else:huCard = huCard + cardArr[i]*(i+1)huCard.sort()        return True,huCard

你品,你细细品一下,看是不是这个道理。下面给大家看一个截图,带万能麻将的胡牌效率。

一个万能牌的情况,理论上4个万能和1个万能使用的时间差不多,都是毫秒级别的。如果这个四川万能麻将的胡牌算法,能满足一切的需求。

有了这个核心的胡万能牌算法,接下来得 听牌算法,是否胡万能的算法就很容易实现了!

麻将胡牌算法带癞子 python实现相关推荐

  1. 跑胡子胡牌算法(带赖子、基于回溯算法)

    跑胡子规则 跑胡子,小写"一"到"十"各4张共40张,大写"壹"到"拾"各4张共40张. 砌牌:跑胡子为3人同玩,庄家砌 ...

  2. 可带癞子的通用麻将胡牌算法

    本文原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章.觉得好的话,顺手分享到朋友圈吧,感谢支持. 笔者前段时间做过一款地方麻将 ...

  3. 麻将 胡牌 算法(任意癞子)

    分享一个麻将胡牌算法,支持多癞子,自己对麻将胡牌的理解写的一套快速识别胡牌逻辑,核心逻辑500行代码,仅对同条万进行处理,字花牌不包含在内,易理解,1M次随机胡牌牌型大概3秒左右.原创分享,我的算法也 ...

  4. 麻将胡牌算法 极速(速度接近理论极限)

    此麻将胡牌算法优点: 1.可处理多赖子牌(万能牌) 2.算法速度极快:1ms可大约计算1W+副手牌是否可胡(带赖子.0.08us左右),不带赖子的牌型更快.(最新版的算法速度感觉已很接近理论极限值) ...

  5. 麻将胡牌算法——C#

    这里只介绍普通的麻将胡牌算法,也就是7个对子或者 1个对子+3*N; N = 三个顺子或者三个一样的 ,其中字牌(东南西北中发白)不能算顺子. 首先对于每张牌 它有牌的的数字 1-9,牌的种类 (万条 ...

  6. 麻将胡牌算法(遍历+剪枝)

    麻将胡牌算法(遍历+剪枝) 简介 麻将胡牌算法及代码 1. 方法引入 2. 类型定义 2.1 牌定义 2.2 牌特征定义 3. 计算胡牌 3.1 检测十三幺牌型 3.2 检测七小对牌型 3.3 检测普 ...

  7. 麻将胡牌算法,带癞子

    貌似去年去面试一家公司,问了麻将的算法.虽然之前做过广东麻将,但是胡牌算法在服务端,就没有在意. 现在在网上搜了一些算法试了试 = =! 麻将普通的胡牌就是刻子+顺子+将.癞子可以充当任意一张牌. 参 ...

  8. 麻将胡牌算法-癞子牌特别多(一)

    麻将内最核心的算法,每一次出牌,摸牌都需要使用到.(仅个人想法,想要更快速度,建用把算出来的结果存储下来,通过查表法来使用) 1.计算前准备 /*癞子数量*/protected byte laiNum ...

  9. 包含癞子的麻将胡牌算法

    记录一下麻将的通用胡牌算法实现,只要满足M x ABC + N x DDD + EE 即可胡牌. 在这里先分析一下最简单的胡牌思路:先找出所有可能的将牌,若除去两张将牌之外的所有牌都能成扑,则可胡牌. ...

最新文章

  1. Asp.net实现直接在浏览器预览Word、Excel、PDF、Txt文件(附源码)
  2. springboot springcloud 热部署
  3. java猜单词游戏_序列应用——猜单词游戏
  4. 提高ASP.net性能的十种方法
  5. 力扣190.颠倒二进制数
  6. HttpClient-----待补充
  7. 宽带连接不上,拨号宽带连接的创建。
  8. linux中逻辑块大小为,Linux 文件系统相关的基本概念
  9. apache评分表的意义_APACHE-II评分表
  10. 【强烈推荐】Java入门基础笔记,超全!
  11. 怎么下载并使用向日葵远程工具
  12. 桌面路径多了一个计算机名,桌面文件放太多电脑变卡怎么办?一招将桌面文件路径改到D盘...
  13. Android用shape画个虚线
  14. yourshelf是什么意思中文_[英语shelf的中文是什么意思]英语shelf的中文是什么意思...
  15. WPF 实现无边框窗口两种方法
  16. IMSI号和IMEI解释
  17. Linux:VNC桌面锁屏问题处理
  18. uniapp手机验证码功能实现
  19. 单例模式(中):单例模式的弊端
  20. PDF 拆分为IMages

热门文章

  1. 如何批量在文件夹中建立php,怎样快速实现批量建立文件夹 电脑一次性快速批量新建多个文件夹的方法...
  2. 2021年转行产品经理十大常见问题汇总
  3. Did you install mysqlclient?
  4. 成功解决“You are using pip version 9.0.1, however version 19.1 is available.”的问题
  5. 数据分析师需要学习什么软件
  6. 古龙群侠传 服务器维护,【图片】【原创】古龙群侠传最全流程攻略~~【环家的那只熊吧】_百度贴吧...
  7. 金数据预约登记工具 引入医院信息管理部门
  8. msdn 系统工具下载
  9. 17.2.20 Sparsifying Neural Network Connections for Face Recognition 小感
  10. 警察蜀黍动真格,抓捕内鬼390余人、黑客近百人