麻将胡牌算法-癞子牌特别多(一)
麻将内最核心的算法,每一次出牌,摸牌都需要使用到。(仅个人想法,想要更快速度,建用把算出来的结果存储下来,通过查表法来使用)
1、计算前准备
/*癞子数量*/protected byte laiNumber;/*癞子牌*/protected List<Byte> laiPoker;/*手牌数量总计*/protected byte pokerNumber;/*计算手牌*/protected byte[] handPoker;/*手牌包含的颜色*/protected List<Byte> colors;/*将牌信息*/protected List<JiangInfo> jiangPoker;/*胡牌可能性*/protected List<TingPossible> tingPossibles = new ArrayList<>();/*一种将牌找到的*/protected List<TingPossible> tingPossibleOne = new ArrayList<>();/*返回胡牌信息*/protected HuInfo huInfo = new HuInfo();
/*** 将牌信息*/public class JiangInfo{/*将牌*/byte jiangOne;byte jiangTwo;/*其中癞子数量*/byte tingNum;}
/*** 癞子牌变牌信息*/public class TingPossible{//剩余未变化癞子数量public byte laiNumber;//当前变化下的手牌public byte[] handPoker;//癞子已经变好的牌public List<Byte> changes = new ArrayList<>();public TingPossible (byte laiNumber,byte[] handPoker,List<Byte> changes){this.laiNumber = laiNumber;this.handPoker = handPoker;this.changes.addAll(changes);}}
/*** 胡牌计算信息*/public class HuInfo{//是否胡牌public boolean isHu;//胡牌可能性组合public List<byte[]> possibility = new ArrayList<>();}
/*** 计算胡牌变化可能性* @param onlyHu 仅判断胡牌* @return*/public HuInfo huInfo(byte[] handPoker,boolean onlyHu){this.handPoker = handPoker.clone();this.pokerNumber = (byte) handPoker.length;this.laiPoker = GameUtil.removeLaiPoker(this.handPoker,mjGame.specialClearn.guiMessage);this.laiNumber = (byte) this.laiPoker.size();this.colors = GameUtil.includeColor(this.handPoker,gamePlayer.playerSpecialClearn.chunk);......}
- 这是外部调用的接口
- 两参数:1、传入手牌。2、是否只是想知道可以胡牌(不考虑癞子牌具体变化)
- laiPoker 需要自定义算法(这个自己写,很简单的)。通过配置找出手牌中的癞子牌,存入laiPoker,并删除手牌this.handPoker中的癞子牌
- colors 自定义算法。存储手牌移除癞子牌后,包含到的花色。
2、花猪检查(排除特殊条件)
某些麻将规则,花色超过2种,不能胡牌。
//花猪,定缺检查if(colors.size() > HUA_ZHU_COLOR_NUM){return huInfo;}
3、七对检查(排除特殊条件)
//小七对检查if(qiXiaoDui(onlyHu) && huInfo.isHu){return huInfo;}
/*** 小七对检查*/protected boolean qiXiaoDui(boolean onlyHu){if(pokerNumber == 14){//对子数byte duiZhiNumber = 0;//癞子数量byte laiNumber = this.laiNumber;TingPossible possible = new TingPossible((byte) 0,null,new ArrayList<>());//查找已有的牌组合for(byte i = 1; i < mjGame.handPokerSize(); i ++){byte number = handPoker[(int)i];if(number > 0){boolean dan = number % 2 == 1;//单双判断double duoDui = Math.ceil((double) number/2);duiZhiNumber += duoDui;if(dan){laiNumber --;//用一张癞子牌固定变成该张单牌possible.changes.add(i);}}}if(laiNumber > 0){duiZhiNumber += laiNumber / 2;}if(duiZhiNumber == 7){if(!onlyHu){//癞子不变,查看是否能胡addNoChangeQXD(laiNumber);//查询多余癞子牌组合moreTing(possible,laiNumber);tingPossibles.add(possible);}return true;}}return false;}
/*** 癞子牌变牌信息* 表示癞子牌能胡的情况下,一种变化*/public class TingPossible{//剩余未变化癞子数量public byte laiNumber;//当前变化下的手牌public byte[] handPoker;//癞子已经变好的牌public List<Byte> changes = new ArrayList<>();public TingPossible (byte laiNumber,byte[] handPoker,List<Byte> changes){this.laiNumber = laiNumber;this.handPoker = handPoker;this.changes.addAll(changes);}}
protected void moreTing(TingPossible possible,byte laiNumber){//变已有的牌,数量小于等于2的牌if(laiNumber > 1){for(byte i = 1; i < mjGame.handPokerSize(); i ++){if(i != guiMessage.fanChose && laiNumber > 1){laiNumber -= addMoreTing(possible,i);}}}//癞子牌仍然有剩余,变已有颜色的牌(排除已有的牌)if(laiNumber > 1){for(byte pokerValue = 1; pokerValue < mjGame.handPokerSize(); pokerValue ++){if(handPoker[pokerValue] == 0){possible.changes.add(pokerValue);possible.changes.add(pokerValue);laiNumber -= 2;if(laiNumber > 1){possible.changes.add(pokerValue);possible.changes.add(pokerValue);laiNumber -= 2;}}}}}
- 7对是不同于正常胡牌的牌型,需要单独计算
- 需要满牌14长,不能有任何的碰、杠
- 组成7个对子就能胡牌。(需要分高,癞子牌这里就需要变成。1尽量相同的颜色,2四张相同的牌尽量多)
- 我这里是计算的最优组合,所有7对最终只会出现1个结果(就算1长普通牌,13长癞子牌。原则上不允许出现14长癞子牌)。
- handPokerSize 指我这里定义的手牌长度。下标1-9代表1-9条,11-19代表1-9筒,21-29代表1-9万,31-34代表东南西北,41-43代表中发白
- 先遍历普通牌,移除所有对子。如果是单长或3长,添加1张癞子牌(算2个对子)。
- 普通牌组合完毕,还剩余癞子牌,自动每两张算一个对子
- 癞子变牌计算(具体变成某一张牌,时分数最大化。)
- 其实这里只会涉及,普通牌组合完毕后,仍然剩余偶数的癞子牌。
- 优先组合,手上已经有1副对子的牌,变成4长一样的牌。(大多数麻将,这里都会有加分)
- 如果手牌全是4长一样的牌,则在手牌已有花色中,选手中没有的牌去变,组成一样的花色。(清一色一条龙)
麻将胡牌算法-癞子牌特别多(一)相关推荐
- erlang实现麻将胡牌以及癞子胡牌算法
判断胡牌 麻将胡牌其实是按照nAAA + mABC + DD的套路,算法判断也很好实现,找出DD,然后剩下的牌都能形成AAA或者ABC即可胡牌.本文只介绍麻将普通胡牌的算法,该算法经过验证可判断除特殊 ...
- python实现洗牌算法_洗牌算法及 random 中 shuffle 方法和 sample 方法浅析
对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章 <扫雷与 ...
- 随机洗牌算法+matlab,洗牌算法及 random 中 shuffle 方法和 sample 方法浅析
对于算法书买了一本又一本却没一本读完超过 10%,Leetcode 刷题从来没坚持超过 3 天的我来说,算法能力真的是渣渣.但是,今天决定写一篇跟算法有关的文章.起因是读了吴师兄的文章<扫雷与算 ...
- shuffle洗牌算法java_洗牌算法shuffle
洗牌算法 1. 背景 阿里的面试的时候做的一道笔试题:题目:写一个方法,入参为自然数n (n > 0),返回一个自然数数组,数组长度为n,元素为[1,n]之间,且每个元素不重复,数组中各元 ...
- 癞子麻将胡牌以及听牌算法实现
最先实现的就是算法的实现. 需求:碰杠胡 ,不能吃 ,不能听 ,只能自摸胡,其中癞子可以做任意牌但是不能碰和杠. 写的时候还不会玩麻将,还是老板教的.^_^ 最麻烦的是胡牌算法.之前搜到的都是不包含 ...
- 癞子麻将胡牌算法实现
最先实现的就是算法的实现. 需求:碰杠胡 ,不能吃 ,不能听 ,仅仅能自摸胡,当中癞子能够做随意牌可是不能碰和杠. 写的时候还不会玩麻将,还是老板教的.^_^ 最麻烦的是胡牌算法.之前搜到的都是不包 ...
- 分享一个麻将听牌算法(带癞子)(Lua)
算法已验证,目前没有发现问题,还有待优化,请指正(没有考虑东南西北中发白): M.CardTb = {{0,0,0,0,0,0,0,0,0}, --筒子{0,0,0,0,0,0,0,0,0}, --万 ...
- 癞子胡牌(听牌)算法
import java.util.ArrayList; import java.util.Collections; import java.util.List;public class LaiZiTi ...
- Unity3D 通用麻将胡牌算法
https://blog.csdn.net/qq_38064109/article/details/78933589 正常的麻将胡牌方式为满足N * ABC + M *DDD +EE 的形式,及存在一 ...
最新文章
- 律理(四)----关于“用韵的疏密和宽严”
- 二维平面内无人机的路径规划——势场法-改进
- 牛顿方法、指数分布族、广义线性模型—斯坦福ML公开课笔记4
- 如何无监督地获得一个句子的向量表示?
- Java 8 (10) CompletableFuture:组合式异步编程
- 农业银行数据库最佳实践和发展规划
- mysql分组查询统计求和
- php 控制台打印_php调试利器:FirePHP的安装与使用
- JavaWeb:HTTP、Request、Response
- IMPLEMENT_DYNCREATE(CFileView, CView)
- 创建Person接口(即“人”),它有setData()和getData()方法对“人”属性name、sex和birthday赋值和获得这些属性组成的字符串信息创建类Student实现Person接口
- unity如何实现图片透视_FPS透视自瞄从入门到入狱
- npi阶段是什么意思_NPI阶段发现的重要性论述
- 1076: 三位数求解-python
- leyou商城day7 构建商品索引库及查询
- Hadoop的原理是什么
- 自己动手实现音乐播放器app
- win7配置C语言VS2010,开发Windows7软件的绝配:Visual Studio 2010
- mysql 烂泥,烂泥:学习mysql的binlog配置
- 昨晚(2009-09-08),自己的第一个项目上线成功,踩个脚印