#include "DDZ_GameLogic.h" #include #include #include ////////////////////////////////////////////////////////////////////////////////// //静态变量 //索引变量 const uint8 cbIndexCount=5; //扑克数据 const uint8 CDDZGameLogic::m_cbCardData[DDZ_FULL_COUNT]= { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D, //方块 A - K 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D, //梅花 A - K 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D, //红桃 A - K 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D, //黑桃 A - K 0x4E,0x4F, }; ////////////////////////////////////////////////////////////////////////////////// //构造函数 CDDZGameLogic::CDDZGameLogic() { } //析构函数 CDDZGameLogic::~CDDZGameLogic() { } //获取类型 uint8 CDDZGameLogic::GetCardType(const uint8 cbCardData[], uint8 cbCardCount) { //简单牌型 switch (cbCardCount) { case 0: //空牌 { return DDZ_CT_ERROR; } case 1: //单牌 { return DDZ_CT_SINGLE; } case 2: //对牌火箭 { //牌型判断 if ((cbCardData[0] == 0x4F) && (cbCardData[1] == 0x4E)) return DDZ_CT_MISSILE_CARD; if (GetCardLogicValue(cbCardData[0]) == GetCardLogicValue(cbCardData[1])) return DDZ_CT_DOUBLE; return DDZ_CT_ERROR; } } //分析扑克 tagAnalyseResult AnalyseResult; AnalysebCardData(cbCardData, cbCardCount, AnalyseResult); //四牌判断 if (AnalyseResult.cbBlockCount[3] > 0) { //牌型判断 if ((AnalyseResult.cbBlockCount[3] == 1) && (cbCardCount == 4)) return DDZ_CT_BOMB_CARD; if ((AnalyseResult.cbBlockCount[3] == 1) && (cbCardCount == 6)) return DDZ_CT_FOUR_TAKE_ONE; if ((AnalyseResult.cbBlockCount[3] == 1) && (cbCardCount == 8) && (AnalyseResult.cbBlockCount[1] == 2)) return DDZ_CT_FOUR_TAKE_TWO; return DDZ_CT_ERROR; } //三牌判断 if (AnalyseResult.cbBlockCount[2] > 0) { //连牌判断 if (AnalyseResult.cbBlockCount[2] > 1) { //变量定义 uint8 cbCardData = AnalyseResult.cbCardData[2][0]; uint8 cbFirstLogicValue = GetCardLogicValue(cbCardData); //错误过虑 if (cbFirstLogicValue >= 15) return DDZ_CT_ERROR; //连牌判断 for (uint8 i = 1; i < AnalyseResult.cbBlockCount[2]; i++) { uint8 cbCardData = AnalyseResult.cbCardData[2][i * 3]; if (cbFirstLogicValue != (GetCardLogicValue(cbCardData) + i)) return DDZ_CT_ERROR; } } else if (cbCardCount == 3) return DDZ_CT_THREE; //牌形判断 if (AnalyseResult.cbBlockCount[2] * 3 == cbCardCount) return DDZ_CT_THREE_LINE; if (AnalyseResult.cbBlockCount[2] * 4 == cbCardCount) return DDZ_CT_THREE_TAKE_ONE; if ((AnalyseResult.cbBlockCount[2] * 5 == cbCardCount) && (AnalyseResult.cbBlockCount[1] == AnalyseResult.cbBlockCount[2])) return DDZ_CT_THREE_TAKE_TWO; return DDZ_CT_ERROR; } //两张类型 if (AnalyseResult.cbBlockCount[1] >= 3) { //变量定义 uint8 cbCardData = AnalyseResult.cbCardData[1][0]; uint8 cbFirstLogicValue = GetCardLogicValue(cbCardData); //错误过虑 if (cbFirstLogicValue >= 15) return DDZ_CT_ERROR; //连牌判断 for (uint8 i = 1; i < AnalyseResult.cbBlockCount[1]; i++) { uint8 cbCardData = AnalyseResult.cbCardData[1][i * 2]; if (cbFirstLogicValue != (GetCardLogicValue(cbCardData) + i)) return DDZ_CT_ERROR; } //二连判断 if ((AnalyseResult.cbBlockCount[1] * 2) == cbCardCount) return DDZ_CT_DOUBLE_LINE; return DDZ_CT_ERROR; } //单张判断 if ((AnalyseResult.cbBlockCount[0] >= 5) && (AnalyseResult.cbBlockCount[0] == cbCardCount)) { //变量定义 uint8 cbCardData = AnalyseResult.cbCardData[0][0]; uint8 cbFirstLogicValue = GetCardLogicValue(cbCardData); //错误过虑 if (cbFirstLogicValue >= 15) return DDZ_CT_ERROR; //连牌判断 for (uint8 i = 1; i < AnalyseResult.cbBlockCount[0]; i++) { uint8 cbCardData = AnalyseResult.cbCardData[0][i]; if (cbFirstLogicValue != (GetCardLogicValue(cbCardData) + i)) return DDZ_CT_ERROR; } return DDZ_CT_SINGLE_LINE; } return DDZ_CT_ERROR; } //排列扑克 void CDDZGameLogic::SortCardList(uint8 cbCardData[], uint8 cbCardCount, uint8 cbSortType) { //数目过虑 if (cbCardCount==0) return; if (cbSortType == DDZ_ST_CUSTOM) return; //转换数值 uint8 cbSortValue[DDZ_MAX_COUNT]; for (uint8 i=0;iCountArray(cbTempCardData)) return false; memcpy(cbTempCardData,cbCardData,cbCardCount*sizeof(cbCardData[0])); //置零扑克 for (uint8 i=0;iCountArray(cbTempCardData)) return false; memcpy(cbTempCardData,cbCardData,cbCardCount*sizeof(cbCardData[0])); //置零扑克 for (uint8 i=0;i= 0; i-- ) { if( i == 2 ) continue; if( AnalyseResult.cbBlockCount[i] > 0 ) { memcpy( &cbCardData[cbCardCount],AnalyseResult.cbCardData[i], sizeof(uint8)*(i+1)*AnalyseResult.cbBlockCount[i] ); cbCardCount += (i+1)*AnalyseResult.cbBlockCount[i]; } } } else if (cbCardType == DDZ_CT_FOUR_TAKE_ONE || cbCardType == DDZ_CT_FOUR_TAKE_TWO) { //分析牌 tagAnalyseResult AnalyseResult = {}; AnalysebCardData( cbCardData,cbCardCount,AnalyseResult ); cbCardCount = AnalyseResult.cbBlockCount[3]*4; //memcpy(cbCardData, AnalyseResult.cbCardData[3], sizeof(uint8)*cbCardCount); memcpy( cbCardData,AnalyseResult.cbCardData[3],sizeof(uint8)*cbCardCount ); for( int i = CountArray(AnalyseResult.cbBlockCount)-1; i >= 0; i-- ) { if( i == 3 ) continue; if( AnalyseResult.cbBlockCount[i] > 0 ) { memcpy( &cbCardData[cbCardCount],AnalyseResult.cbCardData[i], sizeof(uint8)*(i+1)*AnalyseResult.cbBlockCount[i] ); cbCardCount += (i+1)*AnalyseResult.cbBlockCount[i]; } } } return; } //逻辑数值 uint8 CDDZGameLogic::GetCardLogicValue(uint8 cbCardData) { //扑克属性 uint8 cbCardColor=GetCardColor(cbCardData); uint8 cbCardValue=GetCardValue(cbCardData); //转换数值 if (cbCardColor==0x40) return cbCardValue+2; return (cbCardValue<=2)?(cbCardValue+13):cbCardValue; } //对比扑克 bool CDDZGameLogic::CompareCard(const uint8 cbFirstCard[], const uint8 cbNextCard[], uint8 cbFirstCount, uint8 cbNextCount) { //获取类型 uint8 cbNextType = GetCardType(cbNextCard, cbNextCount); uint8 cbFirstType = GetCardType(cbFirstCard, cbFirstCount); //类型判断 if (cbNextType == DDZ_CT_ERROR) return false; if (cbNextType == DDZ_CT_MISSILE_CARD) return true; //炸弹判断 if ((cbFirstType != DDZ_CT_BOMB_CARD) && (cbNextType == DDZ_CT_BOMB_CARD)) return true; if ((cbFirstType == DDZ_CT_BOMB_CARD) && (cbNextType != DDZ_CT_BOMB_CARD)) return false; //规则判断 if ((cbFirstType!=cbNextType)||(cbFirstCount!=cbNextCount)) return false; //开始对比 switch (cbNextType) { case DDZ_CT_SINGLE: case DDZ_CT_DOUBLE: case DDZ_CT_THREE: case DDZ_CT_SINGLE_LINE: case DDZ_CT_DOUBLE_LINE: case DDZ_CT_THREE_LINE: case DDZ_CT_BOMB_CARD: { //获取数值 uint8 cbNextLogicValue=GetCardLogicValue(cbNextCard[0]); uint8 cbFirstLogicValue=GetCardLogicValue(cbFirstCard[0]); //对比扑克 return cbNextLogicValue>cbFirstLogicValue; } case DDZ_CT_THREE_TAKE_ONE: case DDZ_CT_THREE_TAKE_TWO: { //分析扑克 tagAnalyseResult NextResult; tagAnalyseResult FirstResult; AnalysebCardData(cbNextCard,cbNextCount,NextResult); AnalysebCardData(cbFirstCard,cbFirstCount,FirstResult); //获取数值 uint8 cbNextLogicValue=GetCardLogicValue(NextResult.cbCardData[2][0]); uint8 cbFirstLogicValue=GetCardLogicValue(FirstResult.cbCardData[2][0]); //对比扑克 return cbNextLogicValue>cbFirstLogicValue; } case DDZ_CT_FOUR_TAKE_ONE: case DDZ_CT_FOUR_TAKE_TWO: { //分析扑克 tagAnalyseResult NextResult; tagAnalyseResult FirstResult; AnalysebCardData(cbNextCard,cbNextCount,NextResult); AnalysebCardData(cbFirstCard,cbFirstCount,FirstResult); //获取数值 uint8 cbNextLogicValue=GetCardLogicValue(NextResult.cbCardData[3][0]); uint8 cbFirstLogicValue=GetCardLogicValue(FirstResult.cbCardData[3][0]); //对比扑克 return cbNextLogicValue>cbFirstLogicValue; } } return false; } //构造扑克 uint8 CDDZGameLogic::MakeCardData(uint8 cbValueIndex, uint8 cbColorIndex) { return (cbColorIndex<<4)|(cbValueIndex+1); } //分析扑克 void CDDZGameLogic::AnalysebCardData(const uint8 cbCardData[], uint8 cbCardCount, tagAnalyseResult & AnalyseResult) { //设置结果 zeromemory(&AnalyseResult, sizeof(tagAnalyseResult)); //扑克分析 for (uint8 i=0;i>4]++; } return; } //出牌搜索 uint8 CDDZGameLogic::SearchOutCard( const uint8 cbHandCardData[], uint8 cbHandCardCount, const uint8 cbTurnCardData[], uint8 cbTurnCardCount, tagSearchCardResult *pSearchCardResult ) { //设置结果 assert( pSearchCardResult != NULL ); if( pSearchCardResult == NULL ) return 0; zeromemory(pSearchCardResult,sizeof(tagSearchCardResult)); //变量定义 uint8 cbResultCount = 0; tagSearchCardResult tmpSearchCardResult = {}; //构造扑克 uint8 cbCardData[DDZ_MAX_COUNT]; uint8 cbCardCount=cbHandCardCount; memcpy(cbCardData,cbHandCardData,sizeof(uint8)*cbHandCardCount); //排列扑克 SortCardList(cbCardData,cbCardCount,DDZ_ST_ORDER); //获取类型 uint8 cbTurnOutType = GetCardType(cbTurnCardData, cbTurnCardCount); //出牌分析 switch (cbTurnOutType) { case DDZ_CT_ERROR: //错误类型 { //提取各种牌型一组 assert( pSearchCardResult ); if( !pSearchCardResult ) return 0; //是否一手出完 if (GetCardType(cbCardData, cbCardCount) != DDZ_CT_ERROR) { pSearchCardResult->cbCardCount[cbResultCount] = cbCardCount; memcpy( pSearchCardResult->cbResultCard[cbResultCount],cbCardData, sizeof(uint8)*cbCardCount ); cbResultCount++; } //如果最小牌不是单牌,则提取 uint8 cbSameCount = 0; if( cbCardCount > 1 && GetCardValue(cbCardData[cbCardCount-1]) == GetCardValue(cbCardData[cbCardCount-2]) ) { cbSameCount = 1; pSearchCardResult->cbResultCard[cbResultCount][0] = cbCardData[cbCardCount-1]; uint8 cbCardValue = GetCardValue(cbCardData[cbCardCount-1]); for( int i = cbCardCount-2; i >= 0; i-- ) { if( GetCardValue(cbCardData[i]) == cbCardValue ) { pSearchCardResult->cbResultCard[cbResultCount][cbSameCount++] = cbCardData[i]; } else break; } pSearchCardResult->cbCardCount[cbResultCount] = cbSameCount; cbResultCount++; } //单牌 uint8 cbTmpCount = 0; if( cbSameCount != 1 ) { cbTmpCount = SearchSameCard( cbCardData,cbCardCount,0,1,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } } //对牌 if( cbSameCount != 2 ) { cbTmpCount = SearchSameCard( cbCardData,cbCardCount,0,2,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } } //三条 if( cbSameCount != 3 ) { cbTmpCount = SearchSameCard( cbCardData,cbCardCount,0,3,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } } //三带一单 cbTmpCount = SearchTakeCardType( cbCardData,cbCardCount,0,3,1,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } //三带一对 cbTmpCount = SearchTakeCardType( cbCardData,cbCardCount,0,3,2,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } //单连 cbTmpCount = SearchLineCardType( cbCardData,cbCardCount,0,1,0,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } //连对 cbTmpCount = SearchLineCardType( cbCardData,cbCardCount,0,2,0,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } //三连 cbTmpCount = SearchLineCardType( cbCardData,cbCardCount,0,3,0,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } ////飞机 //cbTmpCount = SearchThreeTwoLine( cbCardData,cbCardCount,&tmpSearchCardResult ); //if( cbTmpCount > 0 ) //{ // pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; // memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], // sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); // cbResultCount++; //} //炸弹 if( cbSameCount != 4 ) { cbTmpCount = SearchSameCard( cbCardData,cbCardCount,0,4,&tmpSearchCardResult ); if( cbTmpCount > 0 ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[0]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[0], sizeof(uint8)*tmpSearchCardResult.cbCardCount[0] ); cbResultCount++; } } //搜索火箭 if ((cbCardCount>=2)&&(cbCardData[0]==0x4F)&&(cbCardData[1]==0x4E)) { //设置结果 pSearchCardResult->cbCardCount[cbResultCount] = 2; pSearchCardResult->cbResultCard[cbResultCount][0] = cbCardData[0]; pSearchCardResult->cbResultCard[cbResultCount][1] = cbCardData[1]; cbResultCount++; } pSearchCardResult->cbSearchCount = cbResultCount; return cbResultCount; } case DDZ_CT_SINGLE: //单牌类型 case DDZ_CT_DOUBLE: //对牌类型 case DDZ_CT_THREE: //三条类型 { //变量定义 uint8 cbReferCard=cbTurnCardData[0]; uint8 cbSameCount = 1; if (cbTurnOutType == DDZ_CT_DOUBLE) cbSameCount = 2; else if (cbTurnOutType == DDZ_CT_THREE) cbSameCount = 3; //搜索相同牌 cbResultCount = SearchSameCard( cbCardData,cbCardCount,cbReferCard,cbSameCount,pSearchCardResult ); break; } case DDZ_CT_SINGLE_LINE: //单连类型 case DDZ_CT_DOUBLE_LINE: //对连类型 case DDZ_CT_THREE_LINE: //三连类型 { //变量定义 uint8 cbBlockCount = 1; if (cbTurnOutType == DDZ_CT_DOUBLE_LINE) cbBlockCount = 2; else if (cbTurnOutType == DDZ_CT_THREE_LINE) cbBlockCount = 3; uint8 cbLineCount = cbTurnCardCount/cbBlockCount; //搜索边牌 cbResultCount = SearchLineCardType( cbCardData,cbCardCount,cbTurnCardData[0],cbBlockCount,cbLineCount,pSearchCardResult ); break; } case DDZ_CT_THREE_TAKE_ONE: //三带一单 case DDZ_CT_THREE_TAKE_TWO: //三带一对 { //效验牌数 if( cbCardCount < cbTurnCardCount ) break; //如果是三带一或三带二 if( cbTurnCardCount == 4 || cbTurnCardCount == 5 ) { uint8 cbTakeCardCount = cbTurnOutType == DDZ_CT_THREE_TAKE_ONE ? 1 : 2; //搜索三带牌型 cbResultCount = SearchTakeCardType( cbCardData,cbCardCount,cbTurnCardData[2],3,cbTakeCardCount,pSearchCardResult ); } else { //变量定义 uint8 cbBlockCount = 3; uint8 cbLineCount = cbTurnCardCount / (cbTurnOutType == DDZ_CT_THREE_TAKE_ONE ? 4 : 5); uint8 cbTakeCardCount = cbTurnOutType == DDZ_CT_THREE_TAKE_ONE ? 1 : 2; //搜索连牌 uint8 cbTmpTurnCard[DDZ_MAX_COUNT] = {}; memcpy( cbTmpTurnCard,cbTurnCardData,sizeof(uint8)*cbTurnCardCount ); SortOutCardList( cbTmpTurnCard,cbTurnCardCount ); cbResultCount = SearchLineCardType( cbCardData,cbCardCount,cbTmpTurnCard[0],cbBlockCount,cbLineCount,pSearchCardResult ); //提取带牌 bool bAllDistill = true; for( uint8 i = 0; i < cbResultCount; i++ ) { uint8 cbResultIndex = cbResultCount-i-1; //变量定义 uint8 cbTmpCardData[DDZ_MAX_COUNT]; uint8 cbTmpCardCount = cbCardCount; //删除连牌 memcpy( cbTmpCardData,cbCardData,sizeof(uint8)*cbCardCount ); assert( RemoveCard( pSearchCardResult->cbResultCard[cbResultIndex],pSearchCardResult->cbCardCount[cbResultIndex], cbTmpCardData,cbTmpCardCount ) ); cbTmpCardCount -= pSearchCardResult->cbCardCount[cbResultIndex]; //分析牌 tagAnalyseResult TmpResult = {}; AnalysebCardData( cbTmpCardData,cbTmpCardCount,TmpResult ); //提取牌 uint8 cbDistillCard[DDZ_MAX_COUNT] = {}; uint8 cbDistillCount = 0; for( uint8 j = cbTakeCardCount-1; j < CountArray(TmpResult.cbBlockCount); j++ ) { if( TmpResult.cbBlockCount[j] > 0 ) { if( j+1 == cbTakeCardCount && TmpResult.cbBlockCount[j] >= cbLineCount ) { uint8 cbTmpBlockCount = TmpResult.cbBlockCount[j]; memcpy( cbDistillCard,&TmpResult.cbCardData[j][(cbTmpBlockCount-cbLineCount)*(j+1)], sizeof(uint8)*(j+1)*cbLineCount ); cbDistillCount = (j+1)*cbLineCount; break; } else { for( uint8 k = 0; k < TmpResult.cbBlockCount[j]; k++ ) { uint8 cbTmpBlockCount = TmpResult.cbBlockCount[j]; memcpy( &cbDistillCard[cbDistillCount],&TmpResult.cbCardData[j][(cbTmpBlockCount-k-1)*(j+1)], sizeof(uint8)*cbTakeCardCount ); cbDistillCount += cbTakeCardCount; //提取完成 if( cbDistillCount == cbTakeCardCount*cbLineCount ) break; } } } //提取完成 if( cbDistillCount == cbTakeCardCount*cbLineCount ) break; } //提取完成 if( cbDistillCount == cbTakeCardCount*cbLineCount ) { //复制带牌 uint8 cbCount = pSearchCardResult->cbCardCount[cbResultIndex]; memcpy( &pSearchCardResult->cbResultCard[cbResultIndex][cbCount],cbDistillCard, sizeof(uint8)*cbDistillCount ); pSearchCardResult->cbCardCount[cbResultIndex] += cbDistillCount; } //否则删除连牌 else { bAllDistill = false; pSearchCardResult->cbCardCount[cbResultIndex] = 0; } } //整理组合 if( !bAllDistill ) { pSearchCardResult->cbSearchCount = cbResultCount; cbResultCount = 0; for( uint8 i = 0; i < pSearchCardResult->cbSearchCount; i++ ) { if( pSearchCardResult->cbCardCount[i] != 0 ) { tmpSearchCardResult.cbCardCount[cbResultCount] = pSearchCardResult->cbCardCount[i]; memcpy( tmpSearchCardResult.cbResultCard[cbResultCount],pSearchCardResult->cbResultCard[i], sizeof(uint8)*pSearchCardResult->cbCardCount[i] ); cbResultCount++; } } tmpSearchCardResult.cbSearchCount = cbResultCount; memcpy( pSearchCardResult,&tmpSearchCardResult,sizeof(tagSearchCardResult) ); } } break; } case DDZ_CT_FOUR_TAKE_ONE: //四带两单 case DDZ_CT_FOUR_TAKE_TWO: //四带两双 { uint8 cbTakeCount = cbTurnOutType == DDZ_CT_FOUR_TAKE_ONE ? 1 : 2; uint8 cbTmpTurnCard[DDZ_MAX_COUNT] = {}; memcpy( cbTmpTurnCard,cbTurnCardData,sizeof(uint8)*cbTurnCardCount ); SortOutCardList( cbTmpTurnCard,cbTurnCardCount ); //搜索带牌 cbResultCount = SearchTakeCardType( cbCardData,cbCardCount,cbTmpTurnCard[0],4,cbTakeCount,pSearchCardResult ); break; } } //搜索炸弹 if ((cbCardCount >= 4) && (cbTurnOutType != DDZ_CT_MISSILE_CARD)) { //变量定义 uint8 cbReferCard = 0; if (cbTurnOutType == DDZ_CT_BOMB_CARD) cbReferCard = cbTurnCardData[0]; //搜索炸弹 uint8 cbTmpResultCount = SearchSameCard( cbCardData,cbCardCount,cbReferCard,4,&tmpSearchCardResult ); for( uint8 i = 0; i < cbTmpResultCount; i++ ) { pSearchCardResult->cbCardCount[cbResultCount] = tmpSearchCardResult.cbCardCount[i]; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSearchCardResult.cbResultCard[i], sizeof(uint8)*tmpSearchCardResult.cbCardCount[i] ); cbResultCount++; } } //搜索火箭 if (cbTurnOutType != DDZ_CT_MISSILE_CARD && (cbCardCount >= 2) && (cbCardData[0] == 0x4F) && (cbCardData[1] == 0x4E)) { //设置结果 pSearchCardResult->cbCardCount[cbResultCount] = 2; pSearchCardResult->cbResultCard[cbResultCount][0] = cbCardData[0]; pSearchCardResult->cbResultCard[cbResultCount][1] = cbCardData[1]; cbResultCount++; } if ( pSearchCardResult ) { pSearchCardResult->cbSearchCount = cbResultCount; } return cbResultCount; } //同牌搜索 uint8 CDDZGameLogic::SearchSameCard( const uint8 cbHandCardData[], uint8 cbHandCardCount, uint8 cbReferCard, uint8 cbSameCardCount, tagSearchCardResult *pSearchCardResult ) { //设置结果 if (pSearchCardResult) { zeromemory(pSearchCardResult,sizeof(tagSearchCardResult)); } uint8 cbResultCount = 0; //构造扑克 uint8 cbCardData[DDZ_MAX_COUNT]; uint8 cbCardCount=cbHandCardCount; memcpy(cbCardData,cbHandCardData,sizeof(uint8)*cbHandCardCount); //排列扑克 SortCardList(cbCardData,cbCardCount,DDZ_ST_ORDER); //分析扑克 tagAnalyseResult AnalyseResult = {}; AnalysebCardData( cbCardData,cbCardCount,AnalyseResult ); uint8 cbReferLogicValue = cbReferCard==0?0:GetCardLogicValue(cbReferCard); uint8 cbBlockIndex = cbSameCardCount-1; do { for( uint8 i = 0; i < AnalyseResult.cbBlockCount[cbBlockIndex]; i++ ) { uint8 cbIndex = (AnalyseResult.cbBlockCount[cbBlockIndex]-i-1)*(cbBlockIndex+1); if( GetCardLogicValue(AnalyseResult.cbCardData[cbBlockIndex][cbIndex]) > cbReferLogicValue ) { if( pSearchCardResult == NULL ) return 1; assert( cbResultCount < CountArray(pSearchCardResult->cbCardCount) ); //复制扑克 memcpy( pSearchCardResult->cbResultCard[cbResultCount],&AnalyseResult.cbCardData[cbBlockIndex][cbIndex], cbSameCardCount*sizeof(uint8) ); pSearchCardResult->cbCardCount[cbResultCount] = cbSameCardCount; cbResultCount++; } } cbBlockIndex++; }while( cbBlockIndex < CountArray(AnalyseResult.cbBlockCount) ); if( pSearchCardResult ) pSearchCardResult->cbSearchCount = cbResultCount; return cbResultCount; } //带牌类型搜索(三带一,四带一等) uint8 CDDZGameLogic::SearchTakeCardType( const uint8 cbHandCardData[], uint8 cbHandCardCount, uint8 cbReferCard, uint8 cbSameCount, uint8 cbTakeCardCount, tagSearchCardResult *pSearchCardResult ) { //设置结果 if (pSearchCardResult) { zeromemory(pSearchCardResult, sizeof(tagSearchCardResult)); } uint8 cbResultCount = 0; //效验 assert( cbSameCount == 3 || cbSameCount == 4 ); assert(cbTakeCardCount == 1 || cbTakeCardCount == 2); if( cbSameCount != 3 && cbSameCount != 4 ) return cbResultCount; if( cbTakeCardCount != 1 && cbTakeCardCount != 2 ) return cbResultCount; //长度判断 if( (cbSameCount == 4 && cbHandCardCount 0 ) { //分析扑克 tagAnalyseResult AnalyseResult; AnalysebCardData(cbCardData,cbCardCount,AnalyseResult); //需要牌数 uint8 cbNeedCount = cbSameCount+cbTakeCardCount; if( cbSameCount == 4 ) cbNeedCount += cbTakeCardCount; //提取带牌 for( uint8 i = 0; i < cbSameCardResultCount; i++ ) { bool bMerge = false; for( uint8 j = cbTakeCardCount-1; j < CountArray(AnalyseResult.cbBlockCount); j++ ) { for( uint8 k = 0; k < AnalyseResult.cbBlockCount[j]; k++ ) { //从小到大 uint8 cbIndex = (AnalyseResult.cbBlockCount[j]-k-1)*(j+1); //过滤相同牌 if( GetCardValue(SameCardResult.cbResultCard[i][0]) == GetCardValue(AnalyseResult.cbCardData[j][cbIndex]) ) continue; //复制带牌 uint8 cbCount = SameCardResult.cbCardCount[i]; memcpy( &SameCardResult.cbResultCard[i][cbCount],&AnalyseResult.cbCardData[j][cbIndex], sizeof(uint8)*cbTakeCardCount ); SameCardResult.cbCardCount[i] += cbTakeCardCount; if( SameCardResult.cbCardCount[i] < cbNeedCount ) continue; if( pSearchCardResult == NULL ) return 1; //复制结果 memcpy( pSearchCardResult->cbResultCard[cbResultCount],SameCardResult.cbResultCard[i], sizeof(uint8)*SameCardResult.cbCardCount[i] ); pSearchCardResult->cbCardCount[cbResultCount] = SameCardResult.cbCardCount[i]; cbResultCount++; bMerge = true; //下一组合 break; } if( bMerge ) break; } } } if( pSearchCardResult ) pSearchCardResult->cbSearchCount = cbResultCount; return cbResultCount; } //连牌搜索 uint8 CDDZGameLogic::SearchLineCardType( const uint8 cbHandCardData[], uint8 cbHandCardCount, uint8 cbReferCard, uint8 cbBlockCount, uint8 cbLineCount, tagSearchCardResult *pSearchCardResult ) { //设置结果 if (pSearchCardResult) { zeromemory(pSearchCardResult,sizeof(tagSearchCardResult)); } uint8 cbResultCount = 0; //定义变量 uint8 cbLessLineCount = 0; if( cbLineCount == 0 ) { if( cbBlockCount == 1 ) cbLessLineCount = 5; else if( cbBlockCount == 2 ) cbLessLineCount = 3; else cbLessLineCount = 2; } else cbLessLineCount = cbLineCount; uint8 cbReferIndex = 2; if( cbReferCard != 0 ) { assert(GetCardLogicValue(cbReferCard) - cbLessLineCount >= 2); cbReferIndex = GetCardLogicValue(cbReferCard)-cbLessLineCount+1; } //超过A if( cbReferIndex+cbLessLineCount > 14 ) return cbResultCount; //长度判断 if( cbHandCardCount < cbLessLineCount*cbBlockCount ) return cbResultCount; //构造扑克 uint8 cbCardData[DDZ_MAX_COUNT]; uint8 cbCardCount=cbHandCardCount; memcpy(cbCardData,cbHandCardData,sizeof(uint8)*cbHandCardCount); //排列扑克 SortCardList(cbCardData,cbCardCount,DDZ_ST_ORDER); //分析扑克 tagDistributing Distributing = {}; AnalysebDistributing(cbCardData,cbCardCount,Distributing); //搜索顺子 uint8 cbTmpLinkCount = 0; uint8 cbValueIndex = 0; for (cbValueIndex=cbReferIndex;cbValueIndex<13;cbValueIndex++) { //继续判断 if ( Distributing.cbDistributing[cbValueIndex][cbIndexCount]= cbLessLineCount ) { if( pSearchCardResult == NULL ) return 1; assert(cbResultCount < CountArray(pSearchCardResult->cbCardCount)); //复制扑克 uint8 cbCount = 0; for( uint8 cbIndex = cbValueIndex+1-cbTmpLinkCount; cbIndex <= cbValueIndex; cbIndex++ ) { uint8 cbTmpCount = 0; for (uint8 cbColorIndex=0;cbColorIndex<4;cbColorIndex++) { for( uint8 cbColorCount = 0; cbColorCount < Distributing.cbDistributing[cbIndex][3-cbColorIndex]; cbColorCount++ ) { pSearchCardResult->cbResultCard[cbResultCount][cbCount++]=MakeCardData(cbIndex,3-cbColorIndex); if( ++cbTmpCount == cbBlockCount ) break; } if( cbTmpCount == cbBlockCount ) break; } } //设置变量 pSearchCardResult->cbCardCount[cbResultCount] = cbCount; cbResultCount++; if( cbLineCount != 0 ) { cbTmpLinkCount--; } else { cbTmpLinkCount = 0; } } } //特殊顺子 if( cbTmpLinkCount >= cbLessLineCount-1 && cbValueIndex == 13 ) { if( Distributing.cbDistributing[0][cbIndexCount] >= cbBlockCount || cbTmpLinkCount >= cbLessLineCount ) { if( pSearchCardResult == NULL ) return 1; assert(cbResultCount < CountArray(pSearchCardResult->cbCardCount)); //复制扑克 uint8 cbCount = 0; uint8 cbTmpCount = 0; for( uint8 cbIndex = cbValueIndex-cbTmpLinkCount; cbIndex < 13; cbIndex++ ) { cbTmpCount = 0; for (uint8 cbColorIndex=0;cbColorIndex<4;cbColorIndex++) { for( uint8 cbColorCount = 0; cbColorCount < Distributing.cbDistributing[cbIndex][3-cbColorIndex]; cbColorCount++ ) { pSearchCardResult->cbResultCard[cbResultCount][cbCount++]=MakeCardData(cbIndex,3-cbColorIndex); if( ++cbTmpCount == cbBlockCount ) break; } if( cbTmpCount == cbBlockCount ) break; } } //复制A if( Distributing.cbDistributing[0][cbIndexCount] >= cbBlockCount ) { cbTmpCount = 0; for (uint8 cbColorIndex=0;cbColorIndex<4;cbColorIndex++) { for( uint8 cbColorCount = 0; cbColorCount < Distributing.cbDistributing[0][3-cbColorIndex]; cbColorCount++ ) { pSearchCardResult->cbResultCard[cbResultCount][cbCount++]=MakeCardData(0,3-cbColorIndex); if( ++cbTmpCount == cbBlockCount ) break; } if( cbTmpCount == cbBlockCount ) break; } } //设置变量 pSearchCardResult->cbCardCount[cbResultCount] = cbCount; cbResultCount++; } } if( pSearchCardResult ) pSearchCardResult->cbSearchCount = cbResultCount; return cbResultCount; } //搜索飞机 uint8 CDDZGameLogic::SearchThreeTwoLine( const uint8 cbHandCardData[], uint8 cbHandCardCount, tagSearchCardResult *pSearchCardResult ) { //设置结果 if (pSearchCardResult) { zeromemory(pSearchCardResult,sizeof(tagSearchCardResult)); } //变量定义 tagSearchCardResult tmpSearchResult = {}; tagSearchCardResult tmpSingleWing = {}; tagSearchCardResult tmpDoubleWing = {}; uint8 cbTmpResultCount = 0; //搜索连牌 cbTmpResultCount = SearchLineCardType( cbHandCardData,cbHandCardCount,0,3,0,&tmpSearchResult ); if( cbTmpResultCount > 0 ) { //提取带牌 for( uint8 i = 0; i < cbTmpResultCount; i++ ) { //变量定义 uint8 cbTmpCardData[DDZ_MAX_COUNT]; uint8 cbTmpCardCount = cbHandCardCount; //不够牌 if( cbHandCardCount-tmpSearchResult.cbCardCount[i] < tmpSearchResult.cbCardCount[i]/3 ) { uint8 cbNeedDelCount = 3; while( cbHandCardCount+cbNeedDelCount-tmpSearchResult.cbCardCount[i] < (tmpSearchResult.cbCardCount[i]-cbNeedDelCount)/3 ) cbNeedDelCount += 3; //不够连牌 if( (tmpSearchResult.cbCardCount[i]-cbNeedDelCount)/3 < 2 ) { //废除连牌 continue; } //拆分连牌 RemoveCard( tmpSearchResult.cbResultCard[i],cbNeedDelCount,tmpSearchResult.cbResultCard[i], tmpSearchResult.cbCardCount[i] ); tmpSearchResult.cbCardCount[i] -= cbNeedDelCount; } if( pSearchCardResult == NULL ) return 1; //删除连牌 memcpy( cbTmpCardData,cbHandCardData,sizeof(uint8)*cbHandCardCount ); assert( RemoveCard( tmpSearchResult.cbResultCard[i],tmpSearchResult.cbCardCount[i], cbTmpCardData,cbTmpCardCount ) ); cbTmpCardCount -= tmpSearchResult.cbCardCount[i]; //组合飞机 uint8 cbNeedCount = tmpSearchResult.cbCardCount[i]/3; assert(cbNeedCount <= cbTmpCardCount); uint8 cbResultCount = tmpSingleWing.cbSearchCount++; memcpy( tmpSingleWing.cbResultCard[cbResultCount],tmpSearchResult.cbResultCard[i], sizeof(uint8)*tmpSearchResult.cbCardCount[i] ); memcpy( &tmpSingleWing.cbResultCard[cbResultCount][tmpSearchResult.cbCardCount[i]], &cbTmpCardData[cbTmpCardCount-cbNeedCount],sizeof(uint8)*cbNeedCount ); tmpSingleWing.cbCardCount[i] = tmpSearchResult.cbCardCount[i]+cbNeedCount; //不够带翅膀 if( cbTmpCardCount < tmpSearchResult.cbCardCount[i]/3*2 ) { uint8 cbNeedDelCount = 3; while( cbTmpCardCount+cbNeedDelCount-tmpSearchResult.cbCardCount[i] < (tmpSearchResult.cbCardCount[i]-cbNeedDelCount)/3*2 ) cbNeedDelCount += 3; //不够连牌 if( (tmpSearchResult.cbCardCount[i]-cbNeedDelCount)/3 < 2 ) { //废除连牌 continue; } //拆分连牌 RemoveCard( tmpSearchResult.cbResultCard[i],cbNeedDelCount,tmpSearchResult.cbResultCard[i], tmpSearchResult.cbCardCount[i] ); tmpSearchResult.cbCardCount[i] -= cbNeedDelCount; //重新删除连牌 memcpy( cbTmpCardData,cbHandCardData,sizeof(uint8)*cbHandCardCount ); assert( RemoveCard( tmpSearchResult.cbResultCard[i],tmpSearchResult.cbCardCount[i], cbTmpCardData,cbTmpCardCount ) ); cbTmpCardCount = cbHandCardCount-tmpSearchResult.cbCardCount[i]; } //分析牌 tagAnalyseResult TmpResult = {}; AnalysebCardData( cbTmpCardData,cbTmpCardCount,TmpResult ); //提取翅膀 uint8 cbDistillCard[DDZ_MAX_COUNT] = {}; uint8 cbDistillCount = 0; uint8 cbLineCount = tmpSearchResult.cbCardCount[i]/3; for( uint8 j = 1; j < CountArray(TmpResult.cbBlockCount); j++ ) { if( TmpResult.cbBlockCount[j] > 0 ) { if( j+1 == 2 && TmpResult.cbBlockCount[j] >= cbLineCount ) { uint8 cbTmpBlockCount = TmpResult.cbBlockCount[j]; memcpy( cbDistillCard,&TmpResult.cbCardData[j][(cbTmpBlockCount-cbLineCount)*(j+1)], sizeof(uint8)*(j+1)*cbLineCount ); cbDistillCount = (j+1)*cbLineCount; break; } else { for( uint8 k = 0; k < TmpResult.cbBlockCount[j]; k++ ) { uint8 cbTmpBlockCount = TmpResult.cbBlockCount[j]; memcpy( &cbDistillCard[cbDistillCount],&TmpResult.cbCardData[j][(cbTmpBlockCount-k-1)*(j+1)], sizeof(uint8)*2 ); cbDistillCount += 2; //提取完成 if( cbDistillCount == 2*cbLineCount ) break; } } } //提取完成 if( cbDistillCount == 2*cbLineCount ) break; } //提取完成 if( cbDistillCount == 2*cbLineCount ) { //复制翅膀 cbResultCount = tmpDoubleWing.cbSearchCount++; memcpy( tmpDoubleWing.cbResultCard[cbResultCount],tmpSearchResult.cbResultCard[i], sizeof(uint8)*tmpSearchResult.cbCardCount[i] ); memcpy( &tmpDoubleWing.cbResultCard[cbResultCount][tmpSearchResult.cbCardCount[i]], cbDistillCard,sizeof(uint8)*cbDistillCount ); tmpDoubleWing.cbCardCount[i] = tmpSearchResult.cbCardCount[i]+cbDistillCount; } } //复制结果 for( uint8 i = 0; i < tmpDoubleWing.cbSearchCount; i++ ) { uint8 cbResultCount = pSearchCardResult->cbSearchCount++; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpDoubleWing.cbResultCard[i], sizeof(uint8)*tmpDoubleWing.cbCardCount[i] ); pSearchCardResult->cbCardCount[cbResultCount] = tmpDoubleWing.cbCardCount[i]; } for( uint8 i = 0; i < tmpSingleWing.cbSearchCount; i++ ) { uint8 cbResultCount = pSearchCardResult->cbSearchCount++; memcpy( pSearchCardResult->cbResultCard[cbResultCount],tmpSingleWing.cbResultCard[i], sizeof(uint8)*tmpSingleWing.cbCardCount[i] ); pSearchCardResult->cbCardCount[cbResultCount] = tmpSingleWing.cbCardCount[i]; } } return pSearchCardResult==NULL?0:pSearchCardResult->cbSearchCount; } //////////////////////////////////////////////////////////////////////////////////