⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 majiang.cpp

📁 麻将胡牌算法的实现。不考虑七小队
💻 CPP
字号:
/*
#include<stdio.h>
#include<string.h>
#include <stdio.h>

int g_Pai[3][9]=
{
//	 1,2,3,4,5,6,7,8,9
	{2,2,2,2,2,2,2,0,0},	//筒
	{0,0,0,0,0,0,0,0,0},	//条
	{0,0,0,0,0,0,0,0,0}		//万
};
int g_iGroupFound =0;

bool FindGroup(int iPai1[3][9])
{
	int	m=0,i=0,j=0,k=0,l=0;
	int iJiangFound=0;
	int iPai[3][9];

	if(g_iGroupFound ==4)//若已发现四组牌,则胡牌
		return true;

	memcpy(iPai,iPai1,sizeof(int)*27);
	for(m=0;m<3;m++)
	{
		for(i=0;i<9;i++)
		{
			if(iPai[m][i]>2)		//三张相同牌
			{
				iPai[m][i]-=3;		//找出一组牌后,从当前牌组中删除
				g_iGroupFound++;	//组数增加
				if(FindGroup(iPai))
					goto FIND;
				else				//若未能找出四组相同牌,则刚才找出的那组牌无效,恢复
				{
					g_iGroupFound--;
					iPai[m][i]+=3;
				}
			}

			if(i<6)
			{
				if(iPai[m][i] > 0 && iPai[m][i+1] >0 && iPai[m][i+2]>0)//三张连续牌
				{
					iPai[m][i]--;
					iPai[m][i+1]--;
					iPai[m][i+2]--;
					g_iGroupFound++;
					if(FindGroup(iPai))
						goto FIND;
					else
					{
						iPai[m][i]++;
						iPai[m][i+1]++;
						iPai[m][i+2]++;
						g_iGroupFound--;
					}
				}
			}
		}
	}

	return false;
FIND:
	return true;
}

bool Hu(int iPai1[3][9])
{
	int	m=0,i=0,j=0,k=0,l=0;
	int iJiangFound=0;
	bool bFound=true;
	int iPai[3][9];

	memcpy(iPai,iPai1,sizeof(int)*27);

	for(m=0;m<3;m++)
	{
		for(i=0;i<9;i++)
		{
			if(iPai[m][i]>1)
			{
				iPai[m][i]-=2;			//以某一对相同牌为将牌,看是否能找出四组相同牌
				if(FindGroup(iPai))
					return true;
				else
					iPai[m][i]+=2;
			}
		}
	}

	return false;
};

void main()
{
	int	i=0,j=0,iType=0,iNum=0;
	
	memset(g_Pai,0,sizeof(g_Pai));


	printf("请输入牌:");
	for(i=0;i<14;i++)
	{
		printf("\n第%d张牌:",i+1);
		do
		{
			printf("\n牌类别(1-筒;2-万;3-条): ");
			scanf("%d",&iType);
		}while(iType<1||iType>3);

		do
		{
			printf("牌值(1,2,3,4,5,6,7,8,9): ");
			scanf("%d",&iNum);
		}while(iNum<1 || iNum>9);

		g_Pai[iType-1][iNum-1]+=1;
	}

	printf("当前牌:");
	printf("\n筒:\t");
	for(i=0;i<9;i++)
	{
		if(g_Pai[0][i]>0)
			printf("%d--%d , ",i+1,g_Pai[0][i]);
	}
	printf("\n条:\t");
	for(i=0;i<9;i++)
	{
		if(g_Pai[1][i]>0)
			printf("%d--%d , ",i+1,g_Pai[1][i]);
	}
	printf("\n万:\t");
	for(i=0;i<9;i++)
	{
		if(g_Pai[2][i]>0)
			printf("%d--%d , ",i+1,g_Pai[2][i]);
	}
	if(Hu(g_Pai))
		printf("\n胡牌\n");
	else
		printf("\n不胡牌\n");
}
/*
*/
#include <stdio.h>

int Hu(int PAI[30]);
int Remain(int PAI[30]);

int main()
{
    int PAI[30] = { 0,
					1,3,1,4,1,1,1,1,1,    // PAI[ 1- 9]  一万~九万的个数
                    0,
                    0,0,0,0,0,0,0,0,0,    // PAI[11-19]  一筒~九筒的个数
                    0,
                    0,0,0,0,0,0,0,0,0  // PAI[21-29]    一条~九条的个数
                            
                    };  
//    int PAI[30]={0}
	int sum=0;
/*
    printf("输入牌出现的个数:\n");
	for(int i=0;i<30;i++)
	{
		if(i==0||i==10||i==20) 
		{
			PAI[i]=0;
			continue;
		}
		printf("PAI[%d]:\t",i);
		scanf("%d",&PAI[i]);
		printf("\n");
	    sum+=PAI[i];
		if(sum==14) break;
	    
	}
*/
   
    if( Hu(PAI) ) 
        printf("胡牌\n");
    else
        printf("不是胡牌!\n");

    return 1;
}

// 判断胡牌的递归函数
int Hu(int PAI[30])
{
    static int JIANG = 0;            // 将牌标志,即牌型"三三三三二"中的"二"

    if( !Remain(PAI) ) return 1;     // 递归退出条件:如果没有剩牌,则胡牌返回。

    for(int i=1;!PAI[i]&&i<30;i++);  // 找到有牌的地方,i就是当前牌, PAI[i]是个数

   // printf("i = %d\n",i);            // 跟踪信息

    

    // 3张组合(大对)
    if ( PAI[i] >= 3 )               // 如果当前牌不少于3张
    {
        PAI[i] -= 3;                 // 减去3张牌
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,胡牌
        PAI[i] += 3;                 // 取消3张组合
    }

    // 2张组合(将牌)
    if ( !JIANG && PAI[i] >= 2 )     // 如果之前没有将牌,且当前牌不少于2张
    {
        JIANG = 1;                   // 设置将牌标志
        PAI[i] -= 2;                 // 减去2张牌
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,胡牌
        PAI[i] += 2;                 // 取消2张组合
        JIANG = 0;                   // 清除将牌标志
    }

   
    

    // 顺牌组合,注意是从前往后组合!
    if( i%10 != 8 && i%10 != 9  &&   // 排除数值为8和9的牌
         PAI[i+1] && PAI[i+2] )      // 如果后面有连续两张牌
    {
        PAI[i]--;
        PAI[i+1]--;
        PAI[i+2]--;                  // 各牌数减1
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,胡牌
        PAI[i]++;
        PAI[i+1]++;
        PAI[i+2]++;                  // 恢复各牌数
    }

    // 无法全部组合,不胡!
    return 0;
}

// 检查剩余牌数
int Remain(int PAI[30])
{
    int sum = 0;
    for(int i=1;i<30;i++)
        sum += PAI[i];
    return sum;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -