|
查胡这个核心算法OK了,以它为支撑,可以解决我认为麻将中最难的部分——查听了。最简单的做法是每种花色尝试加一张牌,然后用查胡算法,如果胡了,这张就是听的牌,然后记录。我个人不喜欢这种简单暴力的做法,更愿意做一些有思考的解决方案,今天就聊一下另一种有效率的算法。
一、设计目标
计算手中牌是否上听,如果能上听,则听哪些牌。
二、分析
计算查听有三个先决条件:首先是张数要符合要求,必须为3n+1张;其次如果手中有两个或者以上花色,则必然有有且只有一种花色在OKTable中没有查到;最后就是查到的花色,Value中V应该相同,也就是只能是普通、七对和不靠牌中的一种。因此花色越多,查听的计算越简单,最难的是只有一种花色,因为普通、七对和不靠牌均有可能胡牌,两种以上花色时,查表得到的V值,就确定了胡牌的牌型。
确定了胡牌牌型和查表没找到的花色后,按照数字[0,8]分别给这个花色加一张牌,如果张数合理,也就是这个数字没有超过4张,就再计算NNCode后重新查OKTable,找到并判断V,就可以确定加入的数字是否胡牌了。
三、实现
1. 张数判断,初步确定可能的胡牌牌型:,
1) 不是3n+1,不听;
2) 是3n+1但是不是13张,只可能是普通牌,因为七对和不靠牌型只有13张时才可能胡。
2. 按花色查OKTable表,
1) 两个花色没查到,不听,只有一个花色没查到,确定听牌花色。
2) 已经查到的花色:如果有两个或以上,判断V值,不同则不听,相同则确定听牌牌型;如果只有一个,确定听牌牌型。
3. 数字[0,8]循环
1) 加入到听牌花色中,如果张数不合理,则下一个数字
2) 生成新的听牌花色NNCode,查表,没找到,则下一个数字
3) 找到,判断V是否与听牌牌型相同,相同则记录为听牌牌张
4. 例子
---测试是否听牌---
清一色 :三筒.三筒.四筒.四筒.四筒.五筒.五筒.五筒.五筒.六筒.六筒.六筒.七筒.
听了:|三筒.六筒.
九莲宝灯 :一筒.一筒.一筒.二筒.三筒.四筒.五筒.六筒.七筒.八筒.九筒.九筒.九筒.
听了:|一筒.二筒.三筒.四筒.五筒.六筒.七筒.八筒.九筒.
清龙七对 :一筒.一筒.一筒.一筒.二筒.二筒.二筒.二筒.四筒.四筒.五筒.五筒.六筒.
听了:|六筒.
将对 :二筒.二筒.五筒.五筒.八筒.八筒.二条.二条.五条.五条.八条.八条.八条.
听了:|八条.
全带幺 :一筒.二筒.三筒.一筒.二筒.三筒.七筒.八筒.九筒.九条.九条.九条.一条.
听了:|一条.
三色三步高:一筒.二筒.三筒.二条.三条.四条.三万.四万.五万.七筒.八筒.九筒.五筒.
听了:|五筒.
全不靠 :一筒.四筒.七筒.二条.五条.三万.六万.九万.东风.南风.西风.北风.中风.
听了:|八条.发风.白风.
七星不靠 :一筒.四筒.七筒.二条.五条.三万.六万.白风.东风.南风.西风.北风.中风.
听了:|八条.九万.发风.
组合龙 :一筒.四筒.七筒.二条.五条.八条.六万.九万.三万.南风.西风.北风.中风.
听了:|东风.发风.白风.
一色双龙会:一筒.二筒.三筒.一筒.二筒.三筒.七筒.八筒.九筒.七筒.八筒.九筒.五筒.
听了:|五筒.
三色双龙会:一条.二条.三条.七条.八条.九条.七条.八条.九条.发风.发风.发风.七筒.
听了:|七筒.
三色双龙会:一筒.二筒.三筒.七筒.八筒.九筒.一万.二万.三万.七万.八万.九万.五条.
听了:|五条.
三色双龙会:一条.二条.三条.七条.八条.九条.一筒.二筒.三筒.七筒.八筒.九筒.五万.
听了:|五万.
三色双龙会:一筒.二筒.三筒.七筒.八筒.九筒.一筒.二筒.三筒.七筒.八筒.九筒.五万.
听了:|五万.
小 三 元:中风.中风.中风.发风.发风.发风.七筒.八筒.九筒.七筒.八筒.九筒.白风.
听了:|白风.
乱 风 向:东风.东风.南风.南风.南风.南风.西风.西风.西风.北风.北风.中风.发风.
没听
字 一 色:东风.东风.东风.南风.南风.南风.西风.西风.西风.北风.北风.北风.中风.
听了:|中风.
清 碰:一筒.一筒.一筒.二筒.二筒.二筒.四筒.四筒.四筒.五筒.五筒.五筒.六筒.
听了:|四筒.五筒.六筒.七筒.
混 碰:一筒.一筒.一筒.二筒.二筒.二筒.四筒.四筒.四筒.五筒.五筒.五筒.北风.
听了:|北风.
清龙七对-1:一筒.一筒.一筒.一筒.二筒.二筒.二筒.二筒.四筒.四筒.五筒.五筒.六条.
听了:|六条. |
|