之前用vba写过,当时的思路不清楚,也没有python这样强大的工具,写了好长时间。

现在想想,真的是太太太落后了。磨刀不误砍柴工,学习还是大有裨益的。

麻将和牌规则:

胡牌的基础牌型:(1)11、123、123、123、123(2)11、123、123、123、111(1111,下同)(3)11、123、123、111、111(4)11、123、111、111、111(5)11、111、111、111、111胡牌的特殊牌型:11、11、11、11、11、11、11(七对)

这里先判断7对的牌型,剩下的和牌牌型,包括基础牌型,也可以是吃碰之后的牌,所以数量可能少于14张。

为保证函数solid,成为不需要维护的代码,那么就需要进行参数检查。考虑数字是否在定义的规则范围内;考虑参数的数量是否合规;考虑参数是否包含一个必备选项:对子;考虑是否是特殊和牌类型:7对;常规和牌判断;

错误回顾:1,首次制作,未考虑到遍历完成,未和牌的情况,导致11,235,678 这样的未和牌的,没有返回数据。2,首次制作的时候,对于顺子的判断出现了错误。比如:112233,一个牌型可能有多张,排序完成后,123在数字上连续,但是位置上不一定相邻。所以不能直接用切片判断,应该用 a[0]+1 in a 这样的方式进行判断。3,和牌考虑是否超过了4张。

没想到做一个小的项目要考虑诸多问题,如何防止此类错误的发生?1,事先把限制条件都列出来,然后在做代码的时候,考虑进去,测试时再检查一遍。2,做分枝或判断时,要确定优先次序,彻底思考每一个步骤,是否考虑了所有的情况。
#coding='utf-8'
#author='小罗QQ1271801445'
#麻将胡牌算法
#判定规则:n*(abc)+m*(ddd)+ee
#特殊牌型:7*(ee),7对。##规则:
##胡牌的基础牌型:
##(1)11、123、123、123、123
##(2)11、123、123、123、111(1111,下同)
##(3)11、123、123、111、111
##(4)11、123、111、111、111
##(5)11、111、111、111、111
##胡牌的特殊牌型:
##11、11、11、11、11、11、11(七对)
#国士无双、十三幺九。由1筒(饼)、9筒(饼)、1条(索)、9条(索)、1万、9万、东、南、西、北、中、发、白十三种牌统称幺九牌。
#胡牌时这十三种牌某一种有两枚,而另十二种各一枚,共计十四枚,即构成十三幺。##其中:1=单张 11=将、对子 111=刻子 1111=杠 123=顺子##设计:
##牌型:万条饼,东西南北风,中发白。
##万:1-9
##条:11-19
##饼:21-29
##东西南北风:31,33,35,37
##中发白:41,43,45##这样定义,方便进行连续性计算,防止 东西南风,这样凑成一组牌。
##思路,先判断7对子,然后进行常规判断。遍历和剪枝。
##先找到数量大于等于2的牌,然后去掉,那么剩下的牌,要么连续的3张,或是相同的3张。
#3张相同的,肯定是相连的3张。
#3张连续的,可能是相邻的,也可能有跳跃,比如11,2222,33,结果是22,123,123,和牌成功。如果是只做相邻检测,则结果会不对。##为保证函数solid,成为不需要维护的代码,那么就需要进行参数检查。
##考虑数字是否在定义的规则范围内;
##考虑参数的数量是否合规;
##考虑参数是否包含一个必备选项:对子;
##考虑是否是特殊和牌类型:7对;
##常规和牌判断;
##
##错误回顾:
##1,首次制作,未考虑到遍历完成,未和牌的情况,导致11,235,678 这样的未和牌的,没有返回数据。
##2,首次制作的时候,对于顺子的判断出现了错误。比如:112233,一个牌型可能有多张,排序完成后,123在数字上连续,但是位置上不一定相邻。所以不能直接用切片判断,应该用 a[0]+1 in a 这样的方式进行判断。
##3,另外一个重大错误,举例:345,55,567,88,检查和牌项时,58都是和牌项,但是5明细已经没有牌了。所以要做数量的限制。##知识点:通过减少print,可以大幅度减少运行时间。import time,sys
import random #用于测试。
#公共参数,1套牌库,注意总共是4套。
pais=list(range(1,10))+list(range(11,20))+list(range(21,30))+list(range(31,38,2))+list(range(41,46,2))def hepai(a:list):'''Judge cards hepai. For excample:a=[1,2,3,4,4]a=list,万:1-9,条:11-19,饼:21-29,东西南北风:31,33,35,37,中发白:41,43,45。'''a=sorted(a)#print(a)#牌面检查,是否属于本函数规定的范围内。#pais=list(range(1,10))+list(range(11,20))+list(range(21,30))+list(range(31,38,2))+list(range(41,46,2))#print(pais)for x in set(a):if a.count(x)>4:#某张牌的数量超过了4,是不正确的。return Falseif x not in pais:print('参数错误:输入的牌型{}不在范围内。\n万:1-9,条:11-19,饼:21-29,东西南北风:31,33,35,37,中发白:41,43,45。'.format(x))return False#牌数检查。if len(a)%3!=2:print('和牌失败:牌数不正确。')return False#是否有对子检查。double=[]for x in set(a):if a.count(x)>=2:double.append(x)#print(double)if len(double)==0:#print('和牌失败:无对子')return False#7对子检查(由于不常见,可以放到后面进行判断)#对子的检查,特征1:必须是14张;特征2:一个牌型,有2张,或4张。特别注意有4张的情况。if len(a)==14:for x in set(a):if a.count(x) not in [2,4]:breakelse:
##            print('和牌:7对子。',a)return True#十三幺检查。if len(a)==14:gtws=[1, 9, 11, 19, 21, 29, 31, 33, 35, 37, 41, 43, 45] #[1,9,11,19,21,29]+list(range(31,38,2))+list(range(41,46,2)) #用固定的表示方法,计算速度回加快。#print(gtws)for x in gtws:if 1<=a.count(x)<=2:passelse:breakelse:print('和牌:国土无双,十三幺!')return True#常规和牌检测。a1=a.copy()a2=[] #a2用来存放和牌后分组的结果。for x in double:#print('double',x)#print(a1[0] in a1 and (a1[0]+1) in a1 and (a1[0]+2) in a1)
        a1.remove(x)a1.remove(x)a2.append((x,x))for i in range(int(len(a1)/3)):#print('i-',i)if a1.count(a1[0])==3:#列表移除,可以使用remove,pop,和切片,这里切片更加实用。a2.append((a1[0],)*3)a1=a1[3:]#print(a1)elif a1[0] in a1 and a1[0]+1 in a1 and a1[0]+2 in a1:#这里注意,11,2222,33,和牌结果22,123,123,则连续的3个可能不是相邻的。a2.append((a1[0],a1[0]+1,a1[0]+2))a1.remove(a1[0]+2)a1.remove(a1[0]+1)a1.remove(a1[0])#print(a1)else:a1=a.copy()a2=[]#print('重置')breakelse:#print('和牌成功,结果:',a2)return True#如果上述没有返回和牌成功,这里需要返回和牌失败。else:#print('和牌失败:遍历完成。')return False#单元测试:
#assert hepai([1,1,2,2,3,3,4,4,5,5,6,6,7,7])==True,'7对和牌'try:print('单元测试开始:',hepai([1,1,2,2,3,3,4,4,5,5,6,6,7,7])==True,#7对和牌。hepai([1,1,1,1,13,13,4,4,5,5,6,6,17,17]),#含4个一样牌的7对。hepai([1,9,11,19,21,29]+list(range(31,38,2))+list(range(41,46,2))+[29,])==True, #十三幺测试。hepai([1,1,2,2,2,2,3,3])==True,#不连续和牌。首次写的时候,这里给忽略掉了。hepai([1,1,1,2,2,2,3,3,3,4,5,17,18,19])==True, #正常和牌。hepai([18,18,31,33,35,31,31,33,33,35,35])==True, #东西南北风hepai([33,34,35,36,36])==False, #参数错误。hepai([1,2,3,4])==False, #数量不正确。hepai([1,2,3,4,5])==False, #无对子。hepai([1,1,2,3,5,6,7,8])==False) #遍历完成,不和牌。print('单元测试结束,如果有False,请检查。')print('*'*50)
except:print('运行测试未通过,请检查。')

 
运行结果:
和牌成功,结果: [(1, 1), (2, 3, 4), (2, 3, 4), (5, 6, 7), (5, 6, 7)]
和牌成功,结果: [(2, 2), (1, 2, 3), (1, 2, 3)]
和牌成功,结果: [(3, 3), (1, 1, 1), (2, 2, 2), (3, 4, 5), (17, 18, 19)]
和牌成功,结果: [(18, 18), (31, 31, 31), (33, 33, 33), (35, 35, 35)]
参数错误:输入的牌型不在范围内。
万:1-9,条:11-19,饼:21-29,东西南北风:31,33,35,37,中发白:41,43,45。
和牌失败:牌数不正确
和牌失败:无对子
和牌失败:遍历完成。
单元测试开始: True True True True True True True True
单元测试结束,如果有False,请检查。

转载于:https://www.cnblogs.com/guangzhao17/p/8167302.html

python麻将和牌算法相关推荐

  1. python联机麻将_python麻将和牌算法

    #coding='utf-8' #麻将胡牌算法 #判定规则:n*(abc)+m*(ddd)+ee #特殊牌型:7*(ee),7对. ##规则: ##胡牌的基础牌型: ##(1)11.123.123.1 ...

  2. 麻将胡牌算法带癞子 python实现

    姐姐:你去帮我和闺蜜打麻将? 学霸哥哥:可是我不会打麻将呀! 姐姐:你不是学霸吗?我教你一个麻将公式,我闺蜜可是单身哟! 学霸哥哥:什么公式? 姐姐:麻将胡牌公式: AAA*M+ABC*N+BB,WM ...

  3. python编程胡牌将是什么意思_python麻将和牌算法

    #coding='utf-8'#author='小罗QQ1271801445'#麻将胡牌算法#判定规则:n*(abc)+m*(ddd)+ee#特殊牌型:7*(ee),7对. ##规则:##胡牌的基础牌 ...

  4. 关于麻将和牌算法的那些事

    最近在玩雀魂majsoul,于是就迸发出用Unity写一款简单日标麻将的念头.麻将涉及到一些算法问题,现在我趁着热乎还没忘抓紧记录下来.在这里,麻将的规则不在赘述,只要达成3n+2=14即可用该算法判 ...

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

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

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

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

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

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

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

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

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

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

最新文章

  1. 简单图文配置golang+vscode【win10/centos7+golang helloworld+解决install failed等情况】
  2. Vector Clock理解
  3. Aasp.net前台调用后台cs变量
  4. 计算机浮点数运算误差与解决误差的算法
  5. 织梦模板不支持html,html中{}是什么样的模板?如何使用它?HTML5template模板标签是什么?html常用的字体样式是什么?dede后台文件为什么不能生成html?...
  6. 从Chrome源码看JS Array的实现
  7. PHP7.1 狐教程【旧】不在更新,请点击新连接查看
  8. 2019年泰迪杯技能赛A题心得
  9. 1279C. Stack of Presents
  10. Unity旋转基础——二维旋转与三维旋转
  11. css33d图片轮播_通过html+css3实现图片轮播切换
  12. Samba服务所使用的端口和协议
  13. 使用MATLAB计算一幅图像的熵
  14. C#访问网页、保存网页
  15. [Python从零到壹] 四十.图像处理基础篇之图像量化处理
  16. 什么是数据规约,数据规约的策略都有哪些
  17. 区块链智能合约教材出版
  18. blur表单验证方式
  19. JAVA——取输入范围在1-999内数字最大值,可自动排除无关项
  20. 串口通信与网口通信简介

热门文章

  1. 智慧厂务能源管理系统(FMCS)
  2. iphone怎么使用排水功能?这项功能在哪
  3. 用Python+OpenCV+PIL构建猫脸识别器
  4. 计算机知识枯燥乏味,中职计算机基础知识研究
  5. 测试数据科学家机器学习技能的40个问题
  6. Delphi复制HID、ID门禁卡源码
  7. Spring Boot 配置 HTTPS 的详细流程
  8. Python入门程序【九】
  9. Java包(package)的命名规范 规则
  10. CISP-PTE2021最新考试经验