蓝钻棋牌游戏中心's Archiver

泊众棋牌专业棋牌游戏开发 谁是赢家 游戏运营商必读 遛鸟棋牌游戏
邮邮棋牌中心 斗地主技法从入门到精通 麻将高手秘籍 广告位招租
棋牌游戏推广策略 中国象棋入门 外挂-网游的杀手 棋牌游戏开发厂商

哈尔滨老富 发表于 2008-8-14 07:31

胡牌判断函数

*该函数判断手牌有没有胡牌,手牌的数量一定为[2,5,8,11,14]

*当手牌数量为14时,判断是否有特殊牌型的胡牌[十三么,七对,全不靠]

*当不存在以上牌型时,用递归算法判断是否存在一般的胡牌牌型

*

*作者:yutian(于恬)

*E_main:[email]yution@126.com[/email]

*

*作者声明:本代码为学习时编写的代码,大家可以随意转贴及编译修改

*但不得用于商业用途和赌博,作者保留一切权力

*

*鸣谢:网友  shyworm(怕怕虫) E_mail:[email]shyworm@sina.com[/email]

*       CSDN  ChinaUnix

*/



//-----------------------------------------------------------------------------------------------

int       TWanJia::IsWin()

{

    int i,dblpos,dblcount;



    if(this->PaiCount==13) //先处理特殊牌型,七对、十三么及全不靠

    {

       if((this->PaiInHand[0]==this->PaiInHand[1])&(this->PaiInHand[2]==this->PaiInHand[3])

       &(this->PaiInHand[4]==this->PaiInHand[5])&(this->PaiInHand[6]==this->PaiInHand[7])

       &(this->PaiInHand[8]==this->PaiInHand[9])&(this->PaiInHand[10]==this->PaiInHand[11])

       &(this->PaiInHand[12]==this->PaiInHand[13]))

         return SevenDbl; //七对胡了   



       dblcount=0;





       for(i=0;i<13;i++)  //以下判断手牌中对子的数量及位置

       {

         if(this->PaiInHand[i]==this->PaiInHand[i+1])

         {

            dblcount++;

         }



         if(dblcount>1) break; //如果手牌中含有两个对子(或一个刻子)以上,只能胡基本牌型

       }





       if(dblcount==1) //有一个对子的十三张手牌,可能为十三么

         {

           /***********************************************

            十三么牌型必须是么九牌和字牌组成的十四张牌,按牌的数值定义

             手牌数组PaiInHand中,只要没有1~7,10~16,19~25这些值,

            则可以断定,该数组为十三么

           */

          int IsThirteen=1;

          for(i=0;i<14;i++)

           {

              if(this->PaiInHand[i]>0&&this->PaiInHand[i]<8)

                {

                    IsThirteen=0;

                    break;

                }

              else if(this->PaiInHand[i]>9&&this->PaiInHand[i]<17)

                {

                    IsThirteen=0;

                    break;

                }

              else if(this->PaiInHand[i]>18&&this->PaiInHand[i]<26)

                {

                    IsThirteen=0;

                    break;

                }

           }

          if(IsThirteen) return ThirteenSmall;

         }   //end of 十三么



       if(dblcount==0)//没有对子,可能是全不靠

         {

         /*-------------------------------------------

         十三不靠牌型为万筒条三个花色的147,258,369加上字牌的七张牌共16张

         的任意十四张组成的胡牌,147,258,369的花色可以为任意花色,但不能有两副

         出现相同的序数,如一万,四万,一条,四条是不能组成胡牌的。



         判定的算法是:

         先确定所以序数牌(不是字牌)的个数;

         如果序数牌个数大于9,则返回错误;

         如果有吃牌的序列(存在两张牌可以吃掉另外一张牌),返回错误;

         对于所有的序数牌,自第一个开始,分别与其后的所有牌值mod9得

         到的值比较,如果存在相等,返回错误。

         如果上面判断都通过,则为十三不靠



         */



         int NoWordPos=14;



         for(i=13;i>=0;i--)

           {

              if(this->PaiInHand[i]<=26)

              {

                 NoWordPos=i;

                 break;

              }

           }



         if(NoWordPos<=8)   //如果非字牌有9个以上,肯定不能胡全不靠

           {

              int IsThirteenSingle=1;



              for(i=0;i<NoWordPos;i++)

                {

                  if((this->PaiInHand[i+1]<=(this->PaiInHand[i]+2))&(this->PaiInHand[i]%9==this->PaiInHand[i+1]%9))

                    {

                       IsThirteenSingle=0;

                       break;

                    }

                }



              if(IsThirteenSingle)

                {

                  for(i=0;i<NoWordPos&IsThirteenSingle;i++)

                    {

                       for(int j=0;j<=NoWordPos;j++)

                         {

                            if(this->PaiInHand[i]==this->PaiInHand[j]%9)

                              {

                                IsThirteenSingle=0;

                                break;

                              }

                         }

                    }

                }



                if(IsThirteenSingle) return   ThirteenSingle;

           }





         } //end of 不靠

    }

   

   

    int TempPai[33];

   

    for(i=0;i<34;i++) TempPai=0;

   

    for(i=0;i<14;i++)

      {

        TempPai[this->PaiInHand[i]]++;

      }      

   if(HuPai(TempPai)) return GenaralWin;

    return 0;

}

//-----------------------------------------------------------------------------------------------------------------

int Tfrm_mainwin::HuPai(int arr)

{

/*

以下代码参考了网友

shyworm(怕怕虫) E_mail:[email]shyworm@sina.com[/email]

在csdn论坛发表的算法及源码,在此感谢



原来的算法中要对杠牌进行处理,但我设计的数据结构中,不需要对他们进行判断了,

故略去了一段代码

*/

   static int Jiang=0;  // 将牌标志,即牌型“三三三三二”中的“二”

   

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

   

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

  

  // 3张组合(刻子)

   if(arr[i]>=3)  // 如果当前牌不少于3张

   {

      arr[i]-=3;  // 减去3张牌

      if(HuPai(arr)) return 1;   // 如果剩余的牌组合成功,和牌

      arr[i]+=3;  // 取消3张组合  

   }

   

   // 2张组合(将牌)

   if(!Jiang&arr[i]>=2)  // 如果之前没有将牌,且当前牌不少于2张

   {

     Jiang=1;  // 设置将牌标志

     arr[i]-=2;  // 减去2张牌

     if(HuPai(arr)) return 1;  // 如果剩余的牌组合成功,和牌

     arr[i]+=2;  // 取消2张组合

     Jiang=0; // 清除将牌标志

   }

   

   if(i>26) return 0;  // “东南西北中发白”没有顺牌组合,不和

   

   

   // 顺牌组合,注意是从前往后组合!

   if(i%9!=7&i%9!=8&arr[i+1]&arr[i+2])// 排除数值为8和9的牌且如果后面有连续两张牌  

   {

     arr[i]--;

     arr[i+1]--;

     arr[i+2]--;   // 各牌数减1

     if(HuPai(arr)) return 1;  // 如果剩余的牌组合成功,和牌

     arr[i]++;

     arr[i+1]++;

     arr[i+2]++;  // 恢复各牌数  

   }

   

   

   // 无法全部组合,不和!

   return 0;

}

//----------------------------------------------------------------------------

// 检查剩余牌数

int Tfrm_mainwin::RemainPai(int arr)

{

int sum=0;



for(int i=0;i<34;i++)

   sum+=arr[i];

  

return sum;  



}

//----------------------------------------------------------------------------



[/code]



头文件



[code]

页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.