斗地主牌型基本算法升級版本


       好久沒更新博客了,前段時間和朋友一起開了一個公司 做APP,最后失敗了。現在又開始做棋牌游戲了,最近在看網狐的源碼,發現里面斗地主的基本算法太強大了,現在想想我原來的算法簡直是弱爆了,分享一下 希望能對你有一點點幫助。以下主要涉及到判斷牌型,牌型大小比較2塊,如果你想了解更多關於棋牌游戲的東西請訪問我的棋牌游戲專欄

      大家寫過游戲都會發現,每一種游戲牌的組成類型不一樣的,比如斗地主判斷牌型,和德州判斷牌型就不一樣,最近寫德州撲克游戲發現其實所有判斷牌型的算法都是一樣的。
挑出牌出4張,3張,2張,1張出現的次數,然后各自組合看能出什么樣的牌型
,最后就能確定下來具體的牌型。下面是具體的代碼實現。。。。
一.判斷牌型
定義一個結構來表示每張相同牌的信息。

//分析結構
structtagAnalyseResult
{
    BYTE                         cbFourCount;                      //四張數目
    BYTE                         cbThreeCount;                     //三張數目
    BYTE                         cbDoubleCount;                    //兩張數目
    BYTE                         cbSignedCount;                    //單張數目
    BYTE                         cbFourCardData[MAX_COUNT];        //四張克
    BYTE                         cbThreeCardData[MAX_COUNT];       //三張撲克
    BYTE                         cbDoubleCardData[MAX_COUNT];      //兩張撲克
    BYTE                         cbSignedCardData[MAX_COUNT];      //單張撲克
};


當我們需要判斷牌型的時候,先分析牌把對應的數據存放到上面的結構體。然后根據不同牌型的規則來判斷即可。主要通過下面2個函數.話不多說直接上源代碼:
1、分析撲克(參數:1將要出牌的數據,出牌的張數,out存放分析的結構體)

void CGameLogic::AnalysebCardData(constBYTE cbCardData[], BYTE cbCardCount, tagAnalyseResult & AnalyseResult)
{
         //設置結果
         ZeroMemory(&AnalyseResult,sizeof(AnalyseResult));
 
         //撲克分析
         for(BYTE i=0;i<cbCardCount;i++)
         {
                   //變量定義
                   BYTE cbSameCount=1,cbCardValueTemp=0;
                   BYTE cbLogicValue=GetCardLogicValue(cbCardData[i]);
                   //搜索同牌
                   for(BYTE j=i+1;j<cbCardCount;j++)
                   {
                            //獲取撲克
                            if(GetCardLogicValue(cbCardData[j])!=cbLogicValue) break;
                            //設置變量
                            cbSameCount++;
                   }
                   //設置結果
                   switch(cbSameCount)
                   {
                   case1:    //單張
                            {
                                     BYTE cbIndex=AnalyseResult.cbSignedCount++;
                                     AnalyseResult.cbSignedCardData[cbIndex*cbSameCount]=cbCardData[i];
                                     break;
                            }
                   case2:    //兩張
                            {
                                     BYTE cbIndex=AnalyseResult.cbDoubleCount++;
                                     AnalyseResult.cbDoubleCardData[cbIndex*cbSameCount]=cbCardData[i];
                                     AnalyseResult.cbDoubleCardData[cbIndex*cbSameCount+1]=cbCardData[i+1];
                                     break;
                            }
                   case3:    //三張
                            {
                                     BYTE cbIndex=AnalyseResult.cbThreeCount++;
                                     AnalyseResult.cbThreeCardData[cbIndex*cbSameCount]=cbCardData[i];
                                     AnalyseResult.cbThreeCardData[cbIndex*cbSameCount+1]=cbCardData[i+1];
                                     AnalyseResult.cbThreeCardData[cbIndex*cbSameCount+2]=cbCardData[i+2];
                                     break;
                            }
                   case4:    //四張
                            {
                                     BYTE cbIndex=AnalyseResult.cbFourCount++;
                                     AnalyseResult.cbFourCardData[cbIndex*cbSameCount]=cbCardData[i];
                                     AnalyseResult.cbFourCardData[cbIndex*cbSameCount+1]=cbCardData[i+1];
                                     AnalyseResult.cbFourCardData[cbIndex*cbSameCount+2]=cbCardData[i+2];
                                     AnalyseResult.cbFourCardData[cbIndex*cbSameCount+3]=cbCardData[i+3];
                                     break;
                            }
                   }
 
                   //設置索引
                   i+=cbSameCount-1;
         }
 
         return;
}


2.、獲取具體牌的類型 (實現原理就是 通過出來的張數 和相同的牌來組合牌型 看是否滿足)

//獲取類型
BYTE CGameLogic::GetCardType(constBYTE cbCardData[], BYTE cbCardCount)
{
         //簡單牌型
         switch(cbCardCount)
         {
         case0:      //空牌
                   {
                            returnCT_ERROR;
                   }
         case1: //單牌
                   {
                            returnCT_SINGLE;
                   }
         case2:      //對牌火箭
                   {
                            //牌型判斷
                            if((cbCardData[0]==0x4F)&&(cbCardData[1]==0x4E))returnCT_MISSILE_CARD;
                            if(GetCardLogicValue(cbCardData[0])==GetCardLogicValue(cbCardData[1]))returnCT_DOUBLE;
 
                            returnCT_ERROR;
                   }
         }
 
         //分析撲克
         tagAnalyseResult AnalyseResult;
         AnalysebCardData(cbCardData,cbCardCount,AnalyseResult);
 
         //四牌判斷
         if(AnalyseResult.cbFourCount>0)
         {
                   //牌型判斷
                   if((AnalyseResult.cbFourCount==1)&&(cbCardCount==4))returnCT_BOMB_CARD;
                   //       if((AnalyseResult.cbFourCount==1)&&(AnalyseResult.cbSignedCount==2)&&(cbCardCount==6))return CT_FOUR_LINE_TAKE_ONE;
                   if((AnalyseResult.cbFourCount==1)&&(AnalyseResult.cbSignedCount==2)&&(cbCardCount==6))returnCT_FOUR_LINE_TAKE_ONE;
                   if((AnalyseResult.cbFourCount==1)&&(AnalyseResult.cbDoubleCount==2)&&(cbCardCount==8))returnCT_FOUR_LINE_TAKE_TWO;
 
                   returnCT_ERROR;
         }
 
         //三牌判斷
         if(AnalyseResult.cbThreeCount>0)
         {
                   //三條類型
                   if(AnalyseResult.cbThreeCount==1&& cbCardCount==3) returnCT_THREE ;
 
                   //連牌判斷
                   if(AnalyseResult.cbThreeCount>1)
                   {
                            //變量定義
                            BYTE cbCardData=AnalyseResult.cbThreeCardData[0];
                            BYTE cbFirstLogicValue=GetCardLogicValue(cbCardData);
 
                            //錯誤過慮
                            if(cbFirstLogicValue>=15) return CT_ERROR;
 
                            //連牌判斷
                            for(BYTE i=1;i<AnalyseResult.cbThreeCount;i++)
                            {
                                     BYTE cbCardData=AnalyseResult.cbThreeCardData[i*3];
                                     if(cbFirstLogicValue!=(GetCardLogicValue(cbCardData)+i)) returnCT_ERROR;
                            }
                   }
 
                   //牌形判斷
                   if(AnalyseResult.cbThreeCount*3==cbCardCount) returnCT_THREE_LINE;
                   if(AnalyseResult.cbThreeCount*4==cbCardCount) returnCT_THREE_LINE_TAKE_ONE;
                   if((AnalyseResult.cbThreeCount*5==cbCardCount)&&(AnalyseResult.cbDoubleCount==AnalyseResult.cbThreeCount))returnCT_THREE_LINE_TAKE_TWO;
 
                   returnCT_ERROR;
         }
 
         //兩張類型
         if(AnalyseResult.cbDoubleCount>=3)
         {
                   //變量定義
                   BYTE cbCardData=AnalyseResult.cbDoubleCardData[0];
                   BYTE cbFirstLogicValue=GetCardLogicValue(cbCardData);
 
                   //錯誤過慮
                   if(cbFirstLogicValue>=15) return CT_ERROR;
 
                   //連牌判斷
                   for(BYTE i=1;i<AnalyseResult.cbDoubleCount;i++)
                   {
                            BYTE cbCardData=AnalyseResult.cbDoubleCardData[i*2];
                            if(cbFirstLogicValue!=(GetCardLogicValue(cbCardData)+i)) returnCT_ERROR;
                   }
 
                   //二連判斷
                   if((AnalyseResult.cbDoubleCount*2)==cbCardCount)returnCT_DOUBLE_LINE;
 
                   returnCT_ERROR;
         }
 
         //單張判斷
         if((AnalyseResult.cbSignedCount>=5)&&(AnalyseResult.cbSignedCount==cbCardCount))
         {
                   //變量定義
                   BYTE cbCardData=AnalyseResult.cbSignedCardData[0];
                   BYTE cbFirstLogicValue=GetCardLogicValue(cbCardData);
 
                   //錯誤過慮
                   if(cbFirstLogicValue>=15) return CT_ERROR;
 
                   //連牌判斷
                   for(BYTE i=1;i<AnalyseResult.cbSignedCount;i++)
                   {
                            BYTE cbCardData=AnalyseResult.cbSignedCardData[i];
                            if(cbFirstLogicValue!=(GetCardLogicValue(cbCardData)+i)) returnCT_ERROR;
                   }
 
                   returnCT_SINGLE_LINE;
         }
 
         returnCT_ERROR;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM