成都麻将胡牌算法
//四川麻将胡牌算法(不支持风、花牌):支持缺一门,七小对,正常胡牌,带杠
//感谢 华仔 对我的代码提出了宝贵的意见,华仔很适合做测试啊!!
#include <stdio.h>
#include <memory.h>
#include <string.h>
#define TEST 0
#if TEST
#define LOG(fmt, ...) printf(fmt"\n", ##__VA_ARGS__)
#else
#define LOG(fmt, ...)
#endif
const char g_typedef[3] = {'W', 'T', 'D'};
class CMahJangg
{
public:
CMahJangg()
{
for (int i = 0; i < 3; i++)
{
m_TypeNum[i] = 0;
memset(m_CardNum[i], 0, sizeof(int)*9);
memset(log, 0, sizeof(char)*100);
m_GangNum = false;
}
}
void Init(char *pCards)
{
char *pTmp = pCards;
int nNum = 0;
char cType = 0;
while (*pTmp != '\0')
{
nNum = *pTmp - '0';
cType = *(pTmp+1);
for (int i = 0; i < 3; i++)
{
if (cType == g_typedef[i])
{
m_TypeNum[i]++;
m_CardNum[i][nNum-1]++;
break;
}
}
pTmp += 2;
}
}
bool IsSevenCouple()
{
if (14 == m_TypeNum[0] + m_TypeNum[1] + m_TypeNum[2])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 9; j++)
{
if (m_CardNum[i][j] != 0 && m_CardNum[i][j] != 2)
{
return false;
}
}
}
return true;
}
return false;
}
bool IsWin()
{
if (m_TypeNum[0] && m_TypeNum[1] && m_TypeNum[2])
{
//不是缺一门
LOG("不是缺一门\n");
return false;
}
if (IsSevenCouple())
{
//七小对
LOG("七小对\n");
return true;
}
//正常胡牌:有一个对子,其余的要么三支顺子,要么三支一样的(或四只)
bool HasCouple = false;
for (int i = 0; i < 3; i++)
{
if (!IsOneTypeWin(m_CardNum[i], m_TypeNum[i], HasCouple, i))
{
LOG("花色:%c不满足胡牌\n", g_typedef[i]);
return false;
}
}
if (!HasCouple)
{
LOG("没有对子,不能胡牌\n");
return false;
}
if (m_TypeNum[0]+m_TypeNum[1]+m_TypeNum[2]-14 != m_GangNum)
{
LOG("你丫诈和,牌的数量不对.\n");
return false;
}
LOG("正常胡牌\n");
return true;
}
bool IsOneTypeWin(int *pCards, int Num, bool &HasCouple, int type)
{
if (Num == 0)
{
return true;
}
char tmp[20] = {0};
for (int i = 0; i < 9; i++)
{
if (pCards[i] >= 2 && !HasCouple)
{
pCards[i] -= 2;
HasCouple = true;
if (IsOneTypeWin(pCards, Num-2, HasCouple, type))
{
sprintf(tmp, "%d%c%d%c ", i+1, g_typedef[type], i+1, g_typedef[type]);
strcat(log, tmp);
LOG("当前牌:%s\n", log);
return true;
}
pCards[i] += 2;
HasCouple = false;
}
if (pCards[i] == 4)
{
pCards[i] -= 4;
if (IsOneTypeWin(pCards, Num-4, HasCouple, type))
{
sprintf(tmp, "%d%c%d%c%d%c%d%c ", i+1, g_typedef[type], i+1, g_typedef[type], i+1, g_typedef[type], i+1, g_typedef[type]);
strcat(log, tmp);
LOG("当前牌:%s\n", log);
m_GangNum++;
return true;
}
pCards[i] += 4;
}
if (pCards[i] >= 3)
{
pCards[i] -= 3;
if (IsOneTypeWin(pCards, Num-3, HasCouple, type))
{
sprintf(tmp, "%d%c%d%c%d%c ", i+1, g_typedef[type], i+1, g_typedef[type], i+1, g_typedef[type]);
strcat(log, tmp);
LOG("当前牌:%s\n", log);
return true;
}
pCards[i] += 3;
}
if (i < 7 && pCards[i] && pCards[i+1] && pCards[i+2])
{
pCards[i] -= 1;
pCards[i+1] -= 1;
pCards[i+2] -= 1;
if (IsOneTypeWin(pCards, Num-3, HasCouple, type))
{
sprintf(tmp, "%d%c%d%c%d%c ", i+1, g_typedef[type], i+2, g_typedef[type], i+3, g_typedef[type]);
strcat(log, tmp);
LOG("当前牌:%s\n", log);
return true;
}
pCards[i] += 1;
pCards[i+1] += 1;
pCards[i+2] += 1;
}
}
return false;
}
private:
int m_TypeNum[3]; //分别表示万、条、筒的个数
int m_CardNum[3][9]; //分别表示万、条、筒(W,T,D)
int m_GangNum;
char log[100];
};
bool IsMahJangWin(char *pCard)
{
CMahJangg mj;
mj.Init(pCard);
return mj.IsWin();
}
作者:疯狂青蛙
出处:http://www.cnblogs.com/boyisjl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章明显页面给出原文链接,否则保留追究法律责任的权利。