麻将胡牌判定的判定算法

问题背景 :

简化了麻将规则,给定[1s-9s],[1b-9b],[1t-9t]一共27种牌,每种牌都有4张。需要判断给定的牌是不是胡牌。

胡牌的定义为:

14张牌里面由一个对子,四个坎组成。其中对子代表两张一样的牌,坎代表三张一样的牌,或者三张连续的牌(连续指: 1s,2s,3s | 4t,5t,6t)

举例:

1s,1s,2t,3t,4t,2t,3t,4t,6b,7b,8b,5s,5s,5s就是胡牌。

思路1 搜索+剪枝:

step0:将牌排序

step1: 枚举所有的牌,假设当前枚举到的牌记作 {x},然后尝试获取第2个x(/*如果没有则失败*/). 同时将2个x从手牌集合去除

step2: 枚举所有的顺子(连续的牌).枚举顺子实际上是枚举顺子中最小的那个元素y,因为其他元素可以通过y+1,y+2来表示。并且从集合里面取出y,y+1,y+2;
    为了保持搜索的时候做到 /*不重不漏*/,从顺子里面最小的开始搜索,也就是说,这一次枚举了顺子 y+1,y+2,y+3,那么在接下来的递归搜索里,枚举的顺子最小元素一定从 {大于等于} y的元素开始;
    注意,如果y之后没有y+2了,那么就跳过(比如7s,8s,9s,1t,2t...),直接跳过8s,9s;

step3: 不停搜索顺子,直到
        case1:已经有四个了,当前状态已经满足,直接返回。
        case2: 已经没有顺子了,但是还没有四个坎,于是需要寻找三个一样的元素。判定剩下的牌是不是满足条件很简单,这里就不多言了。

优化1: 可以在去掉选中的顺子之后,提前评估一下当前的状态。如果任何一个元素的数量小于3,且不存在与其连续的其他元素,那么当前局面不可行,直接抛弃掉这个搜索。将这个评估函数记作`evaluate_state`.
    这个剪枝同样可以用在选中`对子`以后的评估。  
    优化2: 由于顺子只可能是相同种类的元素组成(1s,2t,3t是非法组合),所以我们可以将三种不同的种类分开处理。这样就将evaluate_state函数的检查范围缩小到一个种类的元素里面了。            
123456789101112131415

思路2: 打表+状态压缩

这个思路是针对有大量判定操作的需求来的。如果只有偶尔几次,不划算。
1

step1: 枚举所有的合法胡牌状态.这个做法并不难,将思路1里面的代码稍作修改即可。
step2: 对状态进行压缩。这里的压缩不是指对字符串进行压缩(比如将AAAABBBBCC -> 3A4B2C,然后用bit去表示3和A这种压缩),而是真正的减少状态的数量。
    2.1 为什么可以减少状态的数量?
    ans: 因为XXX ABC EFG MNP TT这种状态可以映射为很多胡牌原始状态,ABC可以替换为任何一个连续的顺子。TT可以替换为任何一个对子。
    2.2 怎么进行状态的压缩?
    ans: 很多人的直觉是对给定的状态转换成标准形式。然而,[转换到标准形式]这一步其实就是在判定是否胡牌,那么又回到了搜索的思路上去了。所以必须有一个快速的转换办法。实际上,可以考虑不使用标准状态,而使用一个更[压缩]的状态。
    2.3 更压缩的状态是什么?
    ans: 给定一个序列,对其进行排序得到有序集合 
    A = {1,1,1,1,2,2,2,2,3,3,3,3,9,9},可以压缩为 B = {4,4,4,2}.
    A' = {1,1,1,1,2,3,4,5,6,7,7,7,9,9},可以压缩为 B'={4,1,1,1,1,1,1,2,2}
    这就意味着:对于任何一种连续的序列,可以用连续的1来表示。对于相同的元素,用大于1的数字来表示。这就忽略了具体的元素,只考虑形式上的一致,同时是[排序后]的形式,这表示这里的2(9,9)可能可以映射为标准形式里面的1,2,3这种顺子的一部分,也可以映射为里面对子的一部分。而同样的标准型显然只有一种[更压缩状态]。
    2.4 怎么利用这种[更压缩状态]?
    有疑问是自然的,因为这种压缩虽然规避了[状态转换]这一步的困难(排序+遍历就可以搞定),但是损失了信息。也就是说给定状态即便在表里面,也未必是正确的的胡牌(很容易举出反例,这里省略)。所以我们需要补充信息。方法是将[更压缩形态]里面的分解模式记录下来(对于一种压缩状态,这样反变换的种类不会太多,同时注意去重)。即这种形态可以映射到哪些标准的形态。然后通过这种反变换,我们将给定的状态也变换到标准模式,看看满不满足胡牌的情景。
    这里给出一个例子,假设从标准状态A => [压缩状态]B,那么就在结果集合里面添加一个反映射表示S=[1,4,3,2,5,xx,xx...],它表示对B里面展开后的元素进行如S所示的shuffle(比如第二个元素放在第4个位置)就可以得到标准状态A。
    那么给定一个随机状态C,首先利用排序+转化变成状态B,然后检查状态B是否存在,若存在,获取所有模式反映射的表示,然后一一测试。由于变换到标准模式只是一次排序,而变幻后的模式非常容易测试是不是胡牌的,所以这个策略是可行的。
2.5 客户端的优化(提前过滤)
    由于这种压缩的状态其实占用内存很小,那么可以在客户端做一次提前检测,如果满足条件才向服务器进行二次测验(目的是防止别人修改客户端的代码,这样即使修改了也无法避开服务器的检测,所以修改没有意义)。
1234567891011121314151617

总结:这里有意思的新知识是:状态压缩可以通过这样巧妙的办法来避开,即可以快速转换到一个统一的形式,又不漏掉完整的信息。值得参考。
--------------------- 
作者:PYB不开心 
来源:CSDN 
原文:https://blog.csdn.net/pp634077956/article/details/79054531?utm_source=copy 
版权声明:本文为博主原创文章,转载请附上博文链接!

麻将胡牌判定的判定算法相关推荐

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

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

  2. C语言麻将递归,【算法SQL面试题】面试问题:麻将胡牌递归算… - 看准网

    麻将胡牌算法 运用递归思路,先找出两张一样的牌作将牌,然后在剩下的牌中找顺子和三个一样的牌,当剩余的牌数为0,则排定可以胡牌.目前只是四川麻将的赢牌番型,除去风牌的.可自行进行扩展.(万:11-19, ...

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

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

  4. Unity3D 通用麻将胡牌算法

    https://blog.csdn.net/qq_38064109/article/details/78933589 正常的麻将胡牌方式为满足N * ABC + M *DDD +EE 的形式,及存在一 ...

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

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

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

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

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

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

  8. 麻将胡牌算法的一种设计及其分析

    马勇波  陈欣庆 (解放军理工大学工程兵工程学院研究生二队,南京 210007)       摘  要  文章通过一个二维数组定义麻将的数据结构,并在此基础上设计了一种判断麻将是否胡牌的算法,该算法主 ...

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

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

最新文章

  1. ADODB.Connection 错误 '800a0e7a'
  2. 浅谈用原生 JS 模仿个Promise 的实现
  3. 前端框架Bootstrap 教程
  4. 3步告别忙累压力大没成绩
  5. Docker常用操作命令(一)
  6. 讯飞语音输入法免费版
  7. 电脑键盘下划线怎么打_电脑键盘失灵鼠标不动怎么办 键盘失灵鼠标不动解决办法...
  8. 9月书讯(下)| 开学季,读新书
  9. Git使用教程之初级入门命令行(二)
  10. Consul注册中心注册的服务总是红叉 (All service checks failing)
  11. canvas应用——圆角矩形图片
  12. MVC和MVT框架对比
  13. 为什么说C++太复杂(复杂到哪了?)
  14. 【Python】np.where()替换缺失值
  15. 二、基础SpringBoot2.0.0M4项目目录讲解
  16. PHY芯片88E1512之FPGA
  17. 第二十四章、 X Window 配置介绍
  18. win10win11win7打印机连接共享错误0x00709打印失败错误修复工具
  19. USB 2.0 A型、B型、Mini和Micro接口 type-c 定义及封装
  20. 使用IIS网址重写来阻止图像热链接,渗漏和邪恶Splogger

热门文章

  1. 2019盖茨年信,以及30个关于比尔盖茨的真相
  2. 香魂一缕随风散,愁绪三更入梦遥
  3. 地图软件OZI的使用:OZI for PC 入门(GPS地图绘制软件)
  4. [项目规范]JAVA WEB项目实施规范
  5. Fliqlo屏幕保护工具不能用了!!!
  6. Mangos付魔公式代码
  7. revit学习:Revit中如何部分剪切柱与梁?
  8. Vite 基本配置及原理
  9. MyCat的使用及其项目实战
  10. 网络安全--ESP8266烧录、测试、擦除WiFi杀手(详细教程、附所有工具下载地址)