网上看到的一个麻将算法备用

天远科技  发表于:2019-02-15  分类:其他  阅读(3578)  赞同37
//会牌核心算法递归版本, 由原胡牌算法演进而来,检测更全面    by    iori  2017/1/10
bool laizi_hupai_base(int *pi_mj, int i_num, int *pi_select,int laizi_val)
{
    //pi_select[]用于在递归调用时记录已经访问过的牌
    int i,j,k;
    int i_max,i_min,i_mid;
    int i_mark1,i_mark2;
    int i_have3=0 ,laizi_num = 0;
    
    for(i=0; i<i_num; i++)
    {
        if( pi_select[i] )
            continue;
        else
            i_mark1 = i;
        
        for( j=i+1; j<i_num; j++)
        {
            if( i == j )
                continue;
            if(pi_select[j])
                continue;
            else
                i_mark2 = j;
            
            for( k=j+1; k<i_num; k++)
            {
                if( i==k || j==k )
                    continue;
                if( pi_select[k] )
                    continue;
                
                i_have3 = 1;
                laizi_num = 0;
                i_max = std::max(pi_mj[i], std::max(pi_mj[j], pi_mj[k]));
                i_min = std::min(pi_mj[i], std::min(pi_mj[j], pi_mj[k]));
                i_mid = (i_max + i_min) / 2;
                
//判断选中的是否为赖子,这里传入多个val,可以支持多赖
                if (pi_mj[i] == laizi_val) laizi_num++;
                if (pi_mj[j] == laizi_val) laizi_num++;
                if (pi_mj[k] == laizi_val) laizi_num++;
                
                if (laizi_num >= 2) //能成有会刻或者顺,默认刻
                {
                        // do something  根据你的项目需求可以保存数据
                }
                else
                if( (pi_mj[i] == pi_mj[j] && pi_mj[i] == pi_mj[k]) || (laizi_num == 1 && (pi_mj[i]  ==  pi_mj[j] ||  pi_mj[j] == pi_mj[k] || pi_mj[i]  == pi_mj[k]))  )  //表示能组成刻子
                {
                        // do something
                }
                else  if (laizi_num == 1)//判断是否能成有会顺
                {
                    if(pi_mj[i] == laizi_val)
                    {
                        if(pi_mj[j] - pi_mj[k] != -1 && pi_mj[j] - pi_mj[k] != -2 && pi_mj[j] - pi_mj[k] != 1 && pi_mj[j] - pi_mj[k] != 2 )
                            continue;
//这里根据项目不同的牌值区分 中发白与风牌过滤掉,博主这个项目没有,就不补上了
                    }else if(pi_mj[j] == laizi_val)
                    {
                        if(pi_mj[i] - pi_mj[k] != -1 && pi_mj[i] - pi_mj[k] != -2 && pi_mj[i] - pi_mj[k] != 1 && pi_mj[i] - pi_mj[k] != 2 )
                            continue;
                    }else if(pi_mj[k] == laizi_val)
                    {
                        if(pi_mj[i] - pi_mj[j] != -1 && pi_mj[i] - pi_mj[j] != -2 && pi_mj[i] - pi_mj[j] != 1 && pi_mj[i] - pi_mj[j] != 2 )
                            continue;
                    }
                        
                }else
                if( i_max-i_min == 2 && ( pi_mj[i] == i_mid || pi_mj[j] == i_mid || pi_mj[k] == i_mid)) //表示能组成顺子
                {
                        // do something
                }else
                    continue;
                
                //记录下来 下面递归
                pi_select[i] = pi_select[j] = pi_select[k] = 1;
                
                if( !laizi_hupai_base(pi_mj, i_num, pi_select,laizi_val) )
                {
                    pi_select[i] = pi_select[j] = pi_select[k] = 0; //递归一次结束,返回
                    continue;
                }
                
                //选择的3张成刻、顺,而剩下的和了
                return true;
            }
            
            //只剩两张牌, 相等 或者 其中一张为癞子时,满足牌型
            if( (i_have3 == 0) &&( pi_mj[i_mark1] == pi_mj[i_mark2] || pi_mj[i_mark1] == laizi_val ||  pi_mj[i_mark2] == laizi_val  ))
            {
                return true; //这里不退出,可以保存下来计算出所有能胡的牌型
            }
        }
    }
    return false;
}
博文分类

线

在线联系
点击这里给我发消息
点击这里给我发消息
关注我们