Skip to the content.

简述

麻将作为国粹,为大众所喜爱,每个地区的玩法都不太一样,但是大部分都会有鬼牌,或者叫癞子,本文主要讲的是带多张鬼牌的胡牌算法。首先,简单说下麻将的基本概念。
github地址

使用

maven

<dependency>
    <groupId>com.github.esrrhs</groupId>
    <artifactId>majiang_algorithm</artifactId>
    <version>1.0.15</version>
</dependency>
// load
HuTableJian.load(Files.readAllLines(xxx));
HuTableFeng.load(Files.readAllLines(xxx));
HuTable.load(Files.readAllLines(xxx));
// check
boolean isHu = HuUtil.isHu(cards, gui);
List<Integer> tingCards = HuUtil.isTing(cards, gui);

花色分类

牌型术语

胡牌公式

鬼牌

鬼牌的定义就是能够变成任意牌的牌,通常是提前指定或者每次随机决定,比如白板做鬼,如下图:
image
此时白板可以变成3万,这手牌已经胡了。

遇到的问题

玩过麻将的人会知道,当鬼牌数目比较少时,看胡牌听牌还比较快,如果有多张鬼牌了,别人打一张牌,可能并不会很快的判断是否能胡,比如下图,当别人打了个6条,这手牌胡了吗?
image
实际上能胡的牌有
image
程序的计算也是同理,所以如果我们只是简单穷举鬼牌的变化可能性,再去计算是否胡牌,那么性能将会很低。本文的目的旨在优化此胡牌算法。

解决思路

既然穷举不行,那么我们提前计算好这手牌胡什么,到时候只需要查字典就知道胡的情况了,这个也就是查表法,即空间换时间。
当然,如果把所有牌一起查表,那样数据量又太大了。所以我们根据花色来分别查表,因为万筒条的数据,是一样的。

牌型编码

查表的第一步,要对手牌进行编码做key。

表生成

在生成表的阶段,时间是不值钱的,所以生成方法我们可以任意穷举。

胡牌算法

有了前面辛苦生成的表格,那么判断胡牌算法就很简单了。

查胡算法

其他