好久沒更新博客了,前段時間和朋友一起開了一個公司 做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; }