您的位置:首页 > 其它

四川麻将胡牌算法

2018-01-25 14:46 204 查看
其中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<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;   //输了  

}

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

}

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  麻将