📄 majiang.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 + -