摘要 : 麻将游戏软件的开发 , 就其内核部分 , 大致可以分为自动发牌、自动智能出牌、吃碰杠的处理、听牌判断、胡牌判断、基于不同麻
将玩法规则的番数计算等几大部分。其中以自动智能出牌、听牌判断、胡牌判断等处理最为复杂。这里主要介绍胡牌时 , 手中成牌牌型的
计算机处理的算法设计思想。
关键词 : 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.