#include "StdAfx.h" #include "TableFrameSinkOther.h" ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //构造函数 CTableFrameSinkOther::CTableFrameSinkOther() :m_GameLogic(this) { //游戏变量 bGameType = 0; m_lSiceCount=0; m_wBankerUser=INVALID_CHAIR; ZeroMemory(m_cbCardIndex,sizeof(m_cbCardIndex)); ZeroMemory(m_bTrustee,sizeof(m_bTrustee)); // ZeroMemory( m_GangScore,sizeof(m_GangScore) ); ZeroMemory( m_cbGenCount,sizeof(m_cbGenCount) ); ZeroMemory( m_bPlayStatus,sizeof(m_bPlayStatus) ); ZeroMemory(m_lGameScore, sizeof(m_lGameScore)); ZeroMemory(m_lGameTatolScore, sizeof(m_lGameTatolScore)); ZeroMemory(m_HuPai, sizeof(m_HuPai)); // ZeroMemory( m_lFangPao, sizeof(m_lFangPao)); // ZeroMemory( m_lDianPao, sizeof(m_lDianPao)); // ZeroMemory( m_lMingGang, sizeof(m_lMingGang)); // ZeroMemory( m_lAnGang, sizeof(m_lAnGang)); // ZeroMemory( m_lChaDaJiao, sizeof(m_lChaDaJiao)); ZeroMemory(m_cbHuanSanZhang, sizeof(m_cbHuanSanZhang)); //换三张 ZeroMemory(m_HuanSanZhangData, sizeof(m_HuanSanZhangData)); ZeroMemory(YouXiFan, sizeof(YouXiFan)); ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数 ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 m_cbWinCount = 0; memset( m_wWinOrder,INVALID_CHAIR,sizeof(m_wWinOrder) ); ZeroMemory( m_lGameTax,sizeof(m_lGameTax) ); //ZeroMemory( m_wLostFanShu,sizeof(m_wLostFanShu) ); //出牌信息 m_cbOutCardData=0; m_cbOutCardCount=0; m_wOutCardUser=INVALID_CHAIR; ZeroMemory(m_cbDiscardCard,sizeof(m_cbDiscardCard)); ZeroMemory(m_cbDiscardCount,sizeof(m_cbDiscardCount)); ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData)); ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount)); //ZeroMemory(m_OutLaiZi, sizeof(m_OutLaiZi)); //堆立信息 m_wHeapHand = INVALID_CHAIR; m_wHeapTail = INVALID_CHAIR; ZeroMemory(m_cbHeapCardInfo,sizeof(m_cbHeapCardInfo)); //发牌信息 m_cbSendCardData=0; m_cbSendCardCount=0; m_cbLeftCardCount=0; ZeroMemory(m_cbRepertoryCard,sizeof(m_cbRepertoryCard)); //运行变量 m_cbProvideCard=0; m_wResumeUser=INVALID_CHAIR; m_wCurrentUser=INVALID_CHAIR; m_wProvideUser=INVALID_CHAIR; //状态变量 m_bSendStatus=false; m_bGangStatus = false; m_bGangOutStatus = false; ZeroMemory(m_bEnjoinChiHu,sizeof(m_bEnjoinChiHu)); ZeroMemory(m_bEnjoinChiPeng,sizeof(m_bEnjoinChiPeng)); m_bDuoPao = false;//一炮多向 m_bQiangGang = false;//抢杠胡标示位 //用户状态 ZeroMemory(m_bResponse,sizeof(m_bResponse)); ZeroMemory(m_cbUserAction,sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard,sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction,sizeof(m_cbPerformAction)); ZeroMemory(m_AnGangNum, sizeof(m_AnGangNum)); ZeroMemory(m_MingGangNum, sizeof(m_MingGangNum)); ZeroMemory(m_JiFenCount, sizeof(m_JiFenCount)); //组合扑克 ZeroMemory(m_WeaveItemArray,sizeof(m_WeaveItemArray)); ZeroMemory(m_cbWeaveItemCount,sizeof(m_cbWeaveItemCount)); //结束信息 m_cbChiHuCard=0; ZeroMemory( m_dwChiHuKind,sizeof(m_dwChiHuKind)); ZeroMemory(m_HuPai, sizeof(m_HuPai)); ZeroMemory(m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui)); //组件变量 m_pITableFrame=NULL; m_pGameServiceOption=NULL; //m_bReduceBean = false; ZeroMemory(m_ChiHuRight, sizeof(m_ChiHuRight)); ZeroMemory(m_wChiHuCard, sizeof(m_wChiHuCard)); ZeroMemory(&m_cbLastAction, sizeof(m_cbLastAction)); for (int i = 0; i < GAME_PLAYER; ++i) { //m_cbDingQue[i] = INVALID_BYTE; m_lUserTmpScore[i] = TEMP_MAX_SCORE; //用户临时积分 } return; } //析构函数 CTableFrameSinkOther::~CTableFrameSinkOther(void) { } //接口查询 void * CTableFrameSinkOther::QueryInterface(const IID & Guid, DWORD dwQueryVer) { //QUERYINTERFACE(ITableFrameSink,Guid,dwQueryVer); if ((Guid == IID_ITableFrameSink) && (InterfaceVersionCompare(dwQueryVer, VER_ITableFrameSinkOther))) return static_cast(this); QUERYINTERFACE(ITableUserAction,Guid,dwQueryVer); //QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink,Guid,dwQueryVer); if ((Guid == IID_IUnknownEx) && (InterfaceVersionCompare(dwQueryVer, VER_IUnknownEx))) return static_cast(static_cast(this)); return NULL; } //初始化 bool CTableFrameSinkOther::Initialization(IUnknownEx * pIUnknownEx) { //查询接口 ASSERT(pIUnknownEx!=NULL); m_pITableFrame = ((pIUnknownEx == NULL) ? NULL : ((ITableFrame *)pIUnknownEx->QueryInterface(IID_ITableFrame, VER_ITableFrame))); if (m_pITableFrame==NULL) return false; //获取参数 m_pGameServiceOption=m_pITableFrame->GetGameServiceOption(); ASSERT(m_pGameServiceOption!=NULL); //开始模式 m_pITableFrame->SetStartMode(START_MODE_FULL_READY); return true; } //复位桌子 VOID CTableFrameSinkOther::RepositionSink() { //游戏变量 m_lSiceCount=0; ZeroMemory(m_cbCardIndex,sizeof(m_cbCardIndex)); ZeroMemory(m_bTrustee,sizeof(m_bTrustee)); // ZeroMemory( m_GangScore,sizeof(m_GangScore) ); ZeroMemory( m_cbGenCount,sizeof(m_cbGenCount) ); ZeroMemory( m_lGameScore,sizeof(m_lGameScore) ); ZeroMemory( m_bPlayStatus,sizeof(m_bPlayStatus) ); m_cbWinCount = 0; memset( m_wWinOrder,INVALID_CHAIR,sizeof(m_wWinOrder) ); ZeroMemory( m_lGameTax,sizeof(m_lGameTax) ); //ZeroMemory( m_wLostFanShu,sizeof(m_wLostFanShu) ); ZeroMemory(m_cbHuanSanZhang, sizeof(m_cbHuanSanZhang)); //换三张 ZeroMemory(m_HuanSanZhangData, sizeof(m_HuanSanZhangData)); ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数 ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 ZeroMemory(m_AnGangNum, sizeof(m_AnGangNum)); ZeroMemory(m_MingGangNum, sizeof(m_MingGangNum)); ZeroMemory(m_JiFenCount, sizeof(m_JiFenCount)); //出牌信息 m_cbOutCardData=0; m_cbOutCardCount=0; m_wOutCardUser=INVALID_CHAIR; ZeroMemory(m_cbDiscardCard,sizeof(m_cbDiscardCard)); ZeroMemory(m_cbDiscardCount,sizeof(m_cbDiscardCount)); ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData)); ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount)); //ZeroMemory(m_cbDiscardWuYongCard, sizeof(m_cbDiscardWuYongCard)); //ZeroMemory(m_cbDiscardWuYongCount, sizeof(m_cbDiscardWuYongCount)); //ZeroMemory(m_OutLaiZi, sizeof(m_OutLaiZi)); ZeroMemory(m_HuPai, sizeof(m_HuPai));//胡牌重制 //堆立信息 m_wHeapHand = INVALID_CHAIR; m_wHeapTail = INVALID_CHAIR; ZeroMemory(m_cbHeapCardInfo,sizeof(m_cbHeapCardInfo)); //发牌信息 m_cbSendCardData=0; m_cbSendCardCount=0; m_cbLeftCardCount=0; ZeroMemory(m_cbRepertoryCard,sizeof(m_cbRepertoryCard)); //运行变量 m_cbProvideCard=0; m_wResumeUser=INVALID_CHAIR; m_wCurrentUser=INVALID_CHAIR; m_wProvideUser=INVALID_CHAIR; m_wBankerUser = INVALID_CHAIR; m_bDuoPao = false;//一炮多向 m_bQiangGang = false;//抢杠胡标示位 //状态变量 m_bSendStatus=false; m_bGangStatus = false; m_bGangOutStatus = false; ZeroMemory(m_bEnjoinChiHu,sizeof(m_bEnjoinChiHu)); ZeroMemory(m_bEnjoinChiPeng,sizeof(m_bEnjoinChiPeng)); //用户状态 ZeroMemory(m_bResponse,sizeof(m_bResponse)); ZeroMemory(m_cbUserAction,sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard,sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction,sizeof(m_cbPerformAction)); //组合扑克 ZeroMemory(m_WeaveItemArray,sizeof(m_WeaveItemArray)); ZeroMemory(m_cbWeaveItemCount,sizeof(m_cbWeaveItemCount)); //结束信息 m_cbChiHuCard=0; ZeroMemory(m_dwChiHuKind, sizeof(m_dwChiHuKind)); ZeroMemory(m_wChiHuCard, sizeof(m_wChiHuCard)); ZeroMemory(&m_cbLastAction, sizeof(m_cbLastAction)); ZeroMemory(m_ChiHuRight, sizeof(m_ChiHuRight)); return; } bool CTableFrameSinkOther::RepayRecordStart() { m_bReplayRecordStart = true; for (GameRecordPacket grp : m_UserReplayRecord) { delete[] grp.pData; grp.pData = nullptr; } m_UserReplayRecord.clear();//不会释放内存 m_UserReplayRecord.shrink_to_fit();//释放内存 return true; } bool CTableFrameSinkOther::RepayRecordEnd() { if (!m_bReplayRecordStart) return false; m_bReplayRecordStart = false; CMD_GR_ReplayRecordResp urr; ZeroMemory(&urr, sizeof(CMD_GR_ReplayRecordResp)); urr.m_UUID = 0; urr.m_UserId = 0; urr.m_startTime = time(0); urr.m_endTime = time(0); urr.m_gameconfig = m_gameConfig; //urr.m_UserId = pIServerUserItem->GetUserID(); for (int j = 0; j < GAME_PLAYER; ++j) { IServerUserItem * pIServerUserItem = m_pITableFrame->GetTableUserItem(j); if ((pIServerUserItem == NULL) /*|| (pIServerUserItem->IsClientReady() == false)*/) continue; auto& chairInfo = urr.m_chairList[j]; chairInfo.dwUserId = pIServerUserItem->GetUserID(); chairInfo.wChairId = pIServerUserItem->GetChairID(); lstrcpy(chairInfo.userName, pIServerUserItem->GetNickName()); lstrcpy(chairInfo.headUrl, pIServerUserItem->GetUserInfo ()->szHeadUrl); } urr.m_recordCount = m_UserReplayRecord.size(); int GameRecordPacketSize = sizeof(GameRecordPacket) - sizeof(void*);//每条记录头长度 int totalSize = sizeof(CMD_GR_ReplayRecordResp);//总记录头长度 for (GameRecordPacket grp : m_UserReplayRecord) totalSize += (GameRecordPacketSize + grp.wSize); char* replyRecordData = new char[totalSize]; ZeroMemory(replyRecordData, totalSize); CopyMemory(replyRecordData, &urr, sizeof(CMD_GR_ReplayRecordResp)); int nOffset = sizeof(CMD_GR_ReplayRecordResp); for (GameRecordPacket grp : m_UserReplayRecord) { CopyMemory(replyRecordData + nOffset, &grp, GameRecordPacketSize); nOffset += GameRecordPacketSize; CopyMemory(replyRecordData + nOffset, grp.pData, grp.wSize); nOffset += grp.wSize; } m_pITableFrame->SaveReplayRecord(replyRecordData, totalSize); //delete replyRecordData;不能删除,已托管给SaveReplayRecord函数 return true; } bool CTableFrameSinkOther::RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize) { //获取用户 //char* pNewData = new char[wSize + sizeof(GameRecordPacket)]; //memcpy(pNewData, pData, wSize); //修改BYJN 疑似内存溢出 GameRecordPacket record; record.wSize = wSize; record.wChairID = wChairID; record.wSubCmdID = wSubCmdId; record.wMainCmdID = MDM_GF_GAME; record.pData = new char[wSize]; CopyMemory(record.pData, pData, wSize); m_UserReplayRecord.push_back(record); return true; } //游戏开始 bool CTableFrameSinkOther::OnEventGameStart() { //椅子数量 WORD wChairCount = m_pITableFrame->GetChairCount(); //开始记录回放数据 RepayRecordStart(); //重置发牌状态 m_isCanOutCard = false; //重置掉线玩家列表 m_offlineUsers.clear(); //设置状态 m_pITableFrame->SetGameStatus(GS_MJ_PLAY); m_gameConfig.wHadPlayCount++; //混乱扑克 m_lSiceCount = MAKELONG(MAKEWORD(rand()%6+1,rand()%6+1),MAKEWORD(rand()%6+1,rand()%6+1)); m_cbLeftCardCount = m_GameLogic.RandCardData(m_cbRepertoryCard); if (1 == m_gameConfig.wHadPlayCount || m_wNextBankerUser == INVALID_CHAIR) { m_wBankerUser = 0;//((BYTE)(m_lSiceCount >> 24) + (BYTE)(m_lSiceCount >> 16) - 1) % wChairCount; } else { m_wBankerUser = m_wNextBankerUser; } m_wNextBankerUser = INVALID_CHAIR; //BYTE byTest[] = { // 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, 0x15, 0x16, 0x17, 0x18, 0x19, 0x21, //索子 // 0x26, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子 // 0x11, 0x12, //索子 // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x13, //索子 // 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x17, 0x19, 0x19, 0x21, 0x16, 0x18, 0x18, //索子 //同子 // 0x21, 0x22, 0x23, 0x24, 0x25, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x27, 0x29, //同子 // 0x14, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x28, 0x29, 0x29, 0x21, //同子 //}; //if (m_GameLogic.PeiPai(byTest)) // CopyMemory(m_cbRepertoryCard, byTest, sizeof(byTest)); BYTE cbTakeCount = 0; //分发扑克 for (WORD i=0;i 0 && m_wBankerUser == i) { m_cbCardIndex[m_wBankerUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;//从手上去掉抓的牌 } else { return false; } } ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData)); m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT*i]); if (i == m_wCurrentUser) { GameStart.cbCardData[i * 14 + 13] = m_cbSendCardData;//把去掉的牌加到数组末尾, m_cbCardIndex[m_wBankerUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;//把去掉的加进来 } //发送数据 m_pITableFrame->SendTableData(i, SUB_S_GAME_START, &GameStart, sizeof(GameStart)); } //用户回放 ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData)); ZeroMemory(GameStart.ActionCard, sizeof(GameStart.ActionCard)); //清手牌 旁观只能发一次 m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_START, &GameStart, sizeof(GameStart)); for (WORD i = 0; i < wChairCount; i++) m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT*i]); RepayRecord(INVALID_CHAIR, SUB_S_GAME_START, &GameStart, sizeof(GameStart)); //StartTime = StartTime.GetAsSystemTime(); return true; } void CTableFrameSinkOther::DeletePrivateTable(bool bSendState) { tagScoreInfo ScoreInfoArray[GAME_PLAYER]; ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray)); WORD wChairCount = m_pITableFrame->GetChairCount(); for (int i = 0; i < wChairCount; ++i) { IServerUserItem *pIUserItem = m_pITableFrame->GetTableUserItem(i); if (pIUserItem == NULL) continue; ScoreInfoArray[i].cbType = SCORE_TYPE_END; ScoreInfoArray[i].lScore = m_lUserTmpScore[i] - TEMP_MAX_SCORE; //记录临时分 } m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray)); ConcludeGame(GAME_STATUS_DELETE, bSendState); m_pITableFrame->DeletePrivateTableNow(); } //游戏结束 bool CTableFrameSinkOther::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState) { bool bFinish = (m_gameConfig.wHadPlayCount >= m_gameConfig.wPlayCountRule) ? true : false; bool bDelete = false; switch (cbReason) { case GER_DELETE_PRIVATE: { bFinish = true; bDelete = true; if (!m_pITableFrame->IsGameStarted()) { DeletePrivateTable(bSendState); return true; } } case GER_NORMAL: //常规结束 { m_wNextBankerUser = (m_wBankerUser + 1) % GAME_PLAYER; CMD_S_XueLiuEnd XueLiuGameEnd; ZeroMemory(&XueLiuGameEnd, sizeof(XueLiuGameEnd)); XueLiuGameEnd.bFinish = bFinish; int TempHuaScore[GAME_PLAYER] = { 0 }; int TempJiaoScore[GAME_PLAYER] = { 0 }; if (m_cbLeftCardCount <= 0 && cbReason == GER_NORMAL)//正常结束,牌没抓完结束不查花猪 { for (int i = 0; i < GAME_PLAYER; i++) { if (m_HuPai[i] == 0) { if (!m_GameLogic.IsHuaZhu(m_cbCardIndex[i], m_WeaveItemArray[i], m_cbWeaveItemCount[i])) { XueLiuGameEnd.checkHuazhu[i] = CHR_HUA_ZHU; BYTE FanShu = 0; //BYTE MaxFanShu = 0; for (int j = 0; j < GAME_PLAYER; j++) { if (i == j)continue; if (m_HuPai[j] == 0 && !m_GameLogic.IsTingCard(m_cbCardIndex[j], m_WeaveItemArray[j], m_cbWeaveItemCount[j], bGameType))continue; for (int k = 0; k < m_TabbTingCardCount[j][0]; k++) { BYTE TempFanShu = m_GameLogic.DeCodeFanshu(m_TabbTingCardData[j][0][k]); if (TempFanShu > FanShu) { FanShu = TempFanShu; } } FanShu = m_MingGangNum[i] + 2 * m_AnGangNum[i] + FanShu; //MaxFanShu += FanShu; int TempScoreBeiHua = -m_gameConfig.wDiScore * FanShu * 3; int TempScoreHua = m_gameConfig.wDiScore * FanShu * 3; TempHuaScore[i] += TempScoreBeiHua; TempHuaScore[j] += TempScoreHua; RecordScoreChange(j, HUA_ZHU, 0, 0, FanShu, TempScoreHua, i); RecordScoreChange(i, BEI_HUAZHU, 0, 0, FanShu, TempScoreBeiHua, j); FanShu = 0; } //RecordScoreChange(i, BEI_HUAZHU, 0, 0, MaxFanShu, TempHuaScore[i], i); } else if (!m_GameLogic.IsTingCard(m_cbCardIndex[i], m_WeaveItemArray[i], m_cbWeaveItemCount[i], bGameType)) { XueLiuGameEnd.checkHuazhu[i] = CHR_CHA_JIAO; BYTE FanShu = 0; //BYTE MaxFanShu = 0; for (int j = 0; j < GAME_PLAYER; j++) { if (i == j)continue; if (m_HuPai[j] == 0 && !m_GameLogic.IsTingCard(m_cbCardIndex[j], m_WeaveItemArray[j], m_cbWeaveItemCount[j], bGameType))continue; for (int k = 0; k < m_TabbTingCardCount[j][0]; k++) { BYTE TempFanShu = m_GameLogic.DeCodeFanshu(m_TabbTingCardData[j][0][k]); if (TempFanShu > FanShu) { FanShu = TempFanShu; } } FanShu = m_MingGangNum[i] + 2 * m_AnGangNum[i] + FanShu; int TempScoreBeiJiao = -m_gameConfig.wDiScore * FanShu; int TempScoreJiao = m_gameConfig.wDiScore * FanShu; TempJiaoScore[i] += TempScoreBeiJiao; TempJiaoScore[j] += TempScoreJiao; RecordScoreChange(j, CHA_JIAO, 0, 0, FanShu, TempScoreJiao, i); RecordScoreChange(i, BEI_CHAJIAO, 0, 0, FanShu, TempScoreBeiJiao, j); FanShu = 0; } //RecordScoreChange(i, BEI_CHAJIAO, 0, 0, MaxFanShu, TempJiaoScore[i], i); } else continue; } } } for (BYTE i = 0; i < GAME_PLAYER; i++) { XueLiuGameEnd.checkCoin[i] = TempHuaScore[i] + TempJiaoScore[i]; m_lGameTatolScore[i] += XueLiuGameEnd.checkCoin[i]; m_lGameScore[i] += XueLiuGameEnd.checkCoin[i]; m_GameLogic.SwitchToCardData(m_cbCardIndex[i], XueLiuGameEnd.cbCardData[i]); XueLiuGameEnd.leftCoin[i] = m_lGameTatolScore[i]; XueLiuGameEnd.DangJu[i] = m_lGameScore[i]; m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * 4 + i] = m_lGameScore[i]; } tagScoreInfo ScoreInfoArray[GAME_PLAYER]; ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray)); for (BYTE i = 0; i < GAME_PLAYER; i++) { IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i);//记录单局积分到数据库 if (NULL == pUserItem) continue; BYTE ScoreKind; if (m_lGameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN; else if (m_lGameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE; else ScoreKind = SCORE_TYPE_DRAW; ScoreInfoArray[i].lScore = m_lGameScore[i]; ScoreInfoArray[i].cbType = ScoreKind; XueLiuGameEnd.winScoreNum = 0;//具体积分变动,协议数据 ZeroMemory(XueLiuGameEnd.winScoreType, sizeof(XueLiuGameEnd.winScoreType)); ZeroMemory(XueLiuGameEnd.winScoreRate, sizeof(XueLiuGameEnd.winScoreRate)); ZeroMemory(XueLiuGameEnd.winProvider, sizeof(XueLiuGameEnd.winProvider)); ZeroMemory(XueLiuGameEnd.winFanType, sizeof(XueLiuGameEnd.winFanType)); ZeroMemory(XueLiuGameEnd.winScore, sizeof(XueLiuGameEnd.winScore)); XueLiuGameEnd.winScoreNum = m_JiFenCount[i]; for (BYTE j = 0; j < m_JiFenCount[i]; j++) { XueLiuGameEnd.winScoreType[j] = m_ChiHuRight[i][j].action; //吃胡,点炮,自摸,被自摸,被花猪 XueLiuGameEnd.winScoreRate[j] = m_ChiHuRight[i][j].Fanshu; //翻数 XueLiuGameEnd.winProvider[j] = m_ChiHuRight[i][j].wProvideUser; //点炮人 XueLiuGameEnd.winFanType[j] = m_ChiHuRight[i][j].chr; //胡牌类型 XueLiuGameEnd.winScore[j] = m_ChiHuRight[i][j].Score; //分数 } m_pITableFrame->SendTableData(i, SUB_S_XUELIU_END, &XueLiuGameEnd, sizeof(XueLiuGameEnd)); //保存回放数据,满足回放积分是单局的 for (BYTE j = 0; j < GAME_PLAYER; j++) { XueLiuGameEnd.leftCoin[j] = m_lGameScore[j]; } RepayRecord(i, SUB_S_XUELIU_END, &XueLiuGameEnd, sizeof(XueLiuGameEnd)); for (BYTE j = 0; j < GAME_PLAYER; j++) { XueLiuGameEnd.leftCoin[j] = m_lGameTatolScore[j]; } } m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray)); //发送结束信息 XueLiuGameEnd.winScoreNum = m_JiFenCount[0]; ZeroMemory(XueLiuGameEnd.winScoreType, sizeof(XueLiuGameEnd.winScoreType)); ZeroMemory(XueLiuGameEnd.winScoreRate, sizeof(XueLiuGameEnd.winScoreRate)); ZeroMemory(XueLiuGameEnd.winProvider, sizeof(XueLiuGameEnd.winProvider)); ZeroMemory(XueLiuGameEnd.winFanType, sizeof(XueLiuGameEnd.winFanType)); ZeroMemory(XueLiuGameEnd.winScore, sizeof(XueLiuGameEnd.winScore)); for (BYTE j = 0; j < m_JiFenCount[0]; j++)//旁观数据 { XueLiuGameEnd.winScoreType[j] = m_ChiHuRight[0][j].action; //吃胡,点炮,自摸,被自摸,被花猪 XueLiuGameEnd.winScoreRate[j] = m_ChiHuRight[0][j].Fanshu; //翻数 XueLiuGameEnd.winProvider[j] = m_ChiHuRight[0][j].wProvideUser; //点炮人 XueLiuGameEnd.winFanType[j] = m_ChiHuRight[0][j].chr; //胡牌类型 XueLiuGameEnd.winScore[j] = m_ChiHuRight[0][j].Score; //分数 } m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_XUELIU_END, &XueLiuGameEnd, sizeof(XueLiuGameEnd)); //变量定义 CMD_S_GameEnd GameEnd; ZeroMemory(&GameEnd, sizeof(GameEnd)); GameEnd.bFinish = bFinish;//1…… GameEnd.bOptType = cbReason == GER_NORMAL ? 1 : 3; if (cbReason == GER_DELETE_PRIVATE)//解散 { GameEnd.bOptType = 3; } //统计积分,胡牌得分,玩家牌值 for (WORD i = 0; i < GAME_PLAYER; i++) { GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3………… } GameEnd.bWanJiaId = wChairID;//玩家座位号 5…… GameEnd.bLeftCardCount = m_cbLeftCardCount;//剩余牌输量6………… CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, m_cbLeftCardCount);//剩余牌值7……………… CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8………… GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9…… GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10………… CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10………… ////数据处理 int iSendLen = 0; CMD_S_GameEnd GameEndBuffer; BYTE *pOutData = (BYTE *)&GameEndBuffer; BYTE *pInData = (BYTE *)&GameEnd; ZeroMemory(&GameEndBuffer, sizeof(GameEndBuffer)); CopyMemory(pOutData, &GameEnd, 85); iSendLen = iSendLen + 85; pInData = pInData + 85; pOutData = pOutData + 85; BYTE *pData = (BYTE *)&GameEnd; BYTE bNum = GameEnd.bLeftCardCount; CopyMemory(pOutData, pInData, bNum); iSendLen = iSendLen + bNum; pOutData = pOutData + bNum; pInData = pInData + CountArray(GameEnd.bLeftCardDada); //pInData = pInData + 54; bNum = GameEnd.playGameNum; pOutData[0] = bNum; pInData++; pOutData++; iSendLen = iSendLen + bNum * 4 * GAME_PLAYER + 1; CopyMemory(pOutData, pInData, bNum * 4 * GAME_PLAYER); ////iSendLen = iSendLen + bNum; RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); //发送结束信息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); ConcludeGame(GS_MJ_FREE); if (bFinish) { DeletePrivateTable(true); } //ConcludeGame(GS_MJ_FREE); return true; } case GER_DISMISS: //游戏解散 { //变量定义 //CMD_S_GameEnd GameEnd; //ZeroMemory(&GameEnd, sizeof(GameEnd)); //GameEnd.bFinish = 1; //GameEnd.bOptType = 3; //CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai)); //CopyMemory(GameEnd.cbWanJiaScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); //GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID(); //GameEnd.playGameNum = m_gameConfig.wHadPlayCount; //CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui)); CMD_S_GameEnd GameEnd; ZeroMemory(&GameEnd, sizeof(GameEnd)); GameEnd.bFinish = bFinish;//1…… GameEnd.bOptType = cbReason == GER_NORMAL ? 1 : 3; if (cbReason == GER_DELETE_PRIVATE)//解散 { GameEnd.bOptType = 3; } //统计积分,胡牌得分,玩家牌值 for (WORD i = 0; i < GAME_PLAYER; i++) { GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3………… } GameEnd.bWanJiaId = 0;//玩家座位号 5…… GameEnd.bLeftCardCount = m_cbLeftCardCount;//剩余牌输量6………… CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, m_cbLeftCardCount);//剩余牌值7……………… CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8………… GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9…… GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10………… CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10………… ////数据处理 int iSendLen = 0; CMD_S_GameEnd GameEndBuffer; BYTE *pOutData = (BYTE *)&GameEndBuffer; BYTE *pInData = (BYTE *)&GameEnd; ZeroMemory(&GameEndBuffer, sizeof(GameEndBuffer)); CopyMemory(pOutData, &GameEnd, 85); iSendLen = iSendLen + 85; pInData = pInData + 85; pOutData = pOutData + 85; BYTE *pData = (BYTE *)&GameEnd; BYTE bNum = GameEnd.bLeftCardCount; CopyMemory(pOutData, pInData, bNum); iSendLen = iSendLen + bNum; pOutData = pOutData + bNum; pInData = pInData + CountArray(GameEnd.bLeftCardDada); //pInData = pInData + 54; bNum = GameEnd.playGameNum; pOutData[0] = bNum; pInData++; pOutData++; iSendLen = iSendLen + bNum * 4 * GAME_PLAYER + 1; CopyMemory(pOutData, pInData, bNum * 4 * GAME_PLAYER); ////iSendLen = iSendLen + bNum; RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); //发送结束信息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEndBuffer, iSendLen); ConcludeGame(GS_MJ_FREE); DeletePrivateTable(true); return true; } case GER_NETWORK_ERROR: //网络错误 case GER_USER_LEAVE: //用户强退 { DWORD dwUserID = pIServerUserItem->GetUserID(); m_offlineUsers.push_back(dwUserID); return true; } } //错误断言 ASSERT(FALSE); return false; } //发送场景 断线重连 bool CTableFrameSinkOther::OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret) { switch (cbGameStatus) { case GS_MJ_FREE: //空闲状态 { //变量定义 CMD_S_StatusFree StatusFree; memset(&StatusFree,0,sizeof(StatusFree)); //游戏房主基础配置 CopyMemory(&StatusFree.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig)); for (int i = 0; i < GAME_PLAYER; i++) { StatusFree.lUserTmpScore[i] = (INT)m_lGameTatolScore[i]; } StatusFree.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; //构造数据 StatusFree.UserStat = pIServerUserItem->GetUserInfo()->cbUserStatus; //发送场景 return m_pITableFrame->SendGameScene(pIServerUserItem,&StatusFree,sizeof(StatusFree)); } case GS_MJ_PLAY: //游戏状态 { //变量定义 CMD_S_StatusPlay StatusPlay; memset(&StatusPlay,0,sizeof(StatusPlay)); //游戏房主基础配置 CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig)); CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); StatusPlay.cbTotalCardCount = MAX_REPERTORY; StatusPlay.cbLeftCardCount = m_cbLeftCardCount; StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; //游戏变量 StatusPlay.wBankerUser=m_wBankerUser; WORD wSice = WORD(m_lSiceCount & 0xffff); StatusPlay.lSiZi[0] = HIBYTE(wSice); StatusPlay.lSiZi[1] = 0; StatusPlay.lSiZi[2] = 0; StatusPlay.lSiZi[3] = 0; StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID(); CopyMemory(StatusPlay.bWanLaiZi, m_HuPai, sizeof(m_HuPai));//血流玩家胡牌次数 CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard)); CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount)); StatusPlay.totalOptTime = 10; StatusPlay.leftOptTime = 0; //当前到谁家 StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser); for (BYTE i = 0; i < GAME_PLAYER; i++) { StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]); } if (PanDuanHuanCard(wChiarID) == 0) { BYTE OldUser = 0;//定义一个最后出牌用户 if (m_cbLastAction.action == WIK_CHI_HU)//当最后一个动作是胡牌且还没有下一个动作的时候 { StatusPlay.bTingCardCount[m_cbLastAction.wProvideUser] = m_cbLastAction.cbChihuCard; } else { if (m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR&&m_cbLastAction.action == WIK_NULL)//牌权是摸牌得且没出牌 { if (m_wProvideUser == 0) { OldUser = 3; } else OldUser = m_wProvideUser - 1; BYTE TempIndex; for (BYTE i = 0; i < 55; i++) { if (m_cbDiscardCard[OldUser][i] == 0) { TempIndex = i - 1; break; } } if (OldUser>3 || TempIndex == 255) { OldUser = 0; TempIndex = 0; } StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex]; } if (m_wProvideUser == m_wOutCardUser&& m_wCurrentUser == INVALID_CHAIR&&m_cbLastAction.action == WIK_NULL)//当有人可以碰且没有碰时候,杠,胡 { OldUser = m_wProvideUser; StatusPlay.bPutCardData[OldUser] = m_cbProvideCard; StatusPlay.cbDiscardCard[OldUser][StatusPlay.cbDiscardCount[OldUser]++] = m_cbProvideCard; } } m_GameLogic.SwitchToCardData(m_cbCardIndex[wChiarID], StatusPlay.cbCardData); StatusPlay.cbActionMask = m_cbUserAction[wChiarID]; //需要用到操作码 if (wChiarID == StatusPlay.wCurrentUser&&m_wCurrentUser != INVALID_CHAIR&&m_wCurrentUser != m_wProvideUser)////表示当前牌权就在断线玩家手里,且是轮到他出牌(牌权碰来得) { ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData)); StatusPlay.cbActionMask = m_cbUserAction[wChiarID]; //需要用到操作码 BYTE TempIndex = 0; if (m_cbUserAction[wChiarID] & WIK_AN_GANG) { for (BYTE i = 0; i < MAX_INDEX; i++) { if (m_cbCardIndex[wChiarID][i] == 4) { StatusPlay.gangCards[TempIndex++] = m_GameLogic.SwitchToCardData(i); break; } } } BYTE TempCardData[MAX_INDEX]; CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData)); BYTE TempCardIndex = 0; for (int i = MAX_INDEX - 1; i >= 0; i--)//手牌里面获取最后一张牌, { if (TempCardData[i] > 0 ) { TempCardIndex = i; break; } } if (TempCardData[TempCardIndex] == 0)ASSERT(false); TempCardData[TempCardIndex]--; m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData); BYTE cardNum = m_GameLogic.GetCardCount(TempCardData); StatusPlay.cbCardData[cardNum] = m_GameLogic.SwitchToCardData(TempCardIndex);//处理得到最后一张牌数据放最后 } if (wChiarID == StatusPlay.wCurrentUser&&m_wCurrentUser != INVALID_CHAIR&&m_wCurrentUser == m_wProvideUser)//牌权是轮到他抓牌,未打出 { ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData)); StatusPlay.cbActionMask = m_cbUserAction[wChiarID]; //需要用到操作码 BYTE TempIndex = 0; if (m_cbUserAction[wChiarID] & WIK_AN_GANG) { for (BYTE i = 0; i < MAX_INDEX; i++) { if (m_cbCardIndex[wChiarID][i] == 4) { StatusPlay.gangCards[TempIndex++] = m_GameLogic.SwitchToCardData(i); break; } } } /*if (m_cbUserAction[wChiarID] & WIK_BU_GANG) { for (BYTE i = 0; i < m_cbWeaveItemCount[wChiarID]; i++) { if (m_cbCardIndex[wChiarID][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[wChiarID][i].cbCenterCard)] == 1 && m_WeaveItemArray[wChiarID][i].cbWeaveKind == WIK_PENG) { StatusPlay.gangCards[TempIndex++] = m_WeaveItemArray[wChiarID][i].cbCenterCard; break; } } }*/ BYTE TempCardData[MAX_INDEX]; CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData)); BYTE TempCardIndex = 0; if (TempCardData[m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] > 0) TempCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard); else { for (int i = MAX_INDEX - 1; i >= 0; i--)//手牌里面获取最后一张牌, { if (TempCardData[i] > 0) { TempCardIndex = i; break; } } } if (m_cbCardIndex[wChiarID][TempCardIndex] == 0)return false; TempCardData[TempCardIndex]--; m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData); BYTE cardNum = m_GameLogic.GetCardCount(TempCardData); StatusPlay.cbCardData[cardNum] = m_GameLogic.SwitchToCardData(TempCardIndex);//处理得到最后一张牌数据放最后 } BYTE ChiHuCardMash[GAME_PLAYER][MAX_INDEX] = { 0 };// 每个玩家胡牌数据ChiHuCard[4][20]掩码,里面涵盖胡牌数据来源 EncodeChiHuCardMash(ChiHuCardMash); CopyMemory(StatusPlay.bTingCardData, ChiHuCardMash, sizeof(ChiHuCardMash)); //组合扑克 CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray)); CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount)); } else { BYTE tempStatus = 0; for (BYTE i = 0; i < GAME_PLAYER; i++) { tempStatus = PanDuanHuanCard(i); ASSERT(tempStatus); if (tempStatus == 1){ StatusPlay.cbCardCount[i] -= 3; } StatusPlay.bOutCardCout |= (tempStatus << (2 * i));//改为是否为换牌状态(0,表示非换牌状态.1,表示换牌状态,但是你已经选好牌了.2,表示换牌状态,但是还没有选牌) } tempStatus = PanDuanHuanCard(wChiarID); if (tempStatus == 1) { StatusPlay.bOutCardData[0] = m_HuanSanZhangData[wChiarID].cbCard1; StatusPlay.bOutCardData[1] = m_HuanSanZhangData[wChiarID].cbCard2; StatusPlay.bOutCardData[2] = m_HuanSanZhangData[wChiarID].cbCard3; BYTE TempCardData[MAX_INDEX]; CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData)); TempCardData[m_GameLogic.SwitchToCardIndex(m_HuanSanZhangData[wChiarID].cbCard1)]--; TempCardData[m_GameLogic.SwitchToCardIndex(m_HuanSanZhangData[wChiarID].cbCard2)]--; TempCardData[m_GameLogic.SwitchToCardIndex(m_HuanSanZhangData[wChiarID].cbCard3)]--; m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData); } else if (tempStatus == 2) { m_GameLogic.SwitchToCardData(m_cbCardIndex[wChiarID], StatusPlay.cbCardData); BYTE tempChange[3] = { 0 }; if (m_GameLogic.ExchangeCardIndex(m_cbCardIndex[wChiarID], tempChange)) { StatusPlay.bOutCardData[0] = tempChange[0]; StatusPlay.bOutCardData[1] = tempChange[1]; StatusPlay.bOutCardData[2] = tempChange[2]; } } else { ASSERT(false); return false; } } //扑克数据 //StatusPlay.cbSendCardData=((m_cbSendCardData!=0)&&(m_wProvideUser==wChiarID))?m_cbSendCardData:0x00; //发送场景 return m_pITableFrame->SendGameScene(pIServerUserItem,&StatusPlay,sizeof(StatusPlay)); } } return false; } //定时器事件 bool CTableFrameSinkOther::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam) { switch (wTimerID) { case 10: { m_pITableFrame->KillGameTimer(10); DispatchCardData((WORD)wBindParam, true); break; } case 11: { m_pITableFrame->KillGameTimer(11); OnUserOperateCard((WORD)wBindParam, WIK_CHI_HU, m_cbProvideCard); break; } case 12: { m_pITableFrame->KillGameTimer(12); OnUserOperateCard((WORD)wBindParam, m_cbUserAction[(WORD)wBindParam], m_cbSendCardData); break; } case 13: { m_pITableFrame->KillGameTimer(13); OnUserOutCard((WORD)wBindParam, m_cbSendCardData); } default: break; } return false; } //游戏消息处理 void CTableFrameSinkOther::SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId) { tagGameConfig* ppConfig = (tagGameConfig*)pDataBuffer; m_gameConfig.wSubGameID = ppConfig->wSubGameID; m_gameConfig.wDiScore = ppConfig->wPlayRule; m_gameConfig.wFanFei = ppConfig->wMaxFanRule; m_gameConfig.wIpLimit = ppConfig->wMaxScore; m_gameConfig.wPlayCountRule = ppConfig->wPlayCountRule; m_gameConfig.RoomId = ppConfig->wHadPlayCount; m_gameConfig.wHadPlayCount = 0; lstrcpy(m_gameConfig.sPrivateTableID, sPrivateRoomId.c_str()); bGameType = XueLiu; m_pITableFrame->SetChairCount(GAME_PLAYER); ASSERT(m_gameConfig.wSubGameID >= 0 && m_gameConfig.wSubGameID < MahJongType::count); if (m_gameConfig.wSubGameID == 10) { YouXiFan[0] = 1; YouXiFan[1] = 2; YouXiFan[2] = 4; YouXiFan[3] = 6; } else if (m_gameConfig.wSubGameID == 11) { YouXiFan[0] = 1; YouXiFan[1] = 3; YouXiFan[2] = 6; YouXiFan[3] = 9; } else { YouXiFan[0] = 1; YouXiFan[1] = 4; YouXiFan[2] = 6; YouXiFan[3] = 12; } } //游戏消息处理 bool CTableFrameSinkOther::OnGameMessage(WORD wSubCmdID, VOID* pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem) { switch (wSubCmdID) { case SUB_C_OUT_CARD: //出牌消息 { //效验消息 ASSERT(wDataSize == sizeof(CMD_C_OutCard)); if (wDataSize != sizeof(CMD_C_OutCard)) return false; //用户效验 if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true; //消息处理 CMD_C_OutCard * pOutCard = (CMD_C_OutCard *)pDataBuffer; return OnUserOutCard(pIServerUserItem->GetChairID(), pOutCard->cbCardData); } case SUB_C_OPERATE_CARD: //操作消息 { //效验消息 ASSERT(wDataSize == sizeof(CMD_C_OperateCard)); if (wDataSize != sizeof(CMD_C_OperateCard)) return false; //用户效验 if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true; //消息处理 CMD_C_OperateCard * pOperateCard = (CMD_C_OperateCard *)pDataBuffer; return OnUserOperateCard(pIServerUserItem->GetChairID(), pOperateCard->cbOperateCode, pOperateCard->cbOperateCard); } case SUB_C_TRUSTEE: { CMD_C_Trustee *pTrustee = (CMD_C_Trustee *)pDataBuffer; if (wDataSize != sizeof(CMD_C_Trustee)) return false; m_bTrustee[pIServerUserItem->GetChairID()] = pTrustee->bTrustee; CMD_S_Trustee Trustee; Trustee.bTrustee = pTrustee->bTrustee; Trustee.wChairID = pIServerUserItem->GetChairID(); RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee)); m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee)); return true; } case SUB_C_HUAN_SAN_ZHANG: { CMD_C_HuanSanZhang *pHuansanzhang = (CMD_C_HuanSanZhang *)pDataBuffer; if (wDataSize != sizeof(CMD_C_HuanSanZhang)) return false; WORD wChairID = pIServerUserItem->GetChairID(); CMD_S_GameNotify notify; notify.m_wChairID = wChairID; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_NOTIFY, ¬ify, sizeof(notify)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_NOTIFY, ¬ify, sizeof(notify)); if (0 != m_cbHuanSanZhang[wChairID]) return true; m_cbHuanSanZhang[wChairID] = 1; int cbCard1Count = m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(pHuansanzhang->cbCard1)]; int cbCard2Count = m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(pHuansanzhang->cbCard2)]; int cbCard3Count = m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(pHuansanzhang->cbCard3)]; if (cbCard1Count <= 0 || cbCard2Count <= 0 || cbCard3Count <= 0) return false; memcpy(&m_HuanSanZhangData[wChairID], pHuansanzhang, sizeof(CMD_C_HuanSanZhang)); bool bAllHuanSanZhang = true; for (bool bSend : m_cbHuanSanZhang) { if (0 == bSend) { bAllHuanSanZhang = false; break; } } if (bAllHuanSanZhang) { WORD c1_chairID = (m_wBankerUser + 1) % GAME_PLAYER; WORD c2_chairID = (m_wBankerUser + 2) % GAME_PLAYER; WORD c3_chairID = (m_wBankerUser + 3) % GAME_PLAYER; WORD c4_chairID = (m_wBankerUser + 4) % GAME_PLAYER; WORD chairIDs[GAME_PLAYER] = { c1_chairID, c2_chairID, c3_chairID, c4_chairID }; //获取椅子ID WORD exchangeChairIDs[GAME_PLAYER] = { 0 }; //计算交换者椅子ID BYTE wSice = HIBYTE(WORD(m_lSiceCount & 0xffff)); switch (wSice) { case 1: case 2: { //庄家与上家换 exchangeChairIDs[0] = chairIDs[3]; exchangeChairIDs[3] = chairIDs[2]; exchangeChairIDs[1] = chairIDs[0]; exchangeChairIDs[2] = chairIDs[1]; }break; case 3: case 4: { //庄家与对家换 exchangeChairIDs[0] = chairIDs[2]; exchangeChairIDs[2] = chairIDs[0]; exchangeChairIDs[1] = chairIDs[3]; exchangeChairIDs[3] = chairIDs[1]; }break; case 5: case 6: { //庄家与下家换 exchangeChairIDs[0] = chairIDs[1]; exchangeChairIDs[1] = chairIDs[2]; exchangeChairIDs[2] = chairIDs[3]; exchangeChairIDs[3] = chairIDs[0]; }break; } //回放数据 CMD_S_HuanSanZhang replayData; ZeroMemory(&replayData, sizeof(CMD_S_HuanSanZhang)); replayData.cbSice = wSice; for (int i = 0; icbCard1)]--; m_cbCardIndex[chairID][m_GameLogic.SwitchToCardIndex(c1->cbCard2)]--; m_cbCardIndex[chairID][m_GameLogic.SwitchToCardIndex(c1->cbCard3)]--; //获得新的手牌 m_cbCardIndex[chairID][m_GameLogic.SwitchToCardIndex(c1_get->cbCard1)]++; m_cbCardIndex[chairID][m_GameLogic.SwitchToCardIndex(c1_get->cbCard2)]++; m_cbCardIndex[chairID][m_GameLogic.SwitchToCardIndex(c1_get->cbCard3)]++; CMD_S_HuanSanZhang req; ZeroMemory(&req, sizeof(CMD_S_HuanSanZhang)); req.cbSice = wSice; req.cbCard1[chairID] = c1_get->cbCard1; req.cbCard2[chairID] = c1_get->cbCard2; req.cbCard3[chairID] = c1_get->cbCard3; req.cbUserAction = WIK_NULL; ZeroMemory(req.ActionCard, sizeof(req.ActionCard)); if (chairID == m_wBankerUser) { tagGangCardResult GangCardResult; req.cbUserAction |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[chairID], m_WeaveItemArray[chairID], m_cbWeaveItemCount[chairID], GangCardResult); if (req.cbUserAction&WIK_GANG) { req.cbUserAction |= WIK_AN_GANG; m_cbUserAction[m_wBankerUser] = req.cbUserAction; BYTE TempActionCount = 0; for (BYTE j = 0; j < MAX_INDEX; j++) { if (m_cbCardIndex[chairID][j] == 4) { req.ActionCard[TempActionCount++] = m_GameLogic.SwitchToCardData(j); } } } CChiHuRight chr; req.cbUserAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[chairID], m_WeaveItemArray[chairID], m_cbWeaveItemCount[chairID], chr, bGameType); m_cbUserAction[m_wBankerUser] |= req.cbUserAction; } m_pITableFrame->SendTableData(chairID, SUB_S_HUAN_SAN_ZHANG, &req, sizeof(CMD_S_HuanSanZhang)); //回放数据 replayData.cbCard1[chairID] = c1_get->cbCard1; replayData.cbCard2[chairID] = c1_get->cbCard2; replayData.cbCard3[chairID] = c1_get->cbCard3; replayData.wChairID[chairID] = exchangeChairID; } RepayRecord(INVALID_CHAIR, SUB_S_HUAN_SAN_ZHANG, &replayData, sizeof(CMD_S_HuanSanZhang)); ZeroMemory(&replayData.cbCard1, sizeof(replayData.cbCard1)); ZeroMemory(&replayData.cbCard2, sizeof(replayData.cbCard2)); ZeroMemory(&replayData.cbCard3, sizeof(replayData.cbCard3)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_HUAN_SAN_ZHANG, &replayData, sizeof(CMD_S_HuanSanZhang)); TingCard(m_wBankerUser); if (m_TabbOutCardCout[m_wBankerUser] > 0) HttpTingCard(m_wBankerUser); } return true; } return false; } return false; } //框架消息处理 bool CTableFrameSinkOther::OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem) { return false; } //用户断线重连 bool CTableFrameSinkOther::OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem) { auto dwUserID = pIServerUserItem->GetUserID(); auto iter = std::find(m_offlineUsers.begin(), m_offlineUsers.end(), dwUserID); if (m_TabbOutCardCout[wChairID] > 0) HttpTingCard(wChairID); if (iter != end(m_offlineUsers)) { m_offlineUsers.erase(iter); //玩家重新上线 return true; } return true; } //用户坐下 bool CTableFrameSinkOther::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser) { return true; } //游戏中途旁观进入 bool CTableFrameSinkOther::PerformLookonLogin(IServerUserItem * pIServerUserItem) { CMD_S_PangGuan StatusPlay; memset(&StatusPlay, 0, sizeof(StatusPlay)); //游戏房主基础配置 CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig)); CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); StatusPlay.cbTotalCardCount = MAX_REPERTORY; StatusPlay.cbLeftCardCount = m_cbLeftCardCount; StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; StatusPlay.GameStatus = 1;//m_pITableFrame->IsDrawStarted(); if (StatusPlay.GameStatus) { //游戏变量 StatusPlay.wBankerUser = m_wBankerUser; WORD wSice = WORD(m_lSiceCount & 0xffff); StatusPlay.lSiZi[0] = HIBYTE(wSice); StatusPlay.lSiZi[1] = 0; StatusPlay.lSiZi[2] = 0; StatusPlay.lSiZi[3] = 0; StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID(); CopyMemory(StatusPlay.bWanLaiZi, m_HuPai, sizeof(m_HuPai)); CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard)); CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount)); StatusPlay.totalOptTime = 10; StatusPlay.leftOptTime = 0; //当前到谁家 StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser); for (BYTE i = 0; i < GAME_PLAYER; i++) { StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]); } WORD OldUser = 0;//定义一个最后出牌用户 if (PanDuanHuanCard(0) == 0) { if (m_cbLastAction.action == WIK_CHI_HU)//当最后一个动作是胡牌且还没有下一个动作的时候 { StatusPlay.bTingCardCount[m_cbLastAction.wProvideUser] = m_cbLastAction.cbChihuCard; } else { if (m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR)//牌权是摸牌得且没出牌 { if (m_wProvideUser == 0) { OldUser = 3; } else OldUser = m_wProvideUser - 1; BYTE TempIndex; for (BYTE i = 0; i < 55; i++) { if (m_cbDiscardCard[OldUser][i] == 0) { TempIndex = i - 1; break; } } if (OldUser>3 || TempIndex == 255) { OldUser = 0; TempIndex = 0; } StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex]; } if (m_wProvideUser == m_wOutCardUser&& m_wCurrentUser == INVALID_CHAIR)//当有人可以碰且没有碰时候 { OldUser = m_wProvideUser; StatusPlay.bPutCardData[OldUser] = m_cbProvideCard; StatusPlay.cbDiscardCard[OldUser][StatusPlay.cbDiscardCount[OldUser]++] = m_cbProvideCard; } } BYTE ChiHuCardMash[GAME_PLAYER][MAX_INDEX] = { 0 };// 每个玩家胡牌数据ChiHuCard[4][20]掩码,里面涵盖胡牌数据来源 EncodeChiHuCardMash(ChiHuCardMash); CopyMemory(StatusPlay.bTingCardData, ChiHuCardMash, sizeof(StatusPlay.bTingCardData)); //组合扑克 CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray)); CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount)); } else { BYTE tempStatus = 0; for (BYTE i = 0; i < GAME_PLAYER; i++) { tempStatus = PanDuanHuanCard(i); ASSERT(tempStatus); if (tempStatus == 1){ StatusPlay.cbCardCount[i] -= 3; } StatusPlay.bOutCardCout |= (tempStatus << (2 * i));//改为是否为换牌状态(0,表示非换牌状态.1,表示换牌状态,但是你已经选好牌了.2,表示换牌状态,但是还没有选牌) } } } return m_pITableFrame->SendUserItemData(pIServerUserItem, SUB_S_PANGGUAN, &StatusPlay, sizeof(StatusPlay)); } //用户起来 bool CTableFrameSinkOther::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser) { //庄家设置 if (bLookonUser == false && !QueryUseTemporaryScore()) { m_bTrustee[wChairID]=false; CMD_S_Trustee Trustee; Trustee.bTrustee=false; Trustee.wChairID = wChairID; RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee)); m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_TRUSTEE,&Trustee,sizeof(Trustee)); m_pITableFrame->SendLookonData(INVALID_CHAIR,SUB_S_TRUSTEE,&Trustee,sizeof(Trustee)); } return true; } //用户出牌 bool CTableFrameSinkOther::OnUserOutCard(WORD wChairID, BYTE cbCardData) { //检查是否可以出牌 //if (!IsCanOutCard()) // return true; //效验状态 if (m_pITableFrame->GetGameStatus() != GS_MJ_PLAY) return true; ASSERT(m_pITableFrame->GetGameStatus() == GS_MJ_PLAY); //错误断言 if (wChairID != m_wCurrentUser)return false; ASSERT(wChairID == m_wCurrentUser); ASSERT(m_GameLogic.IsValidCard(cbCardData) == true); if (m_HuPai[wChairID] > 0 && m_cbProvideCard != cbCardData)//玩家已胡牌,出牌必须是抓的牌 { return true; ASSERT(false); } //效验参数 if (wChairID != m_wCurrentUser) return true; if (m_GameLogic.IsValidCard(cbCardData) == false) return false; if ((m_GameLogic.GetCardCount(m_cbCardIndex[wChairID]) - 2) % 3 != 0) { return false; } //删除扑克 if (m_GameLogic.RemoveCard(m_cbCardIndex[wChairID], cbCardData) == false) { ASSERT(FALSE); return false; } //最后操作动作时出牌 ZeroMemory(&m_cbLastAction, sizeof(m_cbLastAction)); //记录出牌数据 ZeroMemory(&m_cbLastDisCardData[wChairID], sizeof(m_cbLastDisCardData[wChairID])); m_cbLastDisCount[wChairID] = 0; for (BYTE i = 0; i < GAME_PLAYER; i++) { if (i == wChairID || m_HuPai[i] > 0)continue; m_cbLastDisCardData[i][m_cbLastDisCount[i]++] = cbCardData;//打出得牌,放到其他玩家得记忆库里面 } //设置变量 m_bSendStatus = true; if (m_bGangStatus) { m_bGangStatus = false; m_bGangOutStatus = true; } m_cbUserAction[wChairID] = WIK_NULL; m_cbPerformAction[wChairID] = WIK_NULL; //出牌记录 m_cbOutCardCount++; //m_cbDiscardCard[wChairID][m_cbDiscardCount[wChairID]++] = cbCardData; //m_cbDiscardWuYongCard[wChairID][m_cbDiscardWuYongCount[wChairID]++] = cbCardData; m_wOutCardUser = wChairID; //记录出牌人 m_cbOutCardData = cbCardData; //记录出牌数据 //构造数据 CMD_S_OutCard OutCard; OutCard.wOutCardUser = wChairID; OutCard.cbOutCardData = cbCardData; OutCard.bOptType = 0; m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数 ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], bGameType))//是否听牌状态 { BYTE cardIndex = m_GameLogic.SwitchToCardIndex(cbCardData); OutTingCard(wChairID,cardIndex); } RepayRecord(INVALID_CHAIR, SUB_S_OUT_CARD, &OutCard, sizeof(OutCard)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_CARD, &OutCard, sizeof(OutCard)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_CARD, &OutCard, sizeof(OutCard)); m_wProvideUser = wChairID; m_cbProvideCard = cbCardData; //用户切换 m_wCurrentUser = (wChairID + 1) % GAME_PLAYER; //while (!m_bPlayStatus[m_wCurrentUser]) // m_wCurrentUser = (m_wCurrentUser + 1) % GAME_PLAYER; //响应判断 bool bAroseAction = EstimateUserRespond(wChairID, cbCardData, EstimatKind_OutCard); //派发扑克 if (bAroseAction == false) DispatchCardData(m_wCurrentUser); return true; } //用户操作 bool CTableFrameSinkOther::OnUserOperateCard(WORD wChairID, int cbOperateCode, BYTE cbOperateCard) { //效验状态 ASSERT(m_pITableFrame->GetGameStatus()==GS_MJ_PLAY); if (m_pITableFrame->GetGameStatus()!=GS_MJ_PLAY) return true; if (m_HuPai[wChairID] > 0 && cbOperateCode == NULL && !(m_cbUserAction[wChairID]&(WIK_AN_GANG|WIK_BU_GANG))) return true; //效验用户 注意:机器人有可能发生此断言 //ASSERT((wChairID==m_wCurrentUser)||(m_wCurrentUser==INVALID_CHAIR)); if ((wChairID!=m_wCurrentUser)&&(m_wCurrentUser!=INVALID_CHAIR)) return true; //清零最后动作 ZeroMemory(&m_cbLastAction, sizeof(m_cbLastAction)); int FanKuiAction = WIK_NULL; //被动动作 if (m_wCurrentUser == INVALID_CHAIR&&wChairID != m_wProvideUser)//表示有人出牌后,下一个人还未摸牌这段时间内,有人对上一张出牌有吃胡、杠、碰等操作 { //效验状态 if (m_bResponse[wChairID] == true) return true; if ((cbOperateCode != WIK_NULL) && ((m_cbUserAction[wChairID] & cbOperateCode) == 0)) return true; //变量定义,操作用户 WORD wTargetUser = wChairID; int cbTargetAction = cbOperateCode; //设置变量 m_bResponse[wChairID] = true; m_cbPerformAction[wChairID] = cbOperateCode; m_cbOperateCard[wChairID] = m_cbProvideCard; //放炮记忆小值 //在自己未摸下一张牌的一圈内,不能弃上一家而胡下一家,癞油不可以胡打出来的牌的。 //if (cbTargetAction == WIK_NULL && (WIK_CHI_HU&m_cbUserAction[wTargetUser]) && m_wProvideUser != wTargetUser) // m_bEnjoinChiHu[wTargetUser] = true; //执行动作的优先级判断, WIK_CHI_HU 大于 WIK_GANG 大于 WIK_PENG 大于 [WIK_RIGHT or WIK_CENTER or WIK_LEFT] for (WORD i = 0; i < GAME_PLAYER; i++) { //获取动作 INT cbUserAction = (m_bResponse[i] == false) ? m_cbUserAction[i] : m_cbPerformAction[i]; //优先级别 BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction); BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction); //动作判断 if (cbOperateCode != WIK_NULL) { if (cbUserActionRank >= cbTargetActionRank && m_cbUserAction[i] != WIK_NULL && i != wChairID) { wTargetUser = i; cbTargetAction = cbUserAction; //cbOperateCard = m_cbProvideCard; } } else { if (cbUserActionRank > cbTargetActionRank && i != wChairID) { wTargetUser = i; cbTargetAction = m_cbPerformAction[i]; } } } if (m_bResponse[wTargetUser] == false )//如果有玩家得操作级别更高,还没操作就需要等别人先确认 { if (cbOperateCode == WIK_CHI_HU)//如果有玩家也胡,那这个玩家就得等其他玩家的操作码 { m_cbUserAction[wChairID] = WIK_DUO_PAO; m_cbPerformAction[wChairID] = WIK_DUO_PAO; m_bDuoPao = true; } if (cbOperateCode == WIK_NULL) { m_cbUserAction[wChairID] = WIK_NULL; } //if (cbOperateCode == WIK_PENG) //{ // m_bResponse[wTargetUser] = false; //} return true; } if (cbOperateCode == WIK_CHI_HU&&m_bDuoPao)//所有玩家的操作码都操作了,且满足一炮多响条件 { m_cbUserAction[wChairID] = WIK_DUO_PAO; cbTargetAction = WIK_DUO_PAO; } if (m_bDuoPao && cbOperateCode == WIK_NULL)//一炮多向,但是最后一个玩家点了过 { int tempUser = 0; int indexUser = 0; for (int i = 0; i < GAME_PLAYER; i++) { if (m_cbUserAction[i] == WIK_DUO_PAO){ tempUser++; indexUser = i; } } if (tempUser == 1) { wTargetUser = indexUser; m_cbUserAction[indexUser] = WIK_CHI_HU; cbTargetAction = WIK_CHI_HU; cbOperateCard = m_cbProvideCard; } else { cbOperateCard = m_cbProvideCard; cbTargetAction = WIK_DUO_PAO; } } if (m_bQiangGang == true)//此动作为抢杠胡才会促发 { m_bQiangGang = false; if (cbOperateCode == WIK_NULL && !m_bDelete) m_MingGangNum[m_wProvideUser]++; if (cbOperateCode == WIK_CHI_HU && !m_bDelete) { for (BYTE i = 0; i < m_cbWeaveItemCount[m_wProvideUser]; i++) { if (m_WeaveItemArray[m_wProvideUser][i].cbWeaveKind == WIK_BU_GANG&&m_WeaveItemArray[m_wProvideUser][i].cbCenterCard == cbOperateCard) m_WeaveItemArray[m_wProvideUser][i].cbWeaveKind = WIK_PENG; } } } m_bDuoPao = false;//一炮多向操作完归零 //放弃操作 if (cbOperateCode == WIK_NULL&&cbTargetAction == WIK_NULL) { //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); //发送扑克 if (m_wCurrentUser == INVALID_CHAIR) DispatchCardData(m_wResumeUser); return true; } //变量定义 BYTE cbTargetCard = cbOperateCard; m_cbOperateCard[wTargetUser] = cbTargetCard; //出牌变量 m_cbOutCardData = 0; m_bSendStatus = true; m_wOutCardUser = INVALID_CHAIR; m_bEnjoinChiHu[wTargetUser] = true; //删除扑克 switch (cbTargetAction) { case WIK_PENG: //碰牌操作 { cbTargetCard = m_cbProvideCard; //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); if (m_HuPai[wTargetUser] > 0)ASSERT(false); //组合扑克 WORD wIndex = m_cbWeaveItemCount[wTargetUser]++; m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE; m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard; m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction; m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser; //删除扑克 if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] < 2) { return false; } BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard }; VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2)); if (m_cbLeftCardCount > 0) { tagGangCardResult GangCardResult; FanKuiAction |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[wTargetUser], m_WeaveItemArray[wTargetUser], m_cbWeaveItemCount[wTargetUser], GangCardResult); } CMD_S_OperateResult OperateResult; OperateResult.wOperateUser = wTargetUser; OperateResult.cbOperateCard = cbTargetCard; OperateResult.cbOperateCode = cbTargetAction; OperateResult.wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser; OperateResult.bOutCardCout = 0;//能出牌个数 OperateResult.cbActionMask = FanKuiAction; m_cbUserAction[wTargetUser] = FanKuiAction; ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard)); ZeroMemory(OperateResult.bOutCardData, sizeof(OperateResult.bOutCardData));//能出牌具体数据 ZeroMemory(OperateResult.bTingCardCount, sizeof(OperateResult.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(OperateResult.bTingCardData, sizeof(OperateResult.bTingCardData)); m_TabbOutCardCout[wTargetUser] = 0; //可以打出的牌就听牌的个数 ZeroMemory(m_TabbOutCardData[wTargetUser], sizeof(m_TabbOutCardData[wTargetUser])); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount[wTargetUser], sizeof(m_TabbTingCardCount[wTargetUser])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData[wTargetUser], sizeof(m_TabbTingCardData[wTargetUser])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 if (FanKuiAction & WIK_GANG) { BYTE TempCount = 0; for (BYTE i = 0; i < MAX_INDEX; i++) { if (m_cbCardIndex[wTargetUser][i] == 4) { OperateResult.cbActionMask |= WIK_AN_GANG; m_cbUserAction[wTargetUser] |= WIK_AN_GANG; OperateResult.cbActionCard[TempCount++] = m_GameLogic.SwitchToCardData(i); } } } //听牌 TingCard(wTargetUser); RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); if (m_TabbOutCardCout[wTargetUser]>0) { HttpTingCard(wTargetUser); } m_wCurrentUser = wTargetUser; return true; } case WIK_MING_GANG: //明杠牌操作 { cbTargetCard = m_cbProvideCard; //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); //组合扑克 ASSERT(m_cbWeaveItemCount[wTargetUser] < 4); WORD wIndex = m_cbWeaveItemCount[wTargetUser]++; m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE; m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard; m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction; m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser; if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] != 3) { return false; } BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard, cbTargetCard }; VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, CountArray(cbRemoveCard))); m_MingGangNum[wTargetUser]++; CMD_S_OperateResult OperateResult; OperateResult.wOperateUser = wTargetUser; OperateResult.cbOperateCard = cbTargetCard; OperateResult.cbOperateCode = cbTargetAction; OperateResult.wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser; OperateResult.bOutCardCout = 0;//能出牌个数 OperateResult.cbActionMask = WIK_NULL; ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard)); ZeroMemory(OperateResult.bOutCardData, sizeof(OperateResult.bOutCardData));//能出牌具体数据 ZeroMemory(OperateResult.bTingCardCount, sizeof(OperateResult.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(OperateResult.bTingCardData, sizeof(OperateResult.bTingCardData)); RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); //设置用户 m_wCurrentUser = wTargetUser; DispatchCardData(wTargetUser, true); return true; } case WIK_CHI_HU: { //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); BYTE TempCardData = m_cbProvideCard; if (m_cbProvideCard != cbOperateCard) { ASSERT(false); return false; } int TempAction; CChiHuRight chr; m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbOperateCard)]++; TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wTargetUser], m_WeaveItemArray[wTargetUser], m_cbWeaveItemCount[wTargetUser], chr, bGameType); if (TempAction == WIK_NULL) { ASSERT(false); return false; } m_HuPai[wTargetUser]++; CMD_S_ChiHu ChiHu; ZeroMemory(&ChiHu, sizeof(ChiHu)); ChiHu.wChiHuUser[wTargetUser] = m_HuPai[wTargetUser]; ChiHu.wProviderUser = m_wProvideUser; ChiHu.cbChiHuCard = cbOperateCard; //ZeroMemory(ChiHu.TingPaiCard, sizeof(ChiHu.TingPaiCard)); RepayRecord(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); //积分变动 CMD_S_GangScore gs; ZeroMemory(&gs, sizeof(gs)); gs.cbOperateCode = cbTargetAction; gs.wChairId = wTargetUser; int TempInfoScore = 0; BYTE HuPaiFanXing = CHK_NULL; BYTE HuPaiType = FiltrateRight(wTargetUser, &HuPaiFanXing); BYTE FanShu = m_MingGangNum[m_wProvideUser] + 2 * m_AnGangNum[m_wProvideUser] + HuPaiType; gs.lGangScore[wTargetUser] += m_gameConfig.wDiScore * FanShu; gs.lGangScore[m_wProvideUser] -= m_gameConfig.wDiScore * FanShu; m_lGameScore[wTargetUser] += gs.lGangScore[wTargetUser]; m_lGameScore[m_wProvideUser] += gs.lGangScore[m_wProvideUser]; m_lGameTatolScore[wTargetUser] += gs.lGangScore[wTargetUser]; m_lGameTatolScore[m_wProvideUser] += gs.lGangScore[m_wProvideUser]; gs.cbWanJiaScore[wTargetUser] = m_lGameTatolScore[wTargetUser]; gs.cbWanJiaScore[m_wProvideUser] = m_lGameTatolScore[m_wProvideUser]; for (BYTE i = 0; i < GAME_PLAYER; i++) { if (i == m_wProvideUser || i == wTargetUser)continue; gs.cbWanJiaScore[i] = m_lGameTatolScore[i]; } m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); for (BYTE i = 0; i < GAME_PLAYER; i++) { gs.cbWanJiaScore[i] = m_lGameScore[i]; } RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbOperateCard)]--; //记录胡牌数据,记录积分变动数据 m_wChiHuCard[wTargetUser][m_HuPai[wTargetUser]-1].action = WIK_CHI_HU; m_wChiHuCard[wTargetUser][m_HuPai[wTargetUser] - 1].cbChihuCard = cbOperateCard; m_wChiHuCard[wTargetUser][m_HuPai[wTargetUser] - 1].wProvideUser = m_wProvideUser; RecordScoreChange(wTargetUser, CHI_HU, cbOperateCard, HuPaiFanXing, FanShu, gs.lGangScore[wTargetUser], m_wProvideUser); RecordScoreChange(m_wProvideUser, DIAN_PAO, cbOperateCard, HuPaiFanXing, FanShu, gs.lGangScore[m_wProvideUser], wTargetUser); m_cbLastAction.action = WIK_CHI_HU; m_cbLastAction.cbChihuCard = cbOperateCard; m_cbLastAction.wProvideUser = wTargetUser; ZeroMemory(&m_cbLastDisCardData[wTargetUser], sizeof(m_cbLastDisCardData[wTargetUser])); m_cbLastDisCount[wTargetUser] = 0; for (BYTE i = 0; i < GAME_PLAYER; i++) { if (i == wTargetUser || m_HuPai[i] > 0)continue; m_cbLastDisCardData[i][m_cbLastDisCount[i]++] = cbOperateCard;//打出得牌,放到其他玩家得记忆库里面 } m_wCurrentUser = (wTargetUser + 1) % GAME_PLAYER; m_pITableFrame->SetGameTimer(10, 1000, -1, m_wCurrentUser);//定时器任务 //Sleep(1000); //DispatchCardData(m_wCurrentUser, true); return true; } case WIK_DUO_PAO: { cbOperateCard = m_cbProvideCard; if (m_cbProvideCard != cbOperateCard) { ASSERT(false); return false; } int TempAction; CChiHuRight chr; CMD_S_ChiHu ChiHu; ZeroMemory(&ChiHu, sizeof(ChiHu)); int tempcount = 0; for (int i = 0; i < GAME_PLAYER; i++) { if (m_cbUserAction[i] == WIK_DUO_PAO){ ChiHu.wChiHuUser[i] = ++m_HuPai[i]; m_wChiHuCard[i][m_HuPai[i] - 1].action = WIK_DUO_PAO;//胡牌记录 m_wChiHuCard[i][m_HuPai[i] - 1].cbChihuCard = cbOperateCard; m_wChiHuCard[i][m_HuPai[i] - 1].wProvideUser = m_wProvideUser; } } ChiHu.wProviderUser = m_wProvideUser; ChiHu.cbChiHuCard = cbOperateCard; //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); RepayRecord(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); //积分变动 CMD_S_GangScore gs; ZeroMemory(&gs, sizeof(gs)); gs.cbOperateCode = cbTargetAction; gs.wChairId = wTargetUser; int TempInfoScore = 0; BYTE HuPaiFanXing = CHK_NULL; BYTE HuPaiType = 0; BYTE FanShu = 0; int i = m_wProvideUser; //从放炮人开始算起 int ZuihouHuPai = 0; //记录最后胡那个人 for (int j = 0; j < GAME_PLAYER; j++) { if (i == m_wProvideUser)//打牌的那个人跳过 { if (i + 1 == 4)i = 0; else i++; continue; } if (m_cbUserAction[i] == WIK_DUO_PAO)//不是放炮的也跳过 { m_cbCardIndex[i][m_GameLogic.SwitchToCardIndex(cbOperateCard)]++; TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[i], m_WeaveItemArray[i], m_cbWeaveItemCount[i], chr, bGameType); if (TempAction == WIK_NULL) { ASSERT(false); return false; } HuPaiType = FiltrateRight(i, &HuPaiFanXing); FanShu = m_MingGangNum[m_wProvideUser] + 2 * m_AnGangNum[m_wProvideUser] + HuPaiType; gs.lGangScore[i] += m_gameConfig.wDiScore * FanShu; gs.lGangScore[m_wProvideUser] -= m_gameConfig.wDiScore * FanShu; TempInfoScore += gs.lGangScore[m_wProvideUser]; m_lGameScore[i] += gs.lGangScore[i]; m_lGameTatolScore[i] += gs.lGangScore[i]; gs.cbWanJiaScore[i] = m_lGameTatolScore[i]; RecordScoreChange(m_wProvideUser, DIAN_PAO, cbOperateCard, HuPaiFanXing, FanShu, gs.lGangScore[m_wProvideUser], i);//积分记录 RecordScoreChange(i, CHI_HU, cbOperateCard, HuPaiFanXing, FanShu, gs.lGangScore[i],m_wProvideUser); m_cbCardIndex[i][m_GameLogic.SwitchToCardIndex(cbOperateCard)]--; ZuihouHuPai = i; ZeroMemory(&m_cbLastDisCardData[i], sizeof(m_cbLastDisCardData[i])); m_cbLastDisCount[i] = 0; gs.lGangScore[m_wProvideUser] = 0; } else { gs.cbWanJiaScore[i] = m_lGameTatolScore[i]; } if (i + 1 == 4)i = 0; else i++; } gs.lGangScore[m_wProvideUser] = TempInfoScore;//点炮人积分变动总和 m_lGameScore[m_wProvideUser] += gs.lGangScore[m_wProvideUser]; m_lGameTatolScore[m_wProvideUser] += gs.lGangScore[m_wProvideUser]; gs.cbWanJiaScore[m_wProvideUser] = m_lGameTatolScore[m_wProvideUser]; m_cbLastAction.action = WIK_CHI_HU; m_cbLastAction.cbChihuCard = cbOperateCard; m_cbLastAction.wProvideUser = ZuihouHuPai; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); for (BYTE i = 0; i < GAME_PLAYER; i++) { gs.cbWanJiaScore[i] = m_lGameScore[i]; } RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); m_wCurrentUser = (ZuihouHuPai + 1) % GAME_PLAYER; m_pITableFrame->SetGameTimer(10, 1000, -1, m_wCurrentUser);//定时器任务 return true; } default: ASSERT(FALSE); return false; } } //主动动作 if (m_wCurrentUser==wChairID) //如果是摸牌用户的操作,比如自摸或者自杠 { //放弃操作 if (cbOperateCode == WIK_NULL) { //用户状态 ZeroMemory(m_bResponse, sizeof(m_bResponse)); ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction)); ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard)); ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction)); //发送扑克 if (m_wCurrentUser == INVALID_CHAIR) DispatchCardData(m_wResumeUser); return true; } //效验操作 if ((cbOperateCode==WIK_NULL)||((m_cbUserAction[wChairID]&cbOperateCode)==0)) return true; //设置变量 m_bSendStatus=true; m_bEnjoinChiHu[m_wCurrentUser]=true; m_cbUserAction[m_wCurrentUser]=WIK_NULL; m_cbPerformAction[m_wCurrentUser]=WIK_NULL; bool bPublic=false; //执行动作 switch (cbOperateCode) { case WIK_AN_GANG: //暗杠牌操作 { //变量定义 BYTE cbWeaveIndex = 0xFF; ASSERT(cbOperateCard); BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard); //杠牌处理 if (m_cbCardIndex[wChairID][cbCardIndex] == 4) { //扑克效验 ASSERT(m_cbCardIndex[wChairID][cbCardIndex] == 4); if (m_cbCardIndex[wChairID][cbCardIndex] != 4) return false; //设置变量 bPublic = false; cbWeaveIndex = m_cbWeaveItemCount[wChairID]++; m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE; m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID; m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode; m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard; } else return false; //删除扑克 m_cbCardIndex[wChairID][cbCardIndex] = 0; m_wDianGangUser = wChairID; //构造结果 CMD_S_OperateResult OperateResult; OperateResult.wOperateUser = wChairID; OperateResult.wProvideUser = wChairID; OperateResult.cbOperateCode = cbOperateCode; OperateResult.cbOperateCard = cbOperateCard; OperateResult.bOutCardCout = 0;//能出牌个数 OperateResult.cbActionMask = WIK_NULL; ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard)); ZeroMemory(OperateResult.bOutCardData, sizeof(OperateResult.bOutCardData));//能出牌具体数据 ZeroMemory(OperateResult.bTingCardCount, sizeof(OperateResult.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(OperateResult.bTingCardData, sizeof(OperateResult.bTingCardData)); RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); m_AnGangNum[wChairID]++; DispatchCardData(wChairID, true); return true; } case WIK_BU_GANG: { BYTE cbCardIndex = 0xFF; if (cbOperateCard != 0 && m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbOperateCard)] == 1) { for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++) { if (m_WeaveItemArray[wChairID][i].cbWeaveKind == WIK_PENG&&m_WeaveItemArray[wChairID][i].cbCenterCard == cbOperateCard) { m_cbProvideCard = m_WeaveItemArray[wChairID][i].cbCenterCard; cbCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard); m_WeaveItemArray[wChairID][i].cbPublicCard = TRUE; m_WeaveItemArray[wChairID][i].wProvideUser = wChairID; m_WeaveItemArray[wChairID][i].cbWeaveKind = cbOperateCode; m_WeaveItemArray[wChairID][i].cbCenterCard = m_cbProvideCard; break; } } if (cbCardIndex == 0xFF) { for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++) { if (m_WeaveItemArray[wChairID][i].cbWeaveKind == WIK_PENG&&m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[wChairID][i].cbCenterCard)] == 1) { m_cbProvideCard = m_WeaveItemArray[wChairID][i].cbCenterCard; cbCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard); m_WeaveItemArray[wChairID][i].cbPublicCard = TRUE; m_WeaveItemArray[wChairID][i].wProvideUser = wChairID; m_WeaveItemArray[wChairID][i].cbWeaveKind = cbOperateCode; m_WeaveItemArray[wChairID][i].cbCenterCard = m_cbProvideCard; break; } } } } else { for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++) { if (m_WeaveItemArray[wChairID][i].cbWeaveKind == WIK_PENG&&m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[wChairID][i].cbCenterCard)] == 1) { m_cbProvideCard = m_WeaveItemArray[wChairID][i].cbCenterCard; cbCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard); m_WeaveItemArray[wChairID][i].cbPublicCard = TRUE; m_WeaveItemArray[wChairID][i].wProvideUser = wChairID; m_WeaveItemArray[wChairID][i].cbWeaveKind = cbOperateCode; m_WeaveItemArray[wChairID][i].cbCenterCard = m_cbProvideCard; break; } } } if (cbCardIndex == 0xFF) { ASSERT(false); return true; } //删除扑克 m_cbCardIndex[wChairID][cbCardIndex] = 0; m_wDianGangUser = wChairID; //构造结果 CMD_S_OperateResult OperateResult; OperateResult.wOperateUser = wChairID; OperateResult.wProvideUser = wChairID; OperateResult.cbOperateCode = cbOperateCode; OperateResult.cbOperateCard = m_cbProvideCard; OperateResult.bOutCardCout = 0;//能出牌个数 OperateResult.cbActionMask = WIK_NULL; ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard)); ZeroMemory(OperateResult.bOutCardData, sizeof(OperateResult.bOutCardData));//能出牌具体数据 ZeroMemory(OperateResult.bTingCardCount, sizeof(OperateResult.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(OperateResult.bTingCardData, sizeof(OperateResult.bTingCardData)); RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, &OperateResult, sizeof(OperateResult)); ZeroMemory(&m_cbLastDisCardData[wChairID], sizeof(m_cbLastDisCardData[wChairID])); m_cbLastDisCount[wChairID] = 0; for (BYTE m = 0; m < GAME_PLAYER; m++) { if (m == wChairID || m_HuPai[m] > 0)continue; m_cbLastDisCardData[m][m_cbLastDisCount[m]++] = m_cbProvideCard;//补杠类似打出去得牌,放到其他玩家得记忆库里面 } //响应判断 m_wProvideUser = wChairID; bool bAroseAction = EstimateUserRespond(wChairID, m_cbProvideCard, EstimatKind_OutCard);//补杠,别人可以抢杠胡 //派发扑克 if (bAroseAction == false) { m_MingGangNum[wChairID]++; DispatchCardData(m_wCurrentUser); } else { m_bQiangGang = true; } return true; } case WIK_ZI_MO: //自摸和牌 { if (cbOperateCard != NULL && cbOperateCard != m_cbProvideCard && m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbOperateCard)] != 0) m_cbProvideCard = cbOperateCard; BYTE TempCardData=m_cbProvideCard; int TempAction; CChiHuRight chr; TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], chr,bGameType); if (TempAction == WIK_NULL) { ASSERT(false); return false; } CMD_S_ChiHu ChiHu; ZeroMemory(&ChiHu, sizeof(ChiHu)); ChiHu.wChiHuUser[wChairID] = ++m_HuPai[wChairID]; ChiHu.wProviderUser = m_wProvideUser; ChiHu.cbChiHuCard = m_cbProvideCard; RepayRecord(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); //发送消息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_CHI_HU, &ChiHu, sizeof(ChiHu)); //积分变动 CMD_S_GangScore gs; ZeroMemory(&gs, sizeof(gs)); gs.wChairId = wChairID; gs.cbOperateCode = WIK_ZI_MO; int TempInfoScore = 0; BYTE FanShu = 0; BYTE HuPaiFanXing = CHK_NULL; BYTE HuPaiType = FiltrateRight(wChairID, &HuPaiFanXing); BYTE MaxFanShu = 0; m_cbLastDisCount[wChairID] = 0;//打出得牌,放到其他玩家得记忆库里面 for (BYTE i = 0; i < GAME_PLAYER; i++)//各个玩家游戏积分变动 { if (i == wChairID)continue; //是否清一色碰碰胡,是否清一色,是否碰碰胡,平胡,(16-6-4-1) FanShu = m_MingGangNum[i] + 2 * m_AnGangNum[i] + HuPaiType; MaxFanShu += FanShu; gs.lGangScore[i] -= m_gameConfig.wDiScore*FanShu; m_lGameScore[i] += gs.lGangScore[i]; m_lGameTatolScore[i] += gs.lGangScore[i]; gs.cbWanJiaScore[i] = m_lGameTatolScore[i]; TempInfoScore -= gs.lGangScore[i]; RecordScoreChange(i, BEI_ZIMO, m_cbProvideCard, HuPaiFanXing, FanShu, gs.lGangScore[i],wChairID); } gs.lGangScore[wChairID] = TempInfoScore; m_lGameScore[wChairID] += gs.lGangScore[wChairID]; m_lGameTatolScore[wChairID] += gs.lGangScore[wChairID]; gs.cbWanJiaScore[wChairID] = m_lGameTatolScore[wChairID]; //记录胡牌数据,记录积分变动数据 m_wChiHuCard[wChairID][m_HuPai[wChairID] - 1].action = WIK_ZI_MO; m_wChiHuCard[wChairID][m_HuPai[wChairID] - 1].cbChihuCard = m_cbProvideCard; m_wChiHuCard[wChairID][m_HuPai[wChairID] - 1].wProvideUser = wChairID; RecordScoreChange(wChairID, ZI_MO, m_cbProvideCard, HuPaiFanXing, MaxFanShu, gs.lGangScore[wChairID], wChairID); m_cbLastAction.action = WIK_CHI_HU;//最后胡牌人 m_cbLastAction.cbChihuCard = cbOperateCard; m_cbLastAction.wProvideUser = wChairID; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); for (BYTE i = 0; i < GAME_PLAYER; i++) { gs.cbWanJiaScore[i] = m_lGameScore[i]; } RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, &gs, sizeof(gs)); if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] == 0) { return false; } m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]--;//把胡的这张牌拿出手牌 OutTingCard(wChairID, m_GameLogic.SwitchToCardIndex(m_cbProvideCard)); m_wCurrentUser = (wChairID + 1) % GAME_PLAYER; m_pITableFrame->SetGameTimer(10, 1000, -1, m_wCurrentUser);//定时器任务 //sleep(1000); //DispatchCardData(m_wCurrentUser, true); return true; } } return true; } return false; } //发送操作 bool CTableFrameSinkOther::SendOperateNotify() { BYTE TempStatus = 0; //发送提示 for (WORD i=0;iSendTableData(i,SUB_S_OPERATE_NOTIFY,&OperateNotify,sizeof(OperateNotify)); if (m_HuPai[i]>0 && m_cbUserAction[i] & WIK_CHI_HU) { if (TempStatus == 0) { m_pITableFrame->SetGameTimer(11, 500, -1, i);//定时器任务 TempStatus++; } else { OnUserOperateCard(i, WIK_CHI_HU, m_cbProvideCard); } //sleep(500) //OnUserOperateCard(i, WIK_CHI_HU, m_cbProvideCard); } } } //m_pITableFrame->SendLookonData(i, SUB_S_OPERATE_NOTIFY, &OperateNotify, sizeof(OperateNotify)); return true; } //派发扑克,wCurrentUser表示给哪个用户,bTail表示是末尾拿牌还是不是,true表示末尾,bLaiZiGang默认false不是癞子杠,true才是 bool CTableFrameSinkOther::DispatchCardData(WORD wCurrentUser, bool bTail, bool bLaiZiGang) { //状态效验 ASSERT(wCurrentUser!=INVALID_CHAIR); if (wCurrentUser==INVALID_CHAIR) return false; //丢弃扑克 if ((m_wOutCardUser != INVALID_CHAIR) && (m_cbOutCardData != 0)) { m_cbDiscardCount[m_wOutCardUser]++; m_cbDiscardCard[m_wOutCardUser][m_cbDiscardCount[m_wOutCardUser] - 1] = m_cbOutCardData; } //血流单局结束 if (m_cbLeftCardCount == 0) { m_cbChiHuCard = 0; m_wProvideUser = INVALID_CHAIR; OnEventGameConclude(m_wProvideUser, NULL, GER_NORMAL); return true; } //设置变量 m_cbOutCardData = 0; m_wCurrentUser = wCurrentUser; //记录拿牌人的索引。 m_wOutCardUser = INVALID_CHAIR; //置空上次出牌用户的索引 m_bEnjoinChiHu[wCurrentUser] = false; BYTE ActionCard[3] = { 0 };//操作牌值 BYTE AnActionCount = 0; //发牌处理 if (m_bSendStatus == true) { //发送扑克 m_cbSendCardCount++; m_cbSendCardData = m_cbRepertoryCard[--m_cbLeftCardCount]; //加牌 m_cbCardIndex[wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++; CChiHuRight chr; m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wCurrentUser], m_WeaveItemArray[wCurrentUser], m_cbWeaveItemCount[wCurrentUser], chr, bGameType); //设置变量 m_wProvideUser = wCurrentUser; m_cbProvideCard = m_cbSendCardData; //杠牌判断 if (m_cbLeftCardCount > 0 ) { bool bCanAnGang = true;//此true表示自己抓牌,false表示表人打得去检验杠, tagGangCardResult GangCardResult; m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[wCurrentUser], m_WeaveItemArray[wCurrentUser], m_cbWeaveItemCount[wCurrentUser], GangCardResult, m_cbSendCardData); if (m_cbUserAction[wCurrentUser] & WIK_GANG) m_cbUserAction[wCurrentUser] |= WIK_AN_GANG; if (m_HuPai[wCurrentUser] > 0 && (m_cbUserAction[wCurrentUser] & WIK_BU_GANG)) { if (m_cbSendCardData != GangCardResult.cbCardData[GangCardResult.cbCardCount-1]) { m_cbUserAction[wCurrentUser] = m_cbUserAction[wCurrentUser] & 0x1FFF; } } } } if (m_cbUserAction[wCurrentUser] & WIK_GANG ) { for (BYTE i = 0; i < MAX_INDEX; i++) { if (m_cbCardIndex[wCurrentUser][i] == 4) { bool flag = true; ActionCard[AnActionCount++] = m_GameLogic.SwitchToCardData(i); m_cbCardIndex[wCurrentUser][i] = 0; BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1 BYTE m_cbTingParCount = 0;//听牌个数 BYTE bTingCardData[MAX_INDEX] = { 0 }; tagWeaveItem Temp_mWeaveItemArray[MAX_WEAVE]; ZeroMemory(Temp_mWeaveItemArray, sizeof(Temp_mWeaveItemArray)); CopyMemory(Temp_mWeaveItemArray, m_WeaveItemArray[wCurrentUser], sizeof(Temp_mWeaveItemArray)); byte Temp_mcbWeaveItemCount = m_cbWeaveItemCount[wCurrentUser]; Temp_mWeaveItemArray[Temp_mcbWeaveItemCount].cbCenterCard = ActionCard[AnActionCount - 1]; Temp_mWeaveItemArray[Temp_mcbWeaveItemCount].cbPublicCard = false; Temp_mWeaveItemArray[Temp_mcbWeaveItemCount].cbWeaveKind = WIK_AN_GANG; Temp_mWeaveItemArray[Temp_mcbWeaveItemCount].wProvideUser = wCurrentUser; Temp_mcbWeaveItemCount++; if (m_HuPai[wCurrentUser] > 0) { if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wCurrentUser], Temp_mWeaveItemArray, Temp_mcbWeaveItemCount, m_cbTingPai, bGameType)) { ActionCard[--AnActionCount] = 0; for (BYTE j = 0; j < MAX_INDEX; j++) { if (m_cbTingPai[j] == 1) { bTingCardData[m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j); if (bTingCardData[m_cbTingParCount - 1] != m_GameLogic.DeCodeCard(m_TabbTingCardData[wCurrentUser][0][m_cbTingParCount - 1])) { m_cbUserAction[wCurrentUser] = m_cbUserAction[wCurrentUser] & 0xFEFEF; flag = false; break; } } } if (m_cbTingParCount != m_TabbTingCardCount[wCurrentUser][0]) { m_cbUserAction[wCurrentUser] = m_cbUserAction[wCurrentUser] & 0xFEFEF; flag = false; } if (flag) { m_cbUserAction[wCurrentUser] |= WIK_GANG; m_cbUserAction[wCurrentUser] |= WIK_AN_GANG; ActionCard[AnActionCount++] = m_GameLogic.SwitchToCardData(i); } } else { ActionCard[--AnActionCount] = 0; m_cbUserAction[wCurrentUser] = m_cbUserAction[wCurrentUser] & 0xFEFEF; } } m_cbCardIndex[wCurrentUser][i] = 4; } } } //构造数据 CMD_S_SendCard SendCard; ZeroMemory(&SendCard, sizeof(SendCard)); SendCard.wCurrentUser = wCurrentUser; SendCard.bTail = 0; SendCard.bLeftCardCount = m_cbLeftCardCount; SendCard.cbActionMask = m_cbUserAction[wCurrentUser]; SendCard.cbCardData = (m_bSendStatus == true) ? m_cbSendCardData : 0x00; SendCard.bOutCardCout = 0;//能出牌个数(由个数决定是否听牌,0表示不可以听牌) ZeroMemory(SendCard.bOutCardData, sizeof(SendCard.bOutCardData));//能出牌具体数据 ZeroMemory(SendCard.bTingCardCount, sizeof(SendCard.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(SendCard.bTingCardData, sizeof(SendCard.bTingCardData)); if (m_HuPai[wCurrentUser]>0)//听牌数据判断 { BYTE TempIndex = m_GameLogic.SwitchToCardIndex(m_cbSendCardData); if(--m_cbCardIndex[wCurrentUser][TempIndex]<0)ASSERT(false); OutTingCard(wCurrentUser, TempIndex); m_cbCardIndex[wCurrentUser][TempIndex]++; m_TabbOutCardCout[wCurrentUser] = 1; m_TabbOutCardData[wCurrentUser][0] = m_cbSendCardData; } else { TingCard(wCurrentUser); } RepayRecord(INVALID_CHAIR, SUB_S_SEND_CARD, &SendCard, sizeof(SendCard) - 378); //m_wResumeUser = m_wCurrentUser;//当前为抓牌用户,就算是过,也是还回到自己牌权 //发送数据 for (int i = 0; i < GAME_PLAYER; i++) { if (i == m_wCurrentUser) {//发送给摸牌玩家的数据,附带麻将牌面数据 SendCard.cbCardData = (m_bSendStatus == true) ? m_cbSendCardData : 0x00; SendCard.cbActionMask = m_cbUserAction[wCurrentUser]; SendCard.bOutCardCout = 0; CopyMemory(SendCard.cbActionCard, ActionCard, sizeof(ActionCard)); ZeroMemory(SendCard.bOutCardData, sizeof(SendCard.bOutCardData));//能出牌具体数据 ZeroMemory(SendCard.bTingCardCount, sizeof(SendCard.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(SendCard.bTingCardData, sizeof(SendCard.bTingCardData)); m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, &SendCard, sizeof(SendCard)); } else {//发送给其他玩家的数据,没有麻将牌面数据(防止客户端作弊) SendCard.cbCardData = 0x00; SendCard.cbActionMask = 0x0000; SendCard.bOutCardCout = 0;//能出牌个数这幅牌出个牌是否可以听牌 ZeroMemory(SendCard.cbActionCard, sizeof(SendCard.cbActionCard));//对哪个牌操作 ZeroMemory(SendCard.bOutCardData, sizeof(SendCard.bOutCardData));//能出牌具体数据 ZeroMemory(SendCard.bTingCardCount, sizeof(SendCard.bTingCardCount));//在出相应牌后能听牌的个数,所以是个二维的 ZeroMemory(SendCard.bTingCardData, sizeof(SendCard.bTingCardData)); m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, &SendCard, sizeof(SendCard)); } } SendCard.cbActionMask = 0; SendCard.cbCardData = 0; SendCard.bOutCardCout = 0; ZeroMemory(SendCard.bOutCardData, sizeof(SendCard.bOutCardData)); ZeroMemory(SendCard.bTingCardCount, sizeof(SendCard.cbCardData)); ZeroMemory(SendCard.bTingCardData, sizeof(SendCard.cbCardData)); ZeroMemory(SendCard.cbActionCard, sizeof(SendCard.cbCardData)); //给旁观者的抓牌动作 m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_SEND_CARD, &SendCard, sizeof(SendCard)); if (m_TabbOutCardCout[wCurrentUser] > 0)//有听牌就发一个听牌协议 { HttpTingCard(wCurrentUser); } if (m_HuPai[wCurrentUser] > 0) { if (m_cbUserAction[wCurrentUser] == WIK_ZI_MO) { m_pITableFrame->SetGameTimer(12, 500, -1, wCurrentUser); //Sleep(500); //OnUserOperateCard(wCurrentUser, m_cbUserAction[wCurrentUser], m_cbSendCardData); } if (m_cbUserAction[wCurrentUser] == WIK_NULL) { m_pITableFrame->SetGameTimer(13, 500, -1, wCurrentUser); //Sleep(500); //OnUserOutCard(wCurrentUser, m_cbSendCardData); } } return true; } bool CTableFrameSinkOther::IsWin(WORD wChairID) { for (auto chairID : m_wWinOrder) { if (chairID == wChairID)//表示玩家已经开始听牌,则出牌必须是所摸牌 return true; } return false; } //响应判断 bool CTableFrameSinkOther::EstimateUserRespond(WORD wCenterUser, BYTE cbCenterCard, enEstimatKind EstimatKind) { //变量定义 bool bAroseAction[GAME_PLAYER] = { false }; bool mbAroseAction = false; //用户状态 ZeroMemory(m_bResponse,sizeof(m_bResponse)); ZeroMemory(m_cbUserAction,sizeof(m_cbUserAction)); ZeroMemory(m_cbPerformAction,sizeof(m_cbPerformAction)); //动作判断 for (WORD i = 0; i < GAME_PLAYER; i++) { //用户过滤 if (wCenterUser == i ) continue;/*|| !m_bPlayStatus[i]*/ //出牌类型 if (EstimatKind == EstimatKind_OutCard) { //点炮判断 CChiHuRight chr; m_cbCardIndex[i][m_GameLogic.SwitchToCardIndex(cbCenterCard)]++; m_cbUserAction[i] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[i], m_WeaveItemArray[i], m_cbWeaveItemCount[i], chr, bGameType); if (m_cbUserAction[i] & WIK_ZI_MO) { m_cbUserAction[i] = WIK_CHI_HU; } m_cbCardIndex[i][m_GameLogic.SwitchToCardIndex(cbCenterCard)]--; ////碰牌判断,胡过了就不能碰了 if (m_HuPai[i] == 0) m_cbUserAction[i] |= m_GameLogic.EstimatePengCard(m_cbCardIndex[i], cbCenterCard); //杠牌判断 if (m_cbLeftCardCount > 0 && m_HuPai[i]==0) { m_cbUserAction[i] |= m_GameLogic.EstimateGangCard(m_cbCardIndex[i], cbCenterCard); } //结果判断 if (m_cbUserAction[i] != WIK_NULL) { bAroseAction[i] = true; if (m_cbUserAction[i] & WIK_PENG || m_cbUserAction[i] & WIK_CHI_HU) { BYTE bTemp = 0; for (BYTE j = 0; j < m_cbLastDisCount[i]; j++) { if (m_cbLastDisCardData[i][j] == cbCenterCard) { bTemp++; if (bTemp == 2) { m_cbUserAction[i] = m_cbUserAction[i] & 0xffff7; m_cbUserAction[i] = m_cbUserAction[i] & 0xFFFBF; bAroseAction[i] = false; } } } } } } } for (int i = 0; i < GAME_PLAYER; i++) { if (bAroseAction[i] == true) { mbAroseAction = true; break; } } //结果处理 if (mbAroseAction == true) { //设置变量 m_wProvideUser=wCenterUser; m_cbProvideCard=cbCenterCard; m_wResumeUser=m_wCurrentUser; m_wCurrentUser=INVALID_CHAIR; //发送提示 SendOperateNotify(); return true; } return false; } int CTableFrameSinkOther::GetGenCount(WORD wChairId, CChiHuRight& chr) { int cbGenCount = 0; //根,青龙七对和龙七对不算根 //if ((chr&CHR_QING_LONG_QI_DUI).IsEmpty() && (chr&CHR_LONG_QI_DUI).IsEmpty()) //{ BYTE cbCardIndexTemp[MAX_INDEX]; CopyMemory(cbCardIndexTemp, m_cbCardIndex[wChairId], sizeof(cbCardIndexTemp)); for (BYTE i = 0; i < m_cbWeaveItemCount[wChairId]; i++) { // 抢杠过滤 bool bQiangGang = false; if (m_WeaveItemArray[wChairId][i].cbWeaveKind == WIK_GANG) { for (BYTE k = 0; k < GAME_PLAYER; k++) { if (m_cbQiangGangCardData[k] == m_WeaveItemArray[wChairId][i].cbCenterCard) bQiangGang = true; } } if (bQiangGang) continue; BYTE cbCardBuffer[4]; BYTE cbCardCount = m_GameLogic.GetWeaveCard(m_WeaveItemArray[wChairId][i].cbWeaveKind, m_WeaveItemArray[wChairId][i].cbCenterCard, cbCardBuffer); for (BYTE j = 0; j < cbCardCount; j++) { BYTE cbIndex = m_GameLogic.SwitchToCardIndex(cbCardBuffer[j]); cbCardIndexTemp[cbIndex]++; } } for (BYTE i = 0; i < MAX_INDEX; i++) { if (cbCardIndexTemp[i] == 4) cbGenCount++; } return cbGenCount; } //计算听牌剩余个数 BYTE CTableFrameSinkOther::RemainNum(WORD wChairId, const BYTE m_cbCard, BYTE bIndex) { BYTE m_cbNum = 0; BYTE mCard[MAX_INDEX] = { 0 }; BYTE TempIndex = m_GameLogic.SwitchToCardIndex(m_cbCard); for (BYTE i = 0; i < GAME_PLAYER; i++) { for (BYTE j = 0; j < m_cbDiscardCount[i]; j++)//丢弃数 { mCard[m_GameLogic.SwitchToCardIndex(m_cbDiscardCard[i][j])]++; } for (BYTE k = 0; k < m_cbWeaveItemCount[i]; k++)//摆出来的牌 { if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_PENG) { mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 3; } else { mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 4; } } for (BYTE m = 0; m < m_HuPai[i]; m++)//胡牌数据 { mCard[m_GameLogic.SwitchToCardIndex(m_wChiHuCard[i][m].cbChihuCard)]++; if (m_wChiHuCard[i][m].action == WIK_DUO_PAO) { bool bTemp = false; for (BYTE j = i + 1; j < GAME_PLAYER; j++) { for (BYTE n = 0; n < m_HuPai[j]; n++) { if (m_wChiHuCard[j][n].action == WIK_DUO_PAO && m_wChiHuCard[j][n].cbChihuCard == m_wChiHuCard[i][m].cbChihuCard) { mCard[m_GameLogic.SwitchToCardIndex(m_wChiHuCard[i][m].cbChihuCard)]--; bTemp = true; break; } } if (bTemp)break; } } } } mCard[bIndex]++; for (BYTE i = 0; i < MAX_INDEX; i++) { mCard[i] += m_cbCardIndex[wChairId][i]; } m_cbNum = 4 - mCard[TempIndex]; if (m_cbNum < 0 || m_cbNum > 4)m_cbNum = 0; ASSERT(m_cbNum >= 0 && m_cbNum <= 4); return m_cbNum; } BYTE CTableFrameSinkOther::FiltrateRight(WORD wChairId,BYTE *HuPaiFanXing) { BYTE ChiRight = 0; if (m_GameLogic.IsQingYiSe(m_cbCardIndex[wChairId], m_WeaveItemArray[wChairId], m_cbWeaveItemCount[wChairId], ChiRight) && m_GameLogic.IsPengPeng(m_cbCardIndex[wChairId], m_WeaveItemArray[wChairId], m_cbWeaveItemCount[wChairId])) { *HuPaiFanXing = CHR_QING_DUI; ChiRight = YouXiFan[3]; } else if (m_GameLogic.IsQingYiSe(m_cbCardIndex[wChairId], m_WeaveItemArray[wChairId], m_cbWeaveItemCount[wChairId], ChiRight)) { *HuPaiFanXing = CHR_QING_YI_SE; ChiRight = YouXiFan[2]; } else if (m_GameLogic.IsPengPeng(m_cbCardIndex[wChairId], m_WeaveItemArray[wChairId], m_cbWeaveItemCount[wChairId])) { *HuPaiFanXing = CHK_PENGPENG; ChiRight = YouXiFan[1]; } else { *HuPaiFanXing = CHK_CHI_HU; ChiRight = YouXiFan[0]; } ChiRight = ChiRight + m_MingGangNum[wChairId] + 2 * m_AnGangNum[wChairId]; if (m_cbWeaveItemCount[wChairId] == 0) { ChiRight++; *HuPaiFanXing |= CHR_MEN_QIAN_QING; } else { for (int i = 0; i < m_cbWeaveItemCount[wChairId]; i++) { if (m_WeaveItemArray[wChairId][i].cbWeaveKind & WIK_PENG || m_WeaveItemArray[wChairId][i].cbWeaveKind & WIK_MING_GANG || m_WeaveItemArray[wChairId][i].cbWeaveKind & WIK_BU_GANG) { return ChiRight; } } ChiRight++; *HuPaiFanXing |= CHR_MEN_QIAN_QING; } return ChiRight; } void CTableFrameSinkOther::RecordScoreChange(WORD wChairID, BYTE action, BYTE card, BYTE FanXing, BYTE FanShu, int Score, BYTE ExUser) { m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].action = action;//记录积分变动 m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].cbChihuCard = card; m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].chr = FanXing; m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].Fanshu = FanShu; m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].Score = Score; m_ChiHuRight[wChairID][m_JiFenCount[wChairID]].wProvideUser = ExUser; m_JiFenCount[wChairID]++; } bool CTableFrameSinkOther::TingCard(WORD wChairID) { m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数 ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 for (BYTE i = 0; i < MAX_INDEX; i++) { if (m_cbCardIndex[wChairID][i] == 0)continue; if (--m_cbCardIndex[wChairID][i] < 0)ASSERT(false); if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], bGameType)) { m_TabbOutCardData[wChairID][m_TabbOutCardCout[wChairID]] = m_GameLogic.SwitchToCardData(i); BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1 BYTE m_cbTingParCount = 0;//听牌数据 if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, bGameType)) { for (BYTE j = 0; j < MAX_INDEX; j++) { if (m_cbTingPai[j] == 1) { m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j); BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1], i); BYTE Fanxing = 0; m_cbCardIndex[wChairID][j]++; BYTE fanshu = FiltrateRight(wChairID, &Fanxing); m_cbCardIndex[wChairID][j]--; m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, fanshu, m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1]); } } m_TabbTingCardCount[wChairID][m_TabbOutCardCout[wChairID]] = m_cbTingParCount; } m_TabbOutCardCout[wChairID]++; } m_cbCardIndex[wChairID][i]++; } return true; } bool CTableFrameSinkOther::OutTingCard(WORD wChairID, BYTE cardIndex) { m_TabbOutCardCout[wChairID] = 255; //可以打出的牌就听牌的个数,当打出牌已经完成,默认255不存在 ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌 ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1 BYTE m_cbTingParCount = 0;//听牌数据 if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, bGameType)) { for (BYTE j = 0; j < MAX_INDEX; j++) { if (m_cbTingPai[j] == 1) { m_TabbTingCardData[wChairID][0][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j); BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1], cardIndex); BYTE HupaiFanxing; m_cbCardIndex[wChairID][j]++; BYTE fanshu = FiltrateRight(wChairID, &HupaiFanxing); m_cbCardIndex[wChairID][j]--; m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, fanshu, m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1]); } } m_TabbTingCardCount[wChairID][0] = m_cbTingParCount; return true; } else { return false; } } BYTE CTableFrameSinkOther::PanDuanHuanCard(WORD wChairID) { bool bAllHuanSanZhang = true; for (bool bSend : m_cbHuanSanZhang) { if (0 == bSend) { bAllHuanSanZhang = false; break; } } if (bAllHuanSanZhang) { return 0; } else { if (m_cbHuanSanZhang[wChairID] == 1) { return 1; } else { return 2; } } } bool CTableFrameSinkOther::EncodeChiHuCardMash(BYTE ChiHuCardMash[GAME_PLAYER][MAX_INDEX]) { for (BYTE i = 0; i < GAME_PLAYER; i++) { for (BYTE j = 0; j < MAX_CHANGE_SCORE; j++) { if (m_HuPai[i] == j)break; m_wChiHuCard[i][j].cbChihuCard; ChiHuCardMash[i][j] = m_wChiHuCard[i][j].cbChihuCard | (m_wChiHuCard[i][j].wProvideUser<<6); } } return true; } void CTableFrameSinkOther::HttpTingCard(WORD wChairID) { CMD_S_TingCard strTingCard; ZeroMemory(&strTingCard, sizeof(strTingCard)); strTingCard.bOutCardCout = m_TabbOutCardCout[wChairID]; CopyMemory(strTingCard.bOutCardData, m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); CopyMemory(strTingCard.bTingCardCount, m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); CopyMemory(strTingCard.bTingCardData, m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); m_pITableFrame->SendTableData(wChairID, SUB_S_TING_CARD, &strTingCard, sizeof(strTingCard)); }