1. 大众麻将规则描述
1.1. 游戏规则
牌库:只使用万,筒,条,点数分别为1至9 (如表1),总共108张牌。庄家起手14张牌,其他3位起手13张牌。打法:行牌过程,可吃、碰、杠和报听,并都可获得直接收益。胡牌方式:点炮,自摸,抢杠胡。
1.2. 番种介绍
1.2.1. 行牌番种
吃:只能吃上家牌,例如上家打出4万,自己手上有56万,则可以吃,凑成456万。
碰:当桌上其他玩家打出的牌与手牌可以构成碰牌时,则可以碰,例如玩家打出4万,自己手上有一对4万,则可以碰。
杠:分为直杠、补杠和暗杠。直杠指当玩家手里有刻子,其他玩家打出该刻子的第4张,进行开杠即为直杠;补杠:当玩家碰牌后,再抓到第4张并杠牌,即为补杠;暗杠:当玩家手牌有4张一样牌张时,进行开杠即为暗杠。
听:当手牌可以下叫时,玩家可选择是否报听。
1.2.2. 胡牌番种
基本胡:胡牌为全是顺子(包括吃)或者三个刻子(包括碰)加一对组成,例如234,678万,234条,567筒加66筒组成的胡牌就计基本胡。
碰碰胡:胡牌全是刻子加上一个对,例如222万,444条,777,999筒,外加22条。
清一色:胡牌只有条筒万中一个花色组成。
七对:胡牌的14张牌全是对子。
1.3. 对局和胡牌 [1]
对局的流程是4 位玩家分东南西北入座,每人起手摸13张牌,由“庄家”位玩家起手按顺时针出牌,“庄家”位玩家起手多摸一张牌,共计14张。行牌过程的优先级为:胡牌 > 杠 > 碰 > 吃。当有玩家成功胡牌,则牌局结束,当牌库中108张牌全部发完依然没有胡牌,则为流局。
2. 大众麻将博弈系统的结构设计
2.1. 博弈系统结构设计
大众麻将博弈系统主要由两个方面组成,博弈平台和博弈算法。麻将博弈系统的目的是让计算机能够像人一样进行分析、判断和做出决策的智能系统。博弈平台的主要功能是规则判断、信息显示和流程的运行等;博弈算法主要研究的是权值算法和搜索算法等工作。博弈算法是一个博弈系统中最为核心的部分,是一个博弈系统的关键,决定了整个系统的能力强弱。大众麻将博弈系统的两方面较为特殊,博弈算法包含在玩家的操作中,玩家同时处在博弈平台中。博弈系统架构如图1所示。
2.2. 功能性以及类的划分 [2]
本系统依据功能性划分为6部分,博弈平台包含历史信息统计系统,玩家类包含玩家反馈系统、权值系统与距胡数、搜索算法、行为设计。博弈平台的历史信息统计系统用以记录玩家操作。玩家反馈系统判断操作,权值系统与距胡数以及搜索算法用来实现智能出牌,行为设计实现玩家在对局中遇到的操作。
从整体架构以及功能性来看,设计三个类实现上述功能是最优的选择,这三个类分别是牌库类、玩家类、以及对局类(如图2)。牌库类包含一个二维数组表示的全体麻将牌个数,同时支持每次随机弹出一张牌模拟玩家请求抓牌的过程,玩家类关键部分为权值设置算法,为每张牌附上权值,以及各种可能的操作,对局类包含牌库类以及玩家类,通过实例化进行麻将的对局,包含历史信息系统用来判断是否有玩家胡牌。类图关系如图3所示,因功能过多,这里只画出关键部分。

Figure 2. Relationship between library, player and game
图2. 牌库类、玩家类和对局类的关系
3. 系统详细设计
3.1. 历史信息统计系统 [3]
牌局类中存在100行3列的二维整数类型history数组,该数组会对每位玩家产生的操作采用[玩家编号,操作名称,操作对象(某一张麻将牌)],操纵名称用数字进行区分:1——胡牌、2——自摸、3——碰牌、4——有吃操作、41——吃牌且操作对象在左侧、42——吃牌且操作对象在中间位置、43——吃牌且操作对象在右侧,5——杠牌(自己有三张,剩余一张被其他玩家打出)、6——暗杠、7——普通出牌、8——加杠(拿到了自己有碰操作的最后一张牌)。
3.2. 玩家反馈系统
当前出牌玩家完成出牌操作并被历史信息统计系统记录后,剩余三个玩家会对所出牌进行判断,检测自己是否有“操作”产生,若产生,则向系统发送申请,系统对收到的玩家申请进行二次判断,若无反馈信息,则“依次”出牌,若只收到一条反馈,则同意该反馈对应的玩家执行相应操作,若收到两条反馈则会出现两个玩家同时胡牌和“碰”操作,收到三条反馈则会有三个玩家同时胡牌、一个玩家胡牌一个玩家吃牌一个玩家碰牌和两个玩家胡牌一个玩家吃牌的情况,多种情况同时发生会根据优先级(胡牌 > 杠牌 = 碰牌 > 吃牌)的顺序仅确定玩家的一种“操作”执行,如图3。
3.3. 权值系统与距胡数
胡牌需要1个对子,4组刻子(3张相同的)或顺子(数字连续,花色相同的3张)组成。现定义一个概念:距胡数,顾名思义就是当前的手牌格局距离胡牌还需要几次有效的调整。
易知,任意一张牌为了组成顺子或者刻子,最多需要2步。4组刻字需要至少8个有效步,组成1个对子需要1步。因此,认为一副手牌距离胡牌需要9步。
权值即表现为距胡数。设置初始的距胡数为9。对所有手牌按照顺序进行运算,如果这张牌是孤立的(没有相邻或者相同的牌),距胡数不改变;如果只有一个相邻或相同的牌,则距胡数减1;如果可以与相邻的牌组成刻子或者顺子,即将距胡数减2。
例如手牌为:
1,4,6,9,9万;2,3,7,7筒;1,5,6,7,8条
计算过程为:遇到第二张九万时减1、遇到三筒时减1、遇到第二张七筒时减1、遇到六条时减1、遇到七条时减1,最后距胡数为4。
3.4. 操作设计
胡牌判断 [4]
除去特殊的牌型胡牌,可以发现所有的胡牌可以使用一个“三、三、三、三、二”的模型来判断,三代表顺子或者刻字,二表示将牌。具体算法是用3除手牌数量,在三种花色的手牌中有且仅有一种余数为2,其余全部为0的时候才能构成胡牌。对于余数为0的牌,可以分解成一个“刻”和“顺”的组合。当余数为“200”类型之后对每个类型的牌进行判断,首先对余数为2的类型的牌进行是否存在“刻”或“顺”的组合,具体操作为先去除将牌,然后对剩下的牌进行是否存在“刻”或“顺”的判断,做完判断之后对另外两个余数为0的类型的牌进行判断是否为顺子或刻子,如果三次判断之后均为“刻”或“顺”,则说明胡牌。
3.5. 搜索算法
搜算算法是博弈系统出牌舍牌的核心,本文提出了两种方案 [5]。
面向现在的权值。每次要出牌时,遍历每张手牌,模拟舍弃该手牌之后距胡数是否改变,选择出结果增大最多的手牌(也可能都没有增大,就选出减小最少的),说明该手牌对玩家胡牌所起到的作用最小。可以选择舍弃。
面向牌局接下来的走向。上面说的搜索算法只面向当前的手牌,可以预见效果可能不够优秀。因此提出面向牌局走向的递归搜索算法 [6]。
定义expect()函数模拟舍牌的搜索过程,伪代码:
For (int hand = 0; hand < 14; hand++)//hand指玩家自己的手牌
For(int lib = 0; lib < 27; lib++)//lib指牌库中剩余的牌
将编号为lib的麻将替换掉第hand张麻将
重新计算距胡数
expect (新的手牌)
下面是递归展开的树形结构示意(图4):
score是加权求所有分支的距胡数,距胡数的系数取决于牌库种对应牌的数量与牌库剩余牌数量之比。
最后选出平均距胡数最大的手牌,表明再未来2轮牌局进行中中,该手牌能带来的利益最小,最不能促进玩家胡牌。考虑到时间,递归不应该超过3轮,否则递归树的结构太大,运行所需时间较长。微软公司于2019年推出的一个名为Suphx的麻将人工智能系统,是世界上第一个达到10段水平的人工智能。Suphx不考虑对手的行为,只专注于寻找可能获胜的牌面。本文的系统同样只专注于减小距胡数,不考虑对手的行为。
相较于传统权值系统的权值,本文提出的距胡数数据量更小,结构更简单,一位玩家只需要一个变量存储距胡数,距胡数的修改操作较为简单。传统的权值系统需要为每一张手牌存储权值,权值的更改操作繁琐。同时传统的权值系统搜索算法主要采用Qlearning和Expextimax算法进行研究 [7] (图5),搜索结构复杂,要考虑的节点较多 [8]。
4. 实验结果与分析
本实验测试使用四个相同功能的玩家进行测试,同时因为当麻将的算法足够优秀的时候可以大幅减少出现流局的次数,而算法比较普通的时候流局的概率又比较高,所以选择的实验标准为固定次数模拟后的流局概率,通过流局概率的变化可以大致分析出相应的智能化程度。随后使用距胡数出牌策略与普通权值出牌进行胜率对比,每次测试1000局,三位选手采取普通权值出牌,一位选手采用基于距胡数改进的出牌策略。其中普通权值的胜利次数为三个普通权值出牌玩家的平均值。
默认顺序打牌为目前最为基础的麻将Ai,其实验中使用的出牌顺序为条,筒,万,同类型选择从数字大的开始出牌。

Table 3. Comparison of Hu card times
表3. 胡牌次数对比
由表2的数据可知,AI选择打牌的流局概率明显低于默认顺序打牌,可以证实本论文所述权值系统具有简单的AI功能,虽然流局概率仍然不够低,但仍然强于默认顺序打牌。
由表3的数据可以发现使用距胡数改进后的出牌策略要比普通权值AI的水平有大幅提高,由此可以知道使用距胡数进行麻将博弈的设计是可行的同时是有效的。
5. 结束语
非完全信息博弈是一个复杂和具有挑战的课题,对于博弈论的学习和现实世界的模拟具有深远的意义 [9] [10],本系统从零开始构建了一个大众麻将系统,实现了AI自动打牌,完整牌局以及智能博弈系统。首先设计了博弈系统架构,选定了每一个用到的数据结构,设计了玩家的操作,包括吃碰杠胡等用到的功能。最后设计了总的权值矩阵以及搜索算法进行出牌舍牌,完成智能博弈功能。实验结果表明,根据距胡数的搜索算法与传统的权值系统相比,在大众麻将上胜率有明显提高。
当然,系统还有很多不足,本文对距胡数调整的方法还是比较朴素,仍然可以进一步地进行研究和改进,比如可以借助机器博弈与深度学习相结合的方法 [11];或许可以构想通过机器子博弈以实现对系统能力的提升。
基金项目
北京信息科技大学2021年大学生创新创业训练计划项助,项目号5102110805。