import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class LaiZiTingPai {public static void main(String[] args) {}/*** @param mah 整副牌* @param laiZi 癞子的那张牌* @return*/public boolean myLaiZiTingPai(List<Integer> mah,Integer laiZi) {return laiZiCanHu(mah,laiZi);}// 癞子是否可以胡public static boolean laiZiCanHu(List<Integer> mah, Integer laiZi) {List<Integer> pais = new ArrayList<Integer>(mah);// 先排序Collections.sort(pais);if (pais.size() == 2) {if (pais.get(0) == pais.get(1)) {return true;}if (pais.contains(laiZi)) {return true;}return false;}int laiZiNum = 0;for (Integer integer : pais) {if (integer == laiZi) {laiZiNum++;}}for (int i = 0; i < laiZiNum; i++) {pais.remove(laiZi);}// 依据牌的顺序从左到右依次分出将牌for (int i = 0; i < pais.size(); i++) {int myLaiZiNum=laiZiNum;List<Integer> paiT = new ArrayList<Integer>();paiT.addAll(pais);// 第一个牌Integer currentPai = paiT.get(i);int count = getPaiNum(paiT, currentPai);// 如果只有一个数量(1.癞子 2.普通牌)// 如果不只一个数量(1.癞子 2.普通牌)if (count >= 2) {paiT.remove(currentPai);paiT.remove(currentPai);} else {if (currentPai == laiZi) {// 癞子(只有一个数量是凑不成对子的)continue;} else {// 不是癞子myLaiZiNum--;paiT.remove(currentPai);paiT.remove(laiZi);}}List<Integer> arrayList = new ArrayList<>();if(HuPaiPanDin(paiT, arrayList, myLaiZiNum, paiT.size(), 0)){return true;}}return false;}// 胡的是正常的刻顺胡// 递归后的麻将,paiSize去除癞子后的牌的数量,当前达到的位置private static boolean HuPaiPanDin(List<Integer> mahs, List<Integer> leftPais, int laiZiNum, int paiSize,int currentIndex) {//System.out.println("mahs"+mahs+" leftPais"+leftPais+" laiZiNum"+laiZiNum+" paiSize"+paiSize+" currentIndex"+currentIndex);if (mahs.size() == 0&&leftPais.size()==0) {return true;}// 说明已经遍历结束了,但是还未能成功,就必须要走癞子流程if (paiSize == currentIndex) {return HuPaiPanDinLaiZi(leftPais, laiZiNum);}Integer currentPai = mahs.get(0);int count = getPaiNum(mahs, currentPai);// 组成克子if (count == 3) {mahs.remove(mahs.get(0));mahs.remove(mahs.get(0));mahs.remove(mahs.get(0));return HuPaiPanDin(mahs, leftPais, laiZiNum, paiSize, currentIndex + 3);} else { // 组成顺子Integer left = mahs.get(0);if (left < 40) {// 万筒条Integer mid = left + 1;Integer right = left + 2;if (mahs.contains(mid) && mahs.contains(right)) {mahs.remove(right);mahs.remove(mid);mahs.remove(left);return HuPaiPanDin(mahs, leftPais, laiZiNum, paiSize, currentIndex + 3);} else {mahs.remove(left);leftPais.add(left);return HuPaiPanDin(mahs, leftPais, laiZiNum, paiSize, currentIndex + 1);}} else {mahs.remove(left);leftPais.add(left);return HuPaiPanDin(mahs, leftPais, laiZiNum, paiSize, currentIndex + 1);}}}// 胡的是有癞子的刻顺胡,癞子要进行一个万能牌填充(这个才能进行癞子的补充)public static boolean HuPaiPanDinLaiZi(List<Integer> leftPais, int laiZiNum) {if (laiZiNum < 0) {return false;}if (leftPais.size() == 0) {return true;}Integer currentPai = leftPais.get(0);    if (currentPai < 40) {// 小于40// 未完成的顺子或者对子,需要减去一张癞子,否则减去两张癞子int num = getPaiNum(leftPais, currentPai);if (num == 2) {// 有对子leftPais.remove(currentPai);leftPais.remove(currentPai);laiZiNum -= 1;return HuPaiPanDinLaiZi(leftPais, laiZiNum);} else {leftPais.remove(currentPai);Integer mid = currentPai + 1;Integer right = currentPai + 2;if (leftPais.contains(mid) || leftPais.contains(right)) {// 有完成一半的顺子if (leftPais.contains(mid)) {leftPais.remove(mid);}if (leftPais.contains(right)) {leftPais.remove(right);}laiZiNum -= 1;} else {laiZiNum -= 2;}return HuPaiPanDinLaiZi(leftPais, laiZiNum);}} else {//风牌  未完成的对子,需要减去一张癞子,否则减去两张癞子 int num = getPaiNum(leftPais, currentPai);if (num == 1) {leftPais.remove(currentPai);laiZiNum -= 2;}if (num == 2) {leftPais.remove(currentPai);leftPais.remove(currentPai);laiZiNum -= 1;}return HuPaiPanDinLaiZi(leftPais, laiZiNum);}}// 排完序后获取数量public static int getPaiNum(List<Integer> pais, int nowPai) {int beginIndex = pais.indexOf(nowPai);int lastIndex = pais.lastIndexOf(nowPai);return lastIndex - beginIndex + 1;}}

癞子胡牌(听牌)算法相关推荐

  1. erlang实现麻将胡牌以及癞子胡牌算法

    判断胡牌 麻将胡牌其实是按照nAAA + mABC + DD的套路,算法判断也很好实现,找出DD,然后剩下的牌都能形成AAA或者ABC即可胡牌.本文只介绍麻将普通胡牌的算法,该算法经过验证可判断除特殊 ...

  2. 棋牌麻将 - 无癞子胡牌算法

    基础知识 本文涉及的所有名词均在博文中有说明: http://blog.csdn.net/kunyus/article/details/78644517 核心思想 去除杂念: 由于字牌中只只允许出现 ...

  3. C++带赖子的麻将听牌检测算法实现

    #include <iostream> #include <vector> #include <set> #include <algorithm>enu ...

  4. 棋牌麻将 - 无癞子胡牌算法(第三版)

    基础知识 本文涉及的所有名词均在博文中有说明: http://blog.csdn.net/kunyus/article/details/78644517 测试结果 测试环境: MEM: 4 GB CP ...

  5. 棋牌麻将 - 无癞子胡牌算法(优化)

    基础知识 本文涉及的所有名词均在博文中有说明: http://blog.csdn.net/kunyus/article/details/78644517 核心思想 去伪存真: 满足胡牌的部分, 要么是 ...

  6. 癞子麻将胡牌以及听牌算法实现

    最先实现的就是算法的实现. 需求:碰杠胡  ,不能吃 ,不能听 ,只能自摸胡,其中癞子可以做任意牌但是不能碰和杠. 写的时候还不会玩麻将,还是老板教的.^_^ 最麻烦的是胡牌算法.之前搜到的都是不包含 ...

  7. 麻将胡牌算法lua 不支持癞子

    --[[ file:game\lualib\mahjongHelper.lua desc:麻将辅助 + 胡牌 + 听牌 算法 auto:Carol Luo ]] local ipairs = ipai ...

  8. 癞子麻将胡牌算法实现

    最先实现的就是算法的实现. 需求:碰杠胡  ,不能吃 ,不能听 ,仅仅能自摸胡,当中癞子能够做随意牌可是不能碰和杠. 写的时候还不会玩麻将,还是老板教的.^_^ 最麻烦的是胡牌算法.之前搜到的都是不包 ...

  9. swift--广东麻将v2.0(带胡牌、听牌算法和自动打牌功能)

    本程序实现了广东麻将的全部功能:自动摸牌.打牌.碰.杠.听牌.胡牌(其中庄家手动打牌,其它电脑玩家自动打牌),具体功能有: 系统通过骰子确定庄家,然后发牌,最开始从庄家手动打牌. 可以碰,杠,不能吃牌 ...

最新文章

  1. 抽象类注意事项(面试常常涉及)
  2. 维度变换--首先将矩阵倒过来
  3. CSS浮动和清除浮动
  4. CNCF 宣布 Helm 成为基金会下一个重点孵化项目
  5. PID算法-温度控制
  6. boost::mpl::times相关的测试程序
  7. how does SAP UI5 filter for list work in xml view
  8. red hat 4.1.2_安装Red Hat Container Development Kit 2.2版本
  9. java 交集怎么写_Java里面如何求两个集合的交集
  10. 同步、异步事件循环(宏任务、微任务「大厂真题解析」)
  11. 深入理解Java堆内存分配策略(Xmx和Xms)
  12. mysql 版本_mysql各个版本介绍
  13. 关于SBUS信号在单片机中的一些个人理解
  14. 《数字电子技术基础》6.3 时序逻辑电路——寄存器、计数器及脉冲发生器功能介绍
  15. Java对接支付宝的支付、退款、提现
  16. 飞秋远程可利用0day 的详细分析和利用方法 飞秋漏洞
  17. Python百宝箱密码锁升级版源代码
  18. 如何写好软件项目的工作计划(一)
  19. Oracle Docker 镜像(制作)
  20. 中国都市女性抗衰洞察:Z世代抗衰意识普遍觉醒,“纹”题成抗衰重点

热门文章

  1. 常见横向控制算法的适用场景及其优缺点
  2. 富士康与华为发布昇腾智造AI质检示范产线;长江和记实业回应与尚乘数科无任何业务往来 | 美通企业日报...
  3. C#调用SSIS包(DTS)
  4. 场效应管质量的好坏简易判断选择
  5. DSDP140B 57160001-ACX
  6. github切换分支
  7. python 课程设计扫雷报告_用 Python 实现扫雷小游戏
  8. python 游戏扫雷_Python游戏:扫雷
  9. 红光光浴真的有用吗?#大健康#红光光浴#红光#种光光学
  10. 应急通讯华为完美版 Ubuntu linux GSMS软件ISO文件 2015最新升级版本