吴昊品游戏核心算法 Round 8(特别篇) —— 吴昊教你打麻将(牌型分析AI)

摘要 : 麻将游戏软件的开发 , 就其内核部分 , 大致可以分为自动发牌、自动智能出牌、吃碰杠的处理、听牌判断、胡牌判断、基于不同麻

将玩法规则的番数计算等几大部分。其中以自动智能出牌、听牌判断、胡牌判断等处理最为复杂。这里主要介绍胡牌时 , 手中成牌牌型的

计算机处理的算法设计思想。

关键词 : AI; 成牌牌型 ; VB6.0

 

中图分类号 : TP 311

 

文献标识码 : A

 

文章编号 : 1009- 3044(2007)11- 21292- 01

1 引言

麻将的胡牌 , 一般接触过麻将的人都知道。但牌型复杂时 , 究

竟胡哪几张牌 , 可能并不是每一个人短时间内都能作出正确的判

断。用计算机来处理 , 也相当复杂。个人手中虽然只有 13 张牌 ( 针

对 13 张牌的玩法 ) , 但因牌局变化无常 , 从概率论的角度来看 , 一

个人两次拿到同样牌局的概率非常之低。可见此问题的复杂且无

规律 , 那计算机能解决吗 ? 答案是肯定的。哪如何解决 ? 又该从哪

儿开始着手呢 ?

麻将的牌局虽然复杂且变化无常 , 但构成手中的 13 张牌也

就只有两类 : 数牌(1)、字牌(2)。

胡牌的牌型 , 也只可能是由此 2 类中的 1- 2 类组成 , 并且 , 其

每一类必须是成牌牌型(3)。如此理解后可知 , 要分析胡牌 , 首先要

分析最基本的单类牌的成牌牌型。根据麻将的胡牌机理 , 数牌与

字牌是属不同的类型 , 它们的成牌牌型分析要分别处理。

2 数牌的成牌牌型分析

数牌中虽包括“条”、“筒”、“万”, 但同属一类 , 对它们的成牌

牌型分析方法是一样的 , 下面以“条”为例来分析。

 

 

(9)12 张牌的成牌牌型有 : 可 分 解 成 [3]和 [9]、[6]和 [6]组 合 等 ,

具体分析略。

3 数牌成牌牌型的计算机分析处理

计算机分析处理问题时 , 关系到数据结构的知识。在此便是

麻将在计算机中的存储形式 , 分两类 : 一是便于程序处理的具体

代表单张麻将的符号 , 如用 Mi( i=1,2,…,9) 代表“条”1 到 9; 二是便

于软件界面显示的具体单张麻将图形。这里只说程序的内在处

理 , 对于“条”, 这里采取的是常见的数组 , 用 cardm(14)来存储 , 其

中 , 前 13 位存放手中可能有的“条”牌 , 第 14 位用于存放统计得

到的手中“条”的总张数。如表(1)所示。

表 1

 

 

对于“条”数目为 2、3、5、6、8、9、11、12 的成牌牌型分析 , 则分

别构造函数来处理。下面以“条”数目为 2、3、5 处理算法为例来分

析 , 其它略。开发工具采用 VB6.0。

3.1 两张牌的成牌牌型分析

 

对于“条”而言 , 任何一次胡牌时 , 手中条的数量只能是 : 0、2、

 

Function SCard2 (card ())

 

' 形 参 数 组 card ()用 于 接 收 cardm

 

3、5、6、8、9、11、12、14 中的任一数目 , 其它数目的“条”均不能构成

成牌牌型。所以对于“条”的成牌牌型分析 , 只限于数目为 2、3、5、

6、8、9、11、12 的分析 , 至于数目是 14 时 , 这里不作分析 , 因手中只

有 13 张牌 , 13 张牌是听牌牌型 , 要听的牌便是第 14 张牌 ( 自摸的

或别人出的牌 ) 。另这里分析的成牌牌型是分析听牌牌型的基础。

(1)1 张牌的牌型 , A 型 , 用[1]表示。

(2)2 张牌的成牌牌型 , 只能是 AA(4)型 , 用 [2]表 示 , 定 为 基 本

成牌牌型。

(3)3 张牌的成牌牌型 , 只能是 AAA(4)或 ABC(4)型 , 用[3]表示 ,

也定为基本成牌牌型。

(4)5 张 牌 的 成 牌 牌 型 有 : AAABB、AABBB、AAABC、AABCD、

ABCCC、ABCDD 等可以分解成[2][3]或[3][2]基本成牌牌型的组合 ;

还有如 ABBBC 不能分解成基本成牌牌型的牌型 , 称之为特殊成

牌牌型。

 

(14)传来的值

x21 = Right(card(1),1): x22 = Right(card(2),1)

If x21 = x22 Then ' AA 成牌牌型

temp = 1

End If

scard2 = temp

End Function

3.2 三张牌的成牌牌型牌型分析

Function SCard3(card())

x31 = Val(Right(card(1),1)): x32 = Val(Right(card(2),1)): x33 =

Val(Right(card(3),1))

If x31 = x32 And Then

temp = 1 ' AAA 成牌牌型

End If

 

(5)

 

6 张 牌 的 成 牌 牌 型 有 : AAABBB、ABCCDE、ABCDEF、

 

If x33 - x32 = 1 And x32 = x33 = 1 Then

 

AAAABC 等可以分解成[3][3] 的基本成牌牌型 ; 还有如 ABBCCD、

AABBCC、ABBBBC 的特殊成牌牌型。

(6)8 张牌的成牌牌型有 : 可分解成[2]和[6]、[3]和 [5]、[2]和两个

[3]组合等 , 具体分析略。

(7)9 张牌的成牌牌型有 : 可分解成[3]和[6]、三个[3]组合等 , 具

体分析略。

(8)11 张牌的成牌牌型有 : 可分解 成 [2]和 [9]、[3]和 [8]组 合 等 ,

具体分析略。

 

temp = 1 ' ABC 成牌牌型

End If

scard3 = temp

End Function

3.3 5 张牌的成牌牌型牌型分析

Function SCard5(card())

……

cd51 = scard2(card51) ' 数组 card51()内存放 5 张条中前 2 张

begin

if(clk' event and clk=' 1' )then

if(ml="100")then

ml<="000";clockml<=not clockml;

else ml<=ml+1;

end if;

cp<=clockml;

end if;

end process;

u1:decoder port map(data_in,countz,countzz,data,csad,csd);

u2:datachange port map(cp,data,data_out,countz,countzz);

address_out<=countzz;

end pcm_arc;

4 结束语

PCM 采 编 器 的 仿 真 波 形 如 图 2 所 示 , 系 统 输 入 为 clk、da-

ta_in, 输出为 data_out、address_out、csd、csad, 由图 2 可以看出 , 系

(上接第 1292 页)

cd52 = scard3(card52)' 数组 card52()内存放 5 张条中后 3 张

If cd51 = 1 And cd52 = 1 Then  ' [2][3]组合成牌牌型分析

temp = 1

End If

'  [1][3][1]特殊成牌牌型 ABBBC

If (x51 - x52 = - 1) And (x52 = x53) And (x53 = x54) And (x54

- x55 = - 1) Then

temp = 1

End If

scard5 = temp

End Function

在上面的分析中 , 对于基本成牌牌型如[2]、[3], 构造函数来判

断 , 是成牌牌型返回 1 值 ; 当牌的张数大于等于 5 时 , 对可以分解

成成牌牌型组合的 , 可直接调用已分析得到的函数来判断 ; 对于

如 ABBBC 等特殊成牌牌型 , 目前采用枚举法。但这里的枚举 , 不

是一一列举 , 而是针对特殊成牌牌型的某一类列举。在上面(3)中

对 ABBBC 一类特殊成牌牌型的分析 , 就可用于处理 : 筒 23334、万

78889 等同属这一类的。

4 字牌的成牌牌型分析

字牌的成牌牌型分析有两种方法 : 一是考虑具体的“字”是什

么字 , 分东、南、西、北等。二是依此类牌的特殊性 , 只需考虑是否

是同字便可知道其是否构成成牌牌型。所以采用方法二 , 可使之

较数牌的成牌牌型分析更简单。这里不再具体分析。

5 字牌成牌牌型的计算机分析处理

对字牌成牌牌型的计算机分析处理 , 下面只对 2、3 张字牌的

成牌牌型判断算法作简要说明 , 其它多张牌时的判断分析 , 同前

面数牌的成牌牌型的计算机分析处理类似。不再赘述。

5.1 判断 2 张字牌是否构成成牌牌型

Function SCardZ2(grdx)

If z2(grdx) = 1 Then

temp = 1

End If

scardz2 = temp

End Function

5.2 判断 3 张字牌是否构成成牌牌型

Function SCardZ3(grdx)

If z3(grdx) = 1 Then

temp = 1

End If

scardz3 = temp

End Function

其中函数 z2()、z3()是用来判断连续的两张、三张字牌是否同字 , 是同字返回 1 值 ; 参数 grdx 是手中某个字牌的起始位置 , 如在

图 1 中 grdx 就等于 11; 数组 grd()存放个人手中的 13 张牌。

6 总结

(1) 单类牌的成牌牌型分析处理是后期听牌、胡牌判断的基

础。如图 1 中听牌的结果显示是“条”1、4、7, 它 就 是 基 于 对 另 外

“筒”456、“万”55、“字”中中中是否构成成牌牌型判断的基础上。

(2)单类牌的成牌牌型分析 , 是按牌的张数从少到多 , 逐步分

析。这符合软件工程中“从小到大”、“从简到繁”的设计思想。另

外 , 从前面的论述中也看到了 , 当牌的张数大于等于 5 时 , 其分析

中直接调用了之前已分析出的结果。这既实现了代码重用 , 提高

了编程的效率 , 又降低了牌数多时的分析难度。

(3)关于重复分析问题。如对 9 张“条”的处理可用 3 个[3]、[3]

与[6] 的两种组合来分析。对“条”111123456 的处理用上述两种组

合分析都可以。如果两种组合都用来分析 , 就出现了重复分析 ; 对

“条 ”123455667、122334777 的 处 理 则 只 能 用 [3]与 [6]的 组 合 来 分

析。实际分析时究竟采取哪中组合呢 ? 处理办法 , 采取更进一步的

细化分析。实际上 , 如果 9 张“条”构成成牌牌型 , 那么其头或尾 3

张牌必是成牌牌型[3]。所以对 9 张“条”是否构成成牌牌型的判断

处理 , 可以只用 [3]与 [6] 的组合来分析 , 这样就能避免重复 分 析 ,

从而提高程序的运行效率。但个别的情况下 , 有限的重复目前还

没有找到更好的解决方法。

 

 

图 1

注释 : (1)数牌 : 指条、筒、万。(2)字牌 : 指东、南、西、北、中、发、

白。(3)成牌牌型 : 指构成胡牌时的基本牌姿 , 如胡牌时手中有 2 张

条 , 则此 2 张条只能是条 AA, 那 么 条 AA 就 称 之 为 成 牌 牌 型 ; 如

胡牌时手中有 3 张条 , 则此 3 张条只能是条 AAA 或条 ABC, 那么

条 AAA、条 ABC 就称之为成牌牌型。 (4)牌型说明 : ①AA: 是指两

张同样的牌 , 如条 11、筒 22、万 33、字东东等。②AAA: 是指三张同

样的牌 , 如条 111、筒 222、万 333、字东东东等。③ABC: 是指三张

连续的牌 , 如条 123、筒 234、万 345 等。

参考文献 :

[1] 傅清详 , 王小东 , 等 . 算法与数据结构 [M]. 电子工业出版

社, 2006.12.

[2] 杨 文 龙 , 古 天 龙 , 等 . 软 件 工 程 [M]. 电 子 工 业 出 版 社 ,

2006.12.

[3] 齐锋, 等. Visual Basic 6.x 程序设计[M]. 中国铁道出版社 ,

2002.9.

你可能感兴趣的:(round)