麻将算法c语言,[转载]麻将胡牌的检测算法

自己写了一个四川麻将胡牌的算法,加入有两组牌让你判定是否胡牌,其中char *as1 =

"1W1W2T2D3W3W5W5W7W7W8W8W9W9W"; char

*as2 = "1W1W1W2W3W4W4W5W6W7W8W9W9W9W";

主要思想是:

1)给牌分组,并排序;检查是否打缺了,只有缺了一门才能胡牌哦;

在排序的时候一定是有14张牌(否则可能就是小相公哦,呵呵……)

for (i=0; i<28; i++)//

{

if(*(Cards + i) == 'D')

{

pb[b++] =

*(Cards + i -1);

}

if(*(Cards + i) ==

'T')

{

pt[t++] =

*(Cards + i -1);

}

if(*(Cards + i) ==

'W')

{

pw[w++] =

*(Cards + i -1); }

}

if(b != 0 && t

!=0 && w != 0)

{

printf("n惨了,还没打缺呢……n");

return false;

}

sort(pb,b);

sort(pt,t);

sort(pw,w);

2)找找看对子在哪里,再开始三三组合

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

{

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) = ' ';

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; //输了 }

3)如何判断某一花色组合正确。

递归调用组合函数Group3S,每次先进行顺子组合,若不能成功,再进行三个相同的组合

找到一组三个相同的组合,在递归调用本函数,不断的进行顺子-三个相同 顺子-三个相同

递归的次数不会超过四次,因为只有12张牌,每一次找到三个相同的牌,都会减少三张牌实现代码如下:

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;

}

4)找出顺子,每找到一组顺子就把顺子剔除,最后,返回数组中剩余的元素的个数,如果返回值为0,

能够组合成若干个顺子,可以胡牌,否则,不能组合成顺子,不能胡牌该算法的核心算法代码如下:

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)

= ' ';

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;

}

5)找出相同的三个连续的牌,如果找到就剔除这三个牌,并返回真,传递进来的数组元素比原来少了3个如果没有,返回假

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)

= ' ';

p

= q;

return

true;

} else

{

for

(j = i;j < n - 3; j++)

{

*(q

+ j) = *(q + j + 3)

; }

*(q+j)

= ' ';

p

= q;

return

true;

}

}

}

return false;

}

这是我自己想的一个办法,如果你觉得哪里不对或者是有更多好办法,可以教教我,呵呵……

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值