|
混合查表胡牌算法中,最重要的就是胡牌表,我称之为OkTable。如何设计好OKTable,对后续的胡牌校验、查听、以及胡牌牌型以及翻数计算有这莫大的帮助。OKTable的核心是红黑树存放的Key-Value对,红黑树不容置疑,STL的unordered_map自带了去重机制和高效的查询效率,无疑是简单优秀的解决方案;Key的选择自然是NNCode的编码,一个uint32_t就可以包含最多13张手中牌的信息;Value最简单的要求是胡牌结果,但是仅有胡牌结果,对于后续的翻数计算极为不利,今天就来聊一下Value编码设计。
一、设计目标
一个uint32_t,可以包含胡牌类型和本次胡牌的牌型。
二、分析
麻将的胡牌可以归纳为三种类型:普通牌(3n+2)、七对牌(2n)和不靠牌型(13n),其中普通牌的不同花色,有可以分为有对和无对两种。
普通牌,最多记录1个对的数字和4个顺或者刻的数字(顺只需要记录最小数字)
七对牌,最多记录7个对的数字
不靠牌,需要记录13张牌,但是从花色来看,筒万条需要记录[1,4,7],[2,5,8],[3,6,9]的组合,风向需要记录最多7张,最少5张的组合,因为七星不靠牌型最多7张不同的风,组合龙牌型最少5张风。
三、实现
Value:变长编码,由A、B、C区组成,以C区的V决定AB区的分解
1. C区
2位,[0,3],用以存放胡牌的牌型
0:3n牌型,无对
1:3n+2牌型,有对,n可以为0;
2:七对牌型;
3:不靠牌型;
2. A、B区
如果V=[0,1],则A+B区一共4+(1+4)*4=24位,分别为
A区(麻将头):4位,存放数字[0,8]
B区(3n区):20位,分为4组5位;每组5位中,第1位 0标识刻、1标识顺,第2、3、4、5位,存放数字[0,8],不足4组,以15填充
如果V=[2,3],则A+B区一共4*7=28位,分为7组,每组4位,存放数字[0,8],不足7组,以15填充
3. 例子
青龙7对:“4个一筒、4个二筒、2个四筒、2个五筒、两个六筒”
筒Value:281878(十进制)
筒二进制:0b00 0000 0000 0001 0001 0011 0100 0101 10
筒分解为: 0 0 1 1 3 4 5 2
筒分区为: -----------------AB区------------- C
还原为:1筒对、1筒对、2筒对、2筒对、4筒对、5筒对、6筒对
结果:7对牌型,7对-0刻-0顺 一筒对.一筒对.二筒对.二筒对.四筒对.五筒对.六筒对.
全带幺: “一筒、二筒、三筒、一筒、二筒、三筒、七筒、八筒、九筒、九条、九条、九条、一条、1条”
筒Value:65080124
筒二进制:0b000000 1111 10000 10000 10110 01111 00
筒分解为: 无效 1顺 1顺 6顺 无效 0
筒分区为: -A区- ----------B区--------- C
还原为:1筒顺、1筒顺、7筒顺;
条Value: 1111997
条二进制:0b000000 0000 01000 01111 01111 01111 01
条分解为: 0对 8刻 无效 无效 无效 1
条分区为: -A区- ---------B区---------- C
还原为:1条对、9条刻
结果:普通牌型,1对-1刻-3顺 一条对.一筒暗顺.一筒暗顺.七筒暗顺.九条暗刻.
全不靠: “一筒、四筒、七筒、二条、五条、三万、六万、九万、东风、西风、南风北风、中、发”
筒Value:14417919(十进制)
筒二进制:0b00 0000 0011 0110 1111 1111 1111 1111 11
筒分解为: 0 3 6 无效 无效 无效 无效 3
筒分区为: -----------------AB区------------- C
还原为:1筒、4筒、7筒
条Value:88080383(十进制)
条二进制:0b00 0001 0100 1111 1111 1111 1111 1111 11
条分解为: 1 4 无效 无效 无效 无效 无效 3
条分区为: -----------------AB区------------- C
还原为:2条、5条
万Value:157548543(十进制)
万二进制:0b00 0010 0101 1000 1111 1111 1111 1111 11
万分解为: 2 5 8 无效 无效 无效 无效 3
万分区为: -----------------AB区------------- C
还原为:3万、6万、9万
风Value:4772223(十进制)
风二进制:0b00 0000 0001 0010 0011 0100 0101 1111 11
风分解为: 0 1 2 3 4 5 无效 3
风分区为: -----------------AB区------------- C
还原为:东、南、西、北、中、发
结果:特殊牌型,0对-0刻-0顺 一筒.四筒.七筒.二条.五条.三万.六万.九万.东风.南风.西风.北风.中风.发风. |
|