麻将高效鬼牌胡牌算法(C++版)

最近做的一个麻将里面有双鬼牌的玩法,即为8张鬼牌,第一反应是采用N重循环把鬼牌变成一张张牌去遍历是否能胡牌,实际测试在5张牌鬼牌的情况得出结果就需要差不多5,6分钟。

因此自己做了一套用凑牌的方式去判断胡牌,原理是尝试把手牌中的任意一张当做对子(将牌),如果不够两张则用鬼牌去补一张,最后再提取出对子,判断剩下的手牌组成横或者顺子需要多少鬼牌,如果大于剩余的鬼牌数量,则本次检查胡牌失败,把对子还原到手牌中,尝试提取下一个对子继续检测。

我这里的实现方式C++,逻辑并不复杂可以简单的转成lua
首先传入的参数分别是手牌的索引(已经去掉鬼牌),和手牌的数量,以及鬼牌的数量
手牌的索引实际上是一个size大小为34(因为麻将的牌除去重复的一共34张)的char数组HandCard,其中HandCard[i]中的i代表牌值(0-34分别为1-9万,1-9条,1-9筒,东南西北中发白按顺序排列),HandCard[i]的值为手牌中这个牌的数量

bool CheckCanHu(char const HandCard[MAX_INDEX], size_t HandCardSize,size_t GhostCount)
{
   
	char TotalCount = HandCardSize + GhostCount;
	if ((TotalCount - 2) % 3 != 0 || TotalCount > MAX_HANDCOUNT)
	{
   
		//牌数,不满足3n+2,或大于14张
		return false;
	}
	//当该手牌中只有万能牌时
	if (TotalCount == GhostCount)
	{
   
		return true;
	}
	char CardIndexTemp[MAX_INDEX];
	memcpy(CardIndexTemp, HandCard, sizeof(CardIndexTemp));
	std::vector<char> PairsInfo;  //用于存放所有能构成胡牌的对子的值
	char CheckZero = ((GhostCount < 2) ? 2 : 0);//(0-未检查 1-成功 2-失败 )
	//1.把手牌中的每一张当做对子(将牌),然后检查余下的牌是否能达到胡牌条件(组成顺子或者横)
	for (char i = 0; i < MAX_INDEX; ++i)
	{
   
		if (0 == CardIndexTemp[i])
		{
   
			//尝试检测一次鬼牌变成手牌里没有的牌
			if (CheckZero == 0)  
			{
   
				//CheckZero不为0说明检测过了 不再检测
				GhostCount -= 2;
				if 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值