记录一下麻将的通用胡牌算法实现,只要满足M x ABC + N x DDD + EE 即可胡牌。
在这里先分析一下最简单的胡牌思路:先找出所有可能的将牌,若除去两张将牌之外的所有牌都能成扑,则可胡牌。
将牌就是公式里唯一的对子EE、扑的意思是一套牌顺子ABC或者刻子DDD。
将牌的查找:遍历每张手牌,若有两张以上相同牌就能作将,或者用一张癞子凑也可。
接下来就只要判断一副牌是否成扑,伪码如下:
function isPu = (牌) { // 这里约定传入的牌是有序的、张数是3的倍数 if (没牌) { return true; } if (若第一张是顺子中的一张) { if (isPu(去掉该顺子剩下的牌)) { return true; } } if (若第一张是刻子中的一张) { if (isPu(去掉该刻子剩下的牌)) { return true; } } return false; }
只要思路清晰了算法就很简单,为什么只考虑第一张牌?其实函数内部递归调用了每张牌都会计算到的,除非没牌了。下面给出详细代码:
function isPu(cards, laizi) { if (cards.length == 0) { return true; } // 若第一张是顺子中的一张 for (var first = cards[0] - 2; first <= cards[0]; first++) { if(first % 10 > 7 || (laizi == 0 && first < cards[0])) { // 剪枝:顺子第一张牌不会大于7点、无赖子情况下顺子第一张只能用手上的牌 continue; } var shunCount = 0; for (var i = 0; i < 3; i++) { if (cards.indexOf(first + i) >= 0) { shunCount++; } } if (shunCount == 3 || shunCount + laizi >= 3) { // 找到包含第一张牌的顺子 var puCards = cards.slice(); var puLaizi = laizi; for (var i = 0; i < 3; i++) { var deletePos = puCards.indexOf(first + i); if (deletePos >= 0) { puCards.splice(deletePos, 1); } else { puLaizi--; } } if (isPu(puCards, puLaizi)) { // 剩下的牌成扑 return true; } } } // 若第一张是刻子中的一张 var keziCount = 1; var keziCard = cards[0]; if (cards[1] == keziCard) { keziCount++; } if (cards[2] == keziCard) { keziCount++; } if (keziCount == 3 || keziCount + laizi >= 3) { var puCards = cards.slice(); var puLaizi = laizi; for (var i = 0; i < 3; i++) { var deletePos = puCards.indexOf(keziCard); if (deletePos >= 0) { puCards.splice(deletePos, 1); } else { puLaizi--; } } if (isPu(puCards, puLaizi)) { return true; } } return false; }
下面是判断胡牌的函数:
function canHuLaizi(cards, laizi) { if ((cards.length + laizi + 1) % 3 != 0) { // 若牌张数不是2、5、8、11、14则不能胡 return false; } // 排序方便胡牌判断 cards.sort(function(a, b) { return a - b; }) // 依次删除一对牌做将,其余牌全部成扑则可胡 for (var i = 0; i < cards.length; i++) { if (i > 0 && cards[i] == cards[i - 1]){ // 和上一次是同样的牌,避免重复计算 continue; } if ((i + 1 < cards.length && cards[i] == cards[i + 1]) || laizi > 0) { // 找到对子、或是用一张癞子拼出的对子 var puCards = cards.slice(); var puLaizi = laizi; puCards.splice(i, 1); if (puCards[i] == cards[i]) { puCards.splice(i, 1); } else { puLaizi--; } // 删去对子判断剩下的牌是否成扑 if (isPu(puCards, puLaizi)) { return true; } } } if (laizi >= 2 && isPu(cards, laizi - 2)) { // 两个癞子做将牌 return true; } return false; }
这里做一下两个输入参数的说明:
// cards:手牌数组,不超过14张牌,每张牌由整数表示如下 // 条:1, 2, 3, 4, 5, 6, 7, 8, 9, // 万:11, 12, 13, 14, 15, 16, 17, 18, 19, // 筒:21, 22, 23, 24, 25, 26, 27, 28, 29, // 东南西北中发白:31, 41, 51, 61, 71, 81, 91, // // laizi:癞子数量,用整数表示
要做这个其实是因为维护的麻将老代码思路比较乱、代码不规范、效率比较低、维护比较难。好吧说了这么多其实就是我看不懂老代码,怕游戏上线了之后这块代码出了问题搞不定。
有关算法代码重构,这里有个小技巧:
使用随机生成的牌型数据,将新版本代码与老版本代码对比,当运算结果不一样时候可以快速的找出bug,也可以循环大量输入统计耗时比较效率。
通过这个手段解决了一些小问题,最终跑1000万次牌型输出结果一致,并且时间效率提高了好几倍,所以现在就可以安心的删掉了老代码 ^-^
相关推荐
golang版麻将胡牌算法,包含带癞子和不带癞子,将gui_index 设置为34 就是不带癞子的麻将胡牌算法,gui_index 设置为[0,34)就是带癞子的麻将胡牌算法
本项目主要探讨了如何使用C++语言实现麻将胡牌算法,包括普通胡牌规则以及特殊的“癞子”(也称为万能牌)胡牌规则。这里我们将深入解析这两种算法的核心原理。 首先,我们来看基础的麻将胡牌算法。麻将是一种四人...
麻将癞子胡牌算法,效率超快。4个5个癞子都测试过,python语言写的。
自己做的一个简单的C源代码麻将胡牌算法 分享给大家学习.
分享一个麻将胡牌算法,支持多癞子,自己对麻将胡牌的理解写的一套快速识别胡牌逻辑,核心逻辑500行代码,仅对同条万进行处理,字花牌不包含在内,易理解,1M次随机胡牌牌型大概3秒左右。原创分享,我的算法也许可以...
麻将癞子算法
mj_ai麻将AI算法基于多种方式实现麻将ai算法1、one_color_knn基于knn算法,选择与听牌表差异最小的目标进行凑牌2、probability基于概率计算与胡牌表,选择打出后胡牌概率最大的牌打出a、当前包含lua版和c语言版本。...
武汉麻将口口番胡牌的秘籍是指一种特殊的麻将玩法,核心是二五八、癞子、开口翻和口口翻。该游戏算番比较复杂,大赢还是大输就在一念之间。因此,麻友须要一边精确计算做大翻牌,一边提防放冲甚至不小心承包,玩法...
包含牛牛算法 结算配置自定义等,里面有测试类,包含牛牛算法 结算配置自定义等,里面有测试类包含牛牛算法 结算配置自定义等,里面有测试类包含牛牛算法 结算配置自定义等,里面有测试类包含牛牛算法 结算配置自定义...
斗地主算法完整版,包含二人三人四人玩法天地癞子玩法,如有修改意见,一起学习交流进步
【目标受众】: 本项目适合IT相关专业各种计算机技术的源代码和项目资料,如计科、人工智能、通信工程、自动化和电子信息等的在校学生、老师或者企业员工下载使用。 也适合小白学习进阶,可以用作比赛项目、可以进行...
4. **算法设计**:涉及到洗牌算法、发牌算法、判断胡牌条件的算法,以及计算得分的策略。 5. **并发编程**:如果游戏支持多人在线对战,可能涉及到线程同步与通信,确保游戏进程的正确性。 6. **数据存储与读取**...
原创分享一个长牌算包(判定牌是否满足最低胡牌要求)算法。该算法采用树结构,通过对指定的牌进行组合所有可能,找出最优解,核心算法700行左右。测试平局0.2ms一次,最耗时的组合是6与8的组合和7组合,如果该牌很...
因此,算法库必须具备高度的可配置性和适应性,以应对包含癞子万能牌的不同麻将游戏规则。这一功能的实现,进一步证明了算法库在面对不同麻将变种时的灵活性和高效性。 牌型判断是麻将游戏中算法库的另一项重要功能...
在标签中提到的“麻将”、“癞子”和“胡牌”是与游戏规则相关的词汇。在Cocos2dx游戏中,这些可能涉及游戏逻辑的实现。例如,“麻将”是一种典型的棋盘游戏,需要创建麻将牌的精灵,并用Cocos2dx的事件监听器处理...
1. 多样性:由于癞子的存在,牌型组合多样化,增加了AI算法的复杂性。 2. 实时性:游戏需要在短时间内做出决策,AI算法需兼顾效率和准确性。 3. 动态调整:AI需要根据对手的变化实时调整策略,这要求算法具备良好的...
最近网上源码难找了,在这里给大家提供一份癞子斗地主源码,可用的哦[img=http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/42.gif][/img]!!!在这里先上图给大家参考[img=...
本程序实现了除广东麻将的全部功能:自动摸牌、打牌、碰、杠、听牌、胡牌(其中庄家手动打牌,具体功能: 1.系统通过骰子确定庄家,然后发牌,最开始从庄家手动打牌。 2.可以碰,杠,不能吃牌;没有癞子。只能自摸。...
《24点游戏:探索“带癞子”规则的魅力》 24点游戏,一个深受人们喜爱的数学娱乐活动,其基本目标是通过加、减、乘、除运算,将四张扑克牌上的数字组合成24。然而,当加入“癞子”规则后,这个游戏的趣味性和挑战性...