#include "StdAfx.h" #include "GameLogic.h" #include "math.h" ////////////////////////////////////////////////////////////////////////// //静态变量 bool CChiHuRight::m_bInit = false; DWORD CChiHuRight::m_dwRightMask[MAX_RIGHT_COUNT]; //构造函数 CChiHuRight::CChiHuRight() { ZeroMemory( m_dwRight,sizeof(m_dwRight) ); if( !m_bInit ) { m_bInit = true; for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ ) { if( 0 == i ) m_dwRightMask[i] = 0; else m_dwRightMask[i] = (DWORD(pow(2.0,i-1)))<<28; } } } //赋值符重载 CChiHuRight & CChiHuRight::operator = ( DWORD dwRight ) { DWORD dwOtherRight = 0; //验证权位 if( !IsValidRight( dwRight ) ) { //验证取反权位 ASSERT( IsValidRight( ~dwRight ) ); if( !IsValidRight( ~dwRight ) ) return *this; dwRight = ~dwRight; dwOtherRight = MASK_CHI_HU_RIGHT; } for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ ) { if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) ) m_dwRight[i] = dwRight&MASK_CHI_HU_RIGHT; else m_dwRight[i] = dwOtherRight; } return *this; } //与等于 CChiHuRight & CChiHuRight::operator &= ( DWORD dwRight ) { bool bNavigate = false; //验证权位 if( !IsValidRight( dwRight ) ) { //验证取反权位 ASSERT( IsValidRight( ~dwRight ) ); if( !IsValidRight( ~dwRight ) ) return *this; //调整权位 DWORD dwHeadRight = (~dwRight)&0xF0000000; DWORD dwTailRight = dwRight&MASK_CHI_HU_RIGHT; dwRight = dwHeadRight|dwTailRight; bNavigate = true; } for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ ) { if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) ) { m_dwRight[i] &= (dwRight&MASK_CHI_HU_RIGHT); } else if( !bNavigate ) m_dwRight[i] = 0; } return *this; } //或等于 CChiHuRight & CChiHuRight::operator |= ( DWORD dwRight ) { //验证权位 if( !IsValidRight( dwRight ) ) return *this; for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ ) { if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) ) m_dwRight[i] |= (dwRight&MASK_CHI_HU_RIGHT); } return *this; } //与 CChiHuRight CChiHuRight::operator & ( DWORD dwRight ) { CChiHuRight chr = *this; return (chr &= dwRight); } //与 CChiHuRight CChiHuRight::operator & ( DWORD dwRight ) const { CChiHuRight chr = *this; return (chr &= dwRight); } //或 CChiHuRight CChiHuRight::operator | ( DWORD dwRight ) { CChiHuRight chr = *this; return chr |= dwRight; } //或 CChiHuRight CChiHuRight::operator | ( DWORD dwRight ) const { CChiHuRight chr = *this; return chr |= dwRight; } //是否权位为空 bool CChiHuRight::IsEmpty() { for( BYTE i = 0; i < CountArray(m_dwRight); i++ ) if( m_dwRight[i] ) return false; return true; } //设置权位为空 void CChiHuRight::SetEmpty() { ZeroMemory( m_dwRight,sizeof(m_dwRight) ); return; } //获取权位数值 BYTE CChiHuRight::GetRightData( DWORD dwRight[], BYTE cbMaxCount ) { ASSERT( cbMaxCount >= CountArray(m_dwRight) ); if( cbMaxCount < CountArray(m_dwRight) ) return 0; CopyMemory( dwRight,m_dwRight,sizeof(DWORD)*CountArray(m_dwRight) ); return CountArray(m_dwRight); } //设置权位数值 bool CChiHuRight::SetRightData( const DWORD dwRight[], BYTE cbRightCount ) { ASSERT( cbRightCount <= CountArray(m_dwRight) ); if( cbRightCount > CountArray(m_dwRight) ) return false; ZeroMemory( m_dwRight,sizeof(m_dwRight) ); CopyMemory( m_dwRight,dwRight,sizeof(DWORD)*cbRightCount ); return true; } //检查仅位是否正确 bool CChiHuRight::IsValidRight( DWORD dwRight ) { DWORD dwRightHead = dwRight & 0xF0000000; for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ ) if( m_dwRightMask[i] == dwRightHead ) return true; return false; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //静态变量 //扑克数据 const BYTE CGameLogic::m_cbCardDataArray[MAX_REPERTORY]= { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, //万子 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, //万子 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, //万子 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, //万子 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, //索子 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, //索子 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, //索子 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, //索子 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, //同子 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, //同子 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, //同子 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, //同子 }; ////////////////////////////////////////////////////////////////////////// //构造函数 CGameLogic::CGameLogic() { m_cbMagicIndex = MAX_INDEX; } //析构函数 CGameLogic::~CGameLogic() { } //混乱扑克 void CGameLogic::RandCardData(BYTE cbCardData[], BYTE cbMaxCount) { //混乱准备 BYTE cbCardDataTemp[CountArray(m_cbCardDataArray)]; CopyMemory(cbCardDataTemp,m_cbCardDataArray,sizeof(m_cbCardDataArray)); //混乱扑克 BYTE cbRandCount=0,cbPosition=0; do { cbPosition=rand()%(cbMaxCount-cbRandCount); cbCardData[cbRandCount++]=cbCardDataTemp[cbPosition]; cbCardDataTemp[cbPosition]=cbCardDataTemp[cbMaxCount-cbRandCount]; } while (cbRandCount0); //删除扑克 BYTE cbRemoveIndex=SwitchToCardIndex(cbRemoveCard); if (cbCardIndex[cbRemoveIndex]>0) { cbCardIndex[cbRemoveIndex]--; return true; } //失败效验 ASSERT(FALSE); return false; } //删除扑克 bool CGameLogic::RemoveCard(BYTE cbCardIndex[MAX_INDEX], const BYTE cbRemoveCard[], BYTE cbRemoveCount) { //删除扑克 for (BYTE i=0;i0); //删除扑克 BYTE cbRemoveIndex=SwitchToCardIndex(cbRemoveCard[i]); if (cbCardIndex[cbRemoveIndex]==0) { //错误断言 ASSERT(FALSE); //还原删除 for (BYTE j=0;jCountArray(cbTempCardData)) return false; CopyMemory(cbTempCardData,cbCardData,cbCardCount*sizeof(cbCardData[0])); //置零扑克 for (BYTE i=0;i>4; return (((cbValue>=1)&&(cbValue<=9)&&(cbColor<=2))||((cbValue>=1)&&(cbValue<=7)&&(cbColor==3))); } //扑克数目 BYTE CGameLogic::GetCardCount(const BYTE cbCardIndex[MAX_INDEX]) { //数目统计 BYTE cbCardCount=0; for (BYTE i=0;i 0 ); //杠上花 if( !(ChiHuRight&CHR_GANG_KAI).IsEmpty() ) wFanShu *= 2; //杠上炮 if( !(ChiHuRight&CHR_GANG_SHANG_PAO).IsEmpty() ) wFanShu *= 2; return wFanShu; } //吃牌判断 BYTE CGameLogic::EstimateEatCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard) { //参数效验 ASSERT(IsValidCard(cbCurrentCard)); //过滤判断 if ( cbCurrentCard>=0x31 || IsMagicCard(cbCurrentCard) ) return WIK_NULL; //变量定义 BYTE cbExcursion[3]={0,1,2}; BYTE cbItemKind[3]={WIK_LEFT,WIK_CENTER,WIK_RIGHT}; //吃牌判断 BYTE cbEatKind=0,cbFirstIndex=0; BYTE cbCurrentIndex=SwitchToCardIndex(cbCurrentCard); for (BYTE i=0;i=cbExcursion[i])&&((cbValueIndex-cbExcursion[i])<=6)) { //吃牌判断 cbFirstIndex=cbCurrentIndex-cbExcursion[i]; //吃牌不能包含有王霸 if( m_cbMagicIndex != MAX_INDEX && m_cbMagicIndex >= cbFirstIndex && m_cbMagicIndex <= cbFirstIndex+2 ) continue; if ((cbCurrentIndex!=cbFirstIndex)&&(cbCardIndex[cbFirstIndex]==0)) continue; if ((cbCurrentIndex!=(cbFirstIndex+1))&&(cbCardIndex[cbFirstIndex+1]==0)) continue; if ((cbCurrentIndex!=(cbFirstIndex+2))&&(cbCardIndex[cbFirstIndex+2]==0)) continue; //设置类型 cbEatKind|=cbItemKind[i]; } } return cbEatKind; } //碰牌判断 BYTE CGameLogic::EstimatePengCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard) { //参数效验 ASSERT(IsValidCard(cbCurrentCard)); //过滤判断 if ( IsMagicCard(cbCurrentCard) ) return WIK_NULL; //碰牌判断 return (cbCardIndex[SwitchToCardIndex(cbCurrentCard)]>=2)?WIK_PENG:WIK_NULL; } //杠牌判断 BYTE CGameLogic::EstimateGangCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard) { //参数效验 ASSERT(IsValidCard(cbCurrentCard)); //过滤判断 if ( IsMagicCard(cbCurrentCard) ) return WIK_NULL; //杠牌判断 return (cbCardIndex[SwitchToCardIndex(cbCurrentCard)]==3)?WIK_GANG:WIK_NULL; } //杠牌分析 BYTE CGameLogic::AnalyseGangCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, tagGangCardResult & GangCardResult) { //设置变量 BYTE cbActionMask=WIK_NULL; ZeroMemory(&GangCardResult,sizeof(GangCardResult)); //手上杠牌 for (BYTE i=0;i0) { // cbChiHuKind = WIK_CHI_HU; //牌型分析 for (INT_PTR i=0;i>4)*9+(cbCardData&MASK_VALUE)-1; } //扑克转换 BYTE CGameLogic::SwitchToCardData(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCardData[MAX_COUNT]) { //转换扑克 BYTE cbPosition=0; //钻牌 if( m_cbMagicIndex != MAX_INDEX ) { for( BYTE i = 0; i < cbCardIndex[m_cbMagicIndex]; i++ ) cbCardData[cbPosition++] = SwitchToCardData(m_cbMagicIndex); } for (BYTE i=0;i=2)&&(cbCardCount<=MAX_COUNT)&&((cbCardCount-2)%3==0)); if ((cbCardCount<2)||(cbCardCount>MAX_COUNT)||((cbCardCount-2)%3!=0)) return false; //变量定义 BYTE cbKindItemCount=0; tagKindItem KindItem[27*2+7+14]; ZeroMemory(KindItem,sizeof(KindItem)); //需求判断 BYTE cbLessKindItem=(cbCardCount-2)/3; ASSERT((cbLessKindItem+cbWeaveCount)==4); //单吊判断 if (cbLessKindItem==0) { //效验参数 ASSERT((cbCardCount==2)&&(cbWeaveCount==4)); //牌眼判断 for (BYTE i=0;i=3) { for (BYTE i=0;i=3) { ASSERT( cbKindItemCount < CountArray(KindItem) ); KindItem[cbKindItemCount].cbCardIndex[0]=i; KindItem[cbKindItemCount].cbCardIndex[1]=i; KindItem[cbKindItemCount].cbCardIndex[2]=i; KindItem[cbKindItemCount].cbWeaveKind=WIK_PENG; KindItem[cbKindItemCount].cbCenterCard=SwitchToCardData(i); KindItem[cbKindItemCount].cbValidIndex[0] = cbMagicCardIndex[i]>0?i:m_cbMagicIndex; KindItem[cbKindItemCount].cbValidIndex[1] = cbMagicCardIndex[i]>1?i:m_cbMagicIndex; KindItem[cbKindItemCount].cbValidIndex[2] = cbMagicCardIndex[i]>2?i:m_cbMagicIndex; cbKindItemCount++; if(cbMagicCardIndex[i]+cbMagicCardCount>=6) { ASSERT( cbKindItemCount < CountArray(KindItem) ); KindItem[cbKindItemCount].cbCardIndex[0]=i; KindItem[cbKindItemCount].cbCardIndex[1]=i; KindItem[cbKindItemCount].cbCardIndex[2]=i; KindItem[cbKindItemCount].cbWeaveKind=WIK_PENG; KindItem[cbKindItemCount].cbCenterCard=SwitchToCardData(i); KindItem[cbKindItemCount].cbValidIndex[0] = cbMagicCardIndex[i]>3?i:m_cbMagicIndex; KindItem[cbKindItemCount].cbValidIndex[1] = m_cbMagicIndex; KindItem[cbKindItemCount].cbValidIndex[2] = m_cbMagicIndex; cbKindItemCount++; } } //连牌判断 if ((i<(MAX_INDEX-9))&&((i%9)<7)) { //只要财神牌数加上3个顺序索引的牌数大于等于3,则进行组合 if( cbMagicCardCount+cbMagicCardIndex[i]+cbMagicCardIndex[i+1]+cbMagicCardIndex[i+2] >= 3 ) { BYTE cbIndex[3] = { i==m_cbMagicIndex?0:cbMagicCardIndex[i],(i+1)==m_cbMagicIndex?0:cbMagicCardIndex[i+1], (i+2)==m_cbMagicIndex?0:cbMagicCardIndex[i+2] }; int nMagicCountTemp = cbMagicCardCount; BYTE cbValidIndex[3]; while( nMagicCountTemp+cbIndex[0]+cbIndex[1]+cbIndex[2] >= 3 ) { for( BYTE j = 0; j < CountArray(cbIndex); j++ ) { if( cbIndex[j] > 0 ) { cbIndex[j]--; cbValidIndex[j] = i+j; } else { nMagicCountTemp--; cbValidIndex[j] = m_cbMagicIndex; } } if( nMagicCountTemp >= 0 ) { ASSERT( cbKindItemCount < CountArray(KindItem) ); KindItem[cbKindItemCount].cbCardIndex[0]=i; KindItem[cbKindItemCount].cbCardIndex[1]=i+1; KindItem[cbKindItemCount].cbCardIndex[2]=i+2; KindItem[cbKindItemCount].cbWeaveKind=WIK_LEFT; KindItem[cbKindItemCount].cbCenterCard=SwitchToCardData(i); CopyMemory( KindItem[cbKindItemCount].cbValidIndex,cbValidIndex,sizeof(cbValidIndex) ); cbKindItemCount++; } else break; } } } } } //组合分析 if (cbKindItemCount>=cbLessKindItem) { //变量定义 BYTE cbCardIndexTemp[MAX_INDEX]; ZeroMemory(cbCardIndexTemp,sizeof(cbCardIndexTemp)); //变量定义 BYTE cbIndex[4]={0,1,2,3}; tagKindItem * pKindItem[4]; ZeroMemory(&pKindItem,sizeof(pKindItem)); //开始组合 do { //设置变量 CopyMemory(cbCardIndexTemp,cbCardIndex,sizeof(cbCardIndexTemp)); for (BYTE i=0;icbValidIndex[i%3]; if (cbCardIndexTemp[cbCardIndex]==0) { bEnoughCard=false; break; } else cbCardIndexTemp[cbCardIndex]--; } //胡牌判断 if (bEnoughCard==true) { //牌眼判断 BYTE cbCardEye=0; bool bMagicEye = false; for (BYTE i=0;icbWeaveKind; AnalyseItem.cbCenterCard[i+cbWeaveCount]=pKindItem[i]->cbCenterCard; AnalyseItem.cbCardData[cbWeaveCount+i][0] = SwitchToCardData(pKindItem[i]->cbValidIndex[0]); AnalyseItem.cbCardData[cbWeaveCount+i][1] = SwitchToCardData(pKindItem[i]->cbValidIndex[1]); AnalyseItem.cbCardData[cbWeaveCount+i][2] = SwitchToCardData(pKindItem[i]->cbValidIndex[2]); } //设置牌眼 AnalyseItem.cbCardEye=cbCardEye; AnalyseItem.bMagicEye = bMagicEye; //插入结果 AnalyseItemArray.Add(AnalyseItem); } } //设置索引 if (cbIndex[cbLessKindItem-1]==(cbKindItemCount-1)) { BYTE i=cbLessKindItem-1; for ( ;i>0;i--) { if ((cbIndex[i-1]+1)!=cbIndex[i]) { BYTE cbNewIndex=cbIndex[i-1]; for (BYTE j=(i-1);j0); } //钻牌 bool CGameLogic::IsMagicCard( BYTE cbCardData ) { if( m_cbMagicIndex != MAX_INDEX ) return SwitchToCardIndex(cbCardData) == m_cbMagicIndex; return false; } //排序,根据牌值排序 bool CGameLogic::SortCardList( BYTE cbCardData[MAX_COUNT], BYTE cbCardCount ) { //数目过虑 if (cbCardCount==0||cbCardCount>MAX_COUNT) return false; //排序操作 bool bSorted=true; BYTE cbSwitchData=0,cbLast=cbCardCount-1; do { bSorted=true; for (BYTE i=0;icbCardData[i+1]) { //设置标志 bSorted=false; //扑克数据 cbSwitchData=cbCardData[i]; cbCardData[i]=cbCardData[i+1]; cbCardData[i+1]=cbSwitchData; } } cbLast--; } while(bSorted==false); return true; } /* // 胡法分析函数 */ //大对子 bool CGameLogic::IsPengPeng( const tagAnalyseItem *pAnalyseItem ) { for( BYTE i = 0; i < CountArray(pAnalyseItem->cbWeaveKind); i++ ) { if( pAnalyseItem->cbWeaveKind[i]&(WIK_LEFT|WIK_CENTER|WIK_RIGHT) ) return false; } return true; } //清一色牌 bool CGameLogic::IsQingYiSe(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], const BYTE cbItemCount,const BYTE cbCurrentCard) { //胡牌判断 BYTE cbCardColor=0xFF; for (BYTE i=0;i 0 ); //检查组合 ASSERT( cbItemCount > 0 ); cbCardColor = WeaveItem[0].cbCenterCard&MASK_COLOR; } if((cbCurrentCard&MASK_COLOR)!=cbCardColor && !IsMagicCard(cbCurrentCard) ) return false; //组合判断 for (BYTE i=0;i cbCardIndexTemp[m_cbMagicIndex] || m_cbMagicIndex == MAX_INDEX && cbReplaceCount > 0 ) return false; return true; } //带幺 bool CGameLogic::IsDaiYao( const tagAnalyseItem *pAnalyseItem ) { //检查牌眼 BYTE cbCardValue = pAnalyseItem->cbCardEye&MASK_VALUE; if( cbCardValue != 1 && cbCardValue != 9 ) return false; for( BYTE i = 0; i < CountArray(pAnalyseItem->cbWeaveKind); i++ ) { if( pAnalyseItem->cbWeaveKind[i]&(WIK_LEFT|WIK_CENTER|WIK_RIGHT) ) { BYTE j = 0; for( ; j < 3; j++ ) { cbCardValue = pAnalyseItem->cbCardData[i][j]&MASK_VALUE; if( cbCardValue == 1 || cbCardValue == 9 ) break; } if( j == 3 ) return false; } else { cbCardValue = pAnalyseItem->cbCenterCard[i]&MASK_VALUE; if( cbCardValue != 1 && cbCardValue != 9 ) return false; } } return true; } //将对 bool CGameLogic::IsJiangDui( const tagAnalyseItem *pAnalyseItem ) { //是否大对子 if( !IsPengPeng(pAnalyseItem) ) return false; //检查牌眼 BYTE cbCardValue = pAnalyseItem->cbCardEye&MASK_VALUE; if( cbCardValue != 2 && cbCardValue != 5 && cbCardValue != 8 ) return false; for( BYTE i = 0; i < CountArray(pAnalyseItem->cbWeaveKind); i++ ) { if( pAnalyseItem->cbWeaveKind[i]&(WIK_LEFT|WIK_CENTER|WIK_RIGHT) ) { BYTE j = 0; for( ; j < 3; j++ ) { cbCardValue = pAnalyseItem->cbCardData[i][j]&MASK_VALUE; if( cbCardValue == 2 || cbCardValue == 5 || cbCardValue == 8 ) break; } if( j == 3 ) return false; } else { cbCardValue = pAnalyseItem->cbCenterCard[i]&MASK_VALUE; if( cbCardValue != 2 && cbCardValue != 5 && cbCardValue != 8 ) return false; } } return true; } //是否花猪 bool CGameLogic::IsHuaZhu( const BYTE cbCardIndex[], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount ) { BYTE cbColor[3] = { 0,0,0 }; for( BYTE i = 0; i < MAX_INDEX; i++ ) { if( cbCardIndex[i] > 0 ) { BYTE cbCardColor = SwitchToCardData(i)&MASK_COLOR; cbColor[cbCardColor>>4]++; i = (i/9+1)*9-1; } } for( BYTE i = 0; i < cbWeaveCount; i++ ) { BYTE cbCardColor = WeaveItem[i].cbCenterCard&MASK_COLOR; cbColor[cbCardColor>>4]++; } //缺一门就不是花猪 for( BYTE i = 0; i < CountArray(cbColor); i++ ) if( cbColor[i] == 0 ) return false; return true; } //////////////////////////////////////////////////////////////////////////