麻将胡牌的算法

来源:互联网 发布:linux vim查看行数 编辑:程序博客网 时间:2024/04/28 02:42

清一色是麻将的种类之一,指有一种花色的序数牌组成的胡牌。

数字1-9,每个数字最多4张牌;

我们不考虑具体的花色,我们只看数字;

刻字:三张一样的牌:111.222.333

顺子:三张连续的牌123,46,789

对子:两张连续的牌;11,22,33,44

需要一个程序实现,判定给定牌,是否可以和牌;

胡牌要求:麻将 牌张数只能是2,5,8,11,14

给定牌可以组合成,除1个对子以外的其他都是刻字或者顺子

胡牌输出YES否则NO

#include<stdio.h>

#include<iostream>
using   namespace std;
bool Group3Same(char *p, int n)
{
char * q;
int sp = 0;
int i, j;
q = p;
if (n == 0)
{
return true;
}
for (i = 0; i < n - 2; i++)
{
if (*(q + i + 1) == *(q + i) && *(q + i + 2) == *(q + i + 1))
{
if (i == n - 3)            //把这三个元素移除,把后面的元素往前移动三格
{
*(q + i) = '\0';
p = q;
return true;
}
else
{
for (j = i; j < n - 3; j++)
{
*(q + j) = *(q + j + 3);
}
*(q + j) = '\0';
p = q;
return true;
}
}
}
return false;
}
int Group3Shunzi(char *p, int n)
{
char *q, *w;
int i, j, k, m, l, sp = 0;
m = 0;
q = p;
w = p;
if (n == 0)
{
return 0;
} for (i = 0; i < n - 2; i++)
{
for (j = i + 1; j < n - 1; j++)
{
if (*(q + j) - *(q + i) == 1)
{
for (k = j + 1; k < n; k++)
{
if (*(q + k) - *(q + j) == 1)
{
if (i == n - 3)          //把这三个元素移除,把后面的元素往前移动三格
{
*(q + i) = '\0';
n -= 3;
i--;
break;
}
else
{
*(q + i) = '0';
*(q + j) = '0';
*(q + k) = '0';
for (m = 0, l = 0; l < n; l++)
{
if (*(q + l) != '0')
{
*(w + (m++)) = *(q + l);
}
}
n = m;
q = w;
i--;
break;
}
}
}
}
continue;
}
}
return  n;
}
bool Group3S(char *p, int n)
{
char pp[14], p2[14];
int i, j;
for (i = 0; i < n; i++)
{
pp[i] = *(p + i);
p2[i] = *(p + i);
}
bool flag = false;
if (n == 0)
{
return true;
}
if (!Group3Shunzi(p, n))
return true;
if (Group3Same(p2, n))               //顺子出错,就看看有没有三个相同的,有就把三个相同的挑出来,在进行顺子算法
{
n -= 3;
flag = Group3S(p2, n);
}
return flag;
}
bool Group(char *pp, int n)
{
char q[14];
char r;
int i, j, k = 0;
r = '0';
for (i = 0; i < n; i++)
{
q[i] = *(pp + i);
}
if (n == 0)
{
return true;
}
else if (n % 3 == 2)              //必定存在一对对子
{
for (i = k; i<n - 1; i++)
{
if (*(q + i) == *(q + i + 1) && *(q + i) != r)     //找对子,并剔除对子
{
r = *(q + i);
for (j = i; j < n - 2; j++)
{
*(q + j) = *(q + j + 2);        //所有元素左移两位
}
*(q + j) = '\0';


i--;
k = i;
if (Group3S(q, n - 2))           //某一花色组合正确
{
return true;
}
for (j = 0; j < n; j++)
{
q[j] = *(pp + j);          //恢复原来的数组,并进行下一轮对子的选择
}
}                //找出对子,并剔除,在剩余的12张牌中进行组合
}
}
else                 //没有对子,只能是三个三个一组(三个相同或者顺子)
{
if (Group3S(q, n))
{
return true;             //某一花色组合正确
}
}
return false;   //输了  
}


void main()
{
/*char s[11] ,*p;
p = s;
gets(p);
int n;
n = *p - '0';
while (*++p)
{
n = n * 7 + *p - '0';
}
printf("%d",n);*/
char *as1 = "11";  
char *as2 = "111222336";
char *as3 = "11122233369";
int d=Group(as3, 11);
if (d == 1)printf("%s", "yes");
else printf("%s","no");
cin.get();



}
0 0
原创粉丝点击