麻将通常有13张牌,在打的时候随着吃,碰越来越少。总数应该维持在3*n + 1,n=0~4,比如1张,4张,7张或10张。胡牌时,加一张(可能是自摸或吃碰来的一张)组成n个顺子或暗刻,外加一个麻将对。
这里要研究的要点是:
1. 给出3n + 2张牌如何判断是否已经胡牌,所有的胡牌可能组合;
2. 如果给出3n+1张牌如何判断是否已经挺牌,挺哪些牌。
这两个问题其实主要是第一个问题,也就是如何判断3n +2 张牌是否胡牌的问题。后者可以简单地通过实验加34种麻将牌之一看是否胡牌来判断是否挺牌,以及挺哪些牌。
如何判断3n +2张牌是否胡牌
麻将牌包括:
1条~9条
1万~9万
1饼~9饼
东西南北中发白
共34种牌,34×4=136张牌。
给每张牌设一个编号
1条~9条
1万~9万
1饼~9饼
东西南北中发白
1 牌的存储
设一个宏,就是牌的种类
#define MAX_TILE_INDEX 34
所摸的牌就可以存在一个长度为34的数组中
int tiles[MAX_TILE_INDEX];
数组的每个成员最大值为4,因为每张牌的总数为4,就算摸到暗杠也不过是4. 所有数组成员加起来应该是3n + 2
2 结果的存储
每个胡牌必定是若干顺子/暗刻,外加一个麻将对,用一个简单的结构或类大概就是:
{
}
给定的3n + 2张牌普通只胡一种情况,但特殊情况也可能有多种胡法,比如4个一万,4个两万,4个3万,2个四万
胡牌至少可以:
i. 4个1万,2万和3万的顺子,外加4万的麻将对;
ii. 1个1万,2万和3万的顺子,1万暗刻,2万暗刻,3万暗刻,以及4万麻将对。
这些结果都应该被存起来,胡牌应该以最大番数计算。
C++可以用一个vector模板来实现结果列表,java可以考虑用哈希表。
3. 胡牌判断算法
判断胡牌与否
判断胡牌与否的过程:
3.1.
3.2.
关于第二步中如何判断3n
从第一张(种)牌开始往后检查,每张牌有5种可能,
i.
ii.
iii.
整个检查过程可以用一个函数递归调用就可以了,每次处理一张,如果不能凑成顺子或暗刻的话就推出返回错误,如果函数处理时总牌数为0,则所有牌都已处理完了,返回成功,结果也已经存在结果里了,把结果加入结果列表。
4. 挺牌检查
挺牌时应该是3*n + 1张牌。遍历34种牌,加入3n +1
5. 测试过程与结果
1.
2.
原帖:http://blog.sina.com.cn/s/blog_7213e0310101dq3w.html
后面补了一遍源码实现 http://blog.csdn.net/u014261855/article/details/54987832