#include "stdafx.h" #include "TableFrameSinkPoker.h" #include "消息定义/CMD_Poker_Sparrow.h" #define MyZeroMemory(x) ZeroMemory(x,sizeof(x)) CTableFrameSinkPoker::CTableFrameSinkPoker() { m_pITableFrame = NULL; m_pGameServiceOption = NULL; memset(&m_gameConfig, 0, sizeof(CMD_S_GameConfig_Poker)); m_cbPlayerNum = GAME_PLAYER; m_cbCardNum = FULL_COUNT_Poker; // // 用户状态 ZeroMemory(m_cbOffline, sizeof(m_cbOffline));//是否断线 0正常 1断线 ZeroMemory(m_cbTrustee, sizeof(m_cbTrustee));//是否托管 0正常 1托管 ZeroMemory(m_cbTimeOutCount, sizeof(m_cbTimeOutCount));//超时次数 连续两次触发托管 // // 玩家分数 //16局积分 ZeroMemory(m_lGameTatolScore, sizeof(m_lGameTatolScore)); //流水详情 MyZeroMemory(m_HuPaiLiuShui); // 游戏回放 m_bReplayRecordStart = false; m_UserReplayRecord.clear(); // 单局变量 MyZeroMemory(m_GameScore);//本局总积分 MyZeroMemory(m_lGameGongXianScore);//本局贡献分 MyZeroMemory(m_lGameAwardScore);//本局双扣基础分 m_wBankerUser = INVALID_CHAIR;//庄家用户 MyZeroMemory(m_bTrustee); m_bSwitchChair = false;//交换位置 MyZeroMemory(m_wSourceID);//原始ID MyZeroMemory(m_wTargetID);//目标ID MyZeroMemory(m_bResponse);//用户反馈 m_wCurrentUser = INVALID_CHAIR; m_wCurrentOperate = INVALID_CHAIR; m_cbStartRandCard = 0xff; m_cbTurnCardCount = 0; m_wWinCount = 0; m_wWinOrder[0] = 255; m_wWinOrder[1] = 255; m_wWinOrder[2] = 255; m_wWinOrder[3] = 255; MyZeroMemory(m_BomoCouut); //输赢情况 MyZeroMemory(m_winLoseCount); m_lastLianxianInfo = 0; MyZeroMemory(&m_struOutCard); MyZeroMemory(m_cbJokerReplacePoker); MyZeroMemory(m_BoomCountInfo); } CTableFrameSinkPoker::~CTableFrameSinkPoker() { } void * CTableFrameSinkPoker::QueryInterface(const IID & Guid, DWORD dwQueryVer) { if ((Guid == IID_ITableFrameSink) && (InterfaceVersionCompare(dwQueryVer, VER_ITableFrameSinkZhiPai))) return static_cast(this); QUERYINTERFACE(ITableUserAction, Guid, dwQueryVer); if ((Guid == IID_IUnknownEx) && (InterfaceVersionCompare(dwQueryVer, VER_IUnknownEx))) return static_cast(static_cast(this)); return NULL; } bool CTableFrameSinkPoker::Initialization(IUnknownEx * pIUnknownEx) { //查询接口 ASSERT(pIUnknownEx != NULL); m_pITableFrame = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, 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 CTableFrameSinkPoker::RepositionSink() { // // 用户状态 ZeroMemory(m_cbOffline, sizeof(m_cbOffline));//是否断线 0正常 1断线 ZeroMemory(m_cbTrustee, sizeof(m_cbTrustee));//是否托管 0正常 1托管 ZeroMemory(m_cbTimeOutCount, sizeof(m_cbTimeOutCount));//超时次数 连续两次触发托管 //游戏回放 m_bReplayRecordStart = false; // 单局变量 MyZeroMemory(m_GameScore);//本局总积分 MyZeroMemory(m_lGameGongXianScore);//本局贡献分 MyZeroMemory(m_lGameAwardScore);//本局双扣基础分 m_wBankerUser = INVALID_CHAIR;//庄家用户 MyZeroMemory(m_bTrustee); m_bSwitchChair = false;//交换位置 MyZeroMemory(m_wSourceID);//原始ID MyZeroMemory(m_wTargetID);//目标ID MyZeroMemory(m_bResponse);//用户反馈 m_wCurrentUser = INVALID_CHAIR; m_wCurrentOperate = INVALID_CHAIR; m_cbStartRandCard = 0xff; m_cbTurnCardCount = 0; m_wWinCount = 0; m_wWinOrder[0] = 255; m_wWinOrder[1] = 255; m_wWinOrder[2] = 255; m_wWinOrder[3] = 255; MyZeroMemory(m_BomoCouut); m_lastLianxianInfo = 0; MyZeroMemory(&m_struOutCard); MyZeroMemory(m_cbJokerReplacePoker); m_listOutCard.clear(); MyZeroMemory(m_BoomCountInfo); } void CTableFrameSinkPoker::DeletePrivateTable(bool bSendState /*= false*/) { 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 = 0; //记录临时分 } m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray)); ConcludeGame(GAME_STATUS_DELETE, bSendState); m_pITableFrame->DeletePrivateTableNow(); } bool CTableFrameSinkPoker::OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem) { //TRACE("断线重连 wChairID = %d \n", wChairID); if (wChairID >= m_cbCardNum) return false; m_cbOffline[wChairID] = 1; return true; } //用户坐下 bool CTableFrameSinkPoker::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser) { return TRUE; } //用户起来 bool CTableFrameSinkPoker::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser) { //庄家设置 if (bLookonUser == false && !QueryUseTemporaryScore()) { m_cbTrustee[wChairID] = false; //托管广播 CMD_C_Trustee_SK Trustee = { 0 }; Trustee.cbTrustee = 0; Trustee.wChairID = wChairID; RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); } return true; } bool CTableFrameSinkPoker::OnActionUserOnReady(WORD wChairID, IServerUserItem * pIServerUserItem, void * pData, WORD wDataSize) { return true; } //游戏中途旁观进入 bool CTableFrameSinkPoker::PerformLookonLogin(IServerUserItem * pIServerUserItem) { CMD_S_PangGuan_Poler StatusPlay = { 0 }; CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig)); CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; StatusPlay.GameStatus = m_pITableFrame->IsDrawStarted(); if (StatusPlay.GameStatus) { //发送场景 StatusPlay.wBankerUser = m_wBankerUser; StatusPlay.wCurrentUser = m_wCurrentUser; StatusPlay.cbCurrPlayCount = m_gameConfig.wHadPlayCount; StatusPlay.cbTotaPlayCount = m_gameConfig.wPlayCountRule; StatusPlay.leftOptTime = 0; int tmpUser = m_wCurrentUser; for (BYTE i = 0; i < m_cbPlayerNum; i++) { tmpUser = (tmpUser - 1) % m_cbPlayerNum; if (tmpUser < 0) tmpUser += m_cbPlayerNum; if (tmpUser == m_wCurrentUser) continue; if (m_cbResponse[tmpUser] == 1) StatusPlay.cbOtherOperate[tmpUser] = OPERATE_MASK_PASS_Poker; else if (m_cbResponse[tmpUser] == 2) { StatusPlay.cbCardType = m_struOutCard.cbOutCardType; StatusPlay.cbOtherOperate[tmpUser] = OPERATE_MASK_OUT_Poker; std::list::reverse_iterator rIt; for (rIt = m_listOutCard.rbegin(); rIt != m_listOutCard.rend(); rIt++) { if (rIt->wOutCardUser == tmpUser) { memcpy(StatusPlay.cbOutCardData[tmpUser], rIt->cbOutCardData, MAX_COUNT_Poker*sizeof(BYTE)); break; } } } } StatusPlay.cbCardType = m_wCurrentOperate; StatusPlay.cbDiscardType = m_struOutCard.cbOutCardType; CopyMemory(StatusPlay.cbReplaceCard, m_cbJokerReplacePoker, sizeof(m_cbJokerReplacePoker)); //扑克数目、玩家手牌 for (BYTE i = 0; i < m_cbPlayerNum; i++) { StatusPlay.cbCardCount[i] = m_cbCardDataCount[i]; StatusPlay.cbRankIndex[i] = m_wWinOrder[i]; StatusPlay.cbTrusteeStatus[i] = m_cbTrustee[i]; StatusPlay.UserGongXianScore[i] = m_lGameGongXianScore[i]; memset(StatusPlay.cbCardData[i], 0xff, StatusPlay.cbCardCount[i]); } StatusPlay.LeftMinPokerVal = m_cbStartRandCard; } CString strOut; strOut.Format(L"局数 [%d/%d] 扑克数目[%d %d %d %d] 随机牌[%x] 当前积分[%d %d %d %d] 贡献分 [%d %d %d %d]", StatusPlay.cbCurrPlayCount, StatusPlay.cbTotaPlayCount, StatusPlay.cbCardCount[0], StatusPlay.cbCardCount[1], StatusPlay.cbCardCount[2], StatusPlay.cbCardCount[3], StatusPlay.LeftMinPokerVal, StatusPlay.lUserTmpScore[0], StatusPlay.lUserTmpScore[1], StatusPlay.lUserTmpScore[2], StatusPlay.lUserTmpScore[3], StatusPlay.UserGongXianScore[0], StatusPlay.UserGongXianScore[1], StatusPlay.UserGongXianScore[2], StatusPlay.UserGongXianScore[3]); return m_pITableFrame->SendUserItemData(pIServerUserItem, SUB_S_PANGGUAN, &StatusPlay, sizeof(StatusPlay)); } void CTableFrameSinkPoker::SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId) { //TRACE("游戏配置设置 \n"); memset(&m_gameConfig, 0, sizeof(CMD_S_GameConfig_Poker)); CMD_S_GameConfig_Poker* ppConfig = (CMD_S_GameConfig_Poker*)pDataBuffer; CopyMemory(&m_gameConfig, ppConfig, sizeof(CMD_S_GameConfig_Poker)); m_gameConfig.wHadPlayCount = 0; m_GameLogic.SetMagicType(m_gameConfig.bDuoLai); m_cbPlayerNum = m_gameConfig.PeoplesNum; m_cbCardNum = FULL_COUNT_Poker; m_pITableFrame->SetChairCount(m_cbPlayerNum); } //翻牌换桌 void CTableFrameSinkPoker::SwapSeat() { BOOL bSwitch = FALSE; FindCardOwner(bSwitch); if (bSwitch==FALSE) { return; } //队友换桌,对面 IServerUserItem *pIServerUserItem = m_pITableFrame->GetTableUserItem(m_wSourceID[0]); pIServerUserItem->SetChairID(m_wSourceID[1]); pIServerUserItem = m_pITableFrame->GetTableUserItem(m_wSourceID[1]); pIServerUserItem->SetChairID(m_wSourceID[0]); m_pITableFrame->SwapChair(); //换手牌,总积分,流水详情 swap(m_cbCardData[m_wSourceID[0]], m_cbCardData[m_wSourceID[1]]); // CString outFen2 = _T("变换前的分数 "); // for (int i = 0; i < 4; i++) // { // CString TMP; // TMP.Format(_T(" %d "), m_lGameTatolScore[i]); // outFen2 += TMP; // } // OutputDebugString(outFen2); //换总积分 int lGameScore = m_lGameTatolScore[m_wSourceID[0]]; m_lGameTatolScore[m_wSourceID[0]] = m_lGameTatolScore[m_wSourceID[1]]; m_lGameTatolScore[m_wSourceID[1]] = lGameScore; // CString outFen; // outFen = _T("变换后的分数 "); // for (int i = 0; i < 4;i++) // { // CString TMP; // TMP.Format(_T(" %d "), m_lGameTatolScore[i]); // outFen += TMP; // } // OutputDebugString(outFen); // // 换流水 和 for (BYTE i = 0; i < (m_gameConfig.wHadPlayCount - 1); i++) { lGameScore = m_HuPaiLiuShui[i * m_cbPlayerNum + m_wSourceID[0]]; m_HuPaiLiuShui[i * m_cbPlayerNum + m_wSourceID[0]] = m_HuPaiLiuShui[i * m_cbPlayerNum + m_wSourceID[1]]; m_HuPaiLiuShui[i * m_cbPlayerNum + m_wSourceID[1]] = lGameScore; } // 输赢次数 int wins = 0; wins = m_winLoseCount[m_wSourceID[0]]; m_winLoseCount[m_wSourceID[0]] = m_winLoseCount[ m_wSourceID[0]]; m_winLoseCount[m_wSourceID[1]] = wins; } bool CTableFrameSinkPoker::OnUserHint(WORD wChairID) { if (m_wCurrentUser != wChairID) return false; if (m_cbCurrentHintNum + 1 > m_cbHintNum) m_cbCurrentHintNum = 0; TRACE("用户出牌提示 wChairID = %d m_cbCurrentHintNum = %d m_cbHintNum = %d \n", wChairID, m_cbCurrentHintNum, m_cbHintNum); // CString strBuffer; // strBuffer.Format(L"用户出牌提示 wChairID = %d m_cbCurrentHintNum = %d m_cbHintNum = %d ", wChairID, m_cbCurrentHintNum, m_cbHintNum); // OutputDebugString(strBuffer); //提示结果 CMD_S_Hint_Result_Poker HintResult = { 0 }; memcpy(HintResult.cbHintCardData, mHistList[m_cbCurrentHintNum].cbHintLogicCardData, MAX_COUNT_Poker*sizeof(BYTE)); HintResult.cbCardType = mHistList[m_cbCurrentHintNum].cbCardType; //特殊处理 将所有 1 2 转换成14 15 for (int i = 0; i < MAX_COUNT_Poker;i++) { if (HintResult.cbHintCardData[i]==0) { break; } if (HintResult.cbHintCardData[i]<=2) { HintResult.cbHintCardData[i] = m_GameLogic.GetCardLogicValue(HintResult.cbHintCardData[i]); } } PrintCards(HintResult.cbHintCardData, MAX_COUNT_Poker); m_pITableFrame->SendTableData(wChairID, SUB_S_HINT_RESULT, &HintResult, sizeof(HintResult)); m_cbCurrentHintNum++; return true; } bool CTableFrameSinkPoker::OnEventGameStart() { TRACE("游戏开始 \n"); m_pITableFrame->SetGameStatus(GS_MJ_PLAY); m_gameConfig.wHadPlayCount++; //开始记录回放数据 RepayRecordStart(); //混乱扑克 WORD wRoomId = m_gameConfig.RoomId; m_GameLogic.RandCardList(m_cbRepertoryCard, CountArray(m_cbRepertoryCard), m_gameConfig.tmp2, wRoomId); ReadGameData(); ////////////////////////////////////////////////////////////////////////// { m_cbLeftCardCount = FULL_COUNT_Poker; //发牌 for (BYTE i = 0; i < m_cbPlayerNum; i++) { m_cbCardDataCount[i] = MAX_COUNT_Poker; CopyMemory(&m_cbCardData[i], &(m_cbRepertoryCard[i*m_cbCardDataCount[i]]), MAX_COUNT_Poker); } } ////////////////////////////////////////////////////////////////////////// // //发送数据 // OutputDebugString(_T("洗牌后4个玩家的数据输出")); // // for (int i = 0; i < m_cbPlayerNum;i++) // { // PrintCards(m_cbCardData[i], MAX_COUNT_Poker); // } // OutputDebugString(_T("洗牌后4个玩家的数据输出End")); //随机取一张牌 BYTE cbRandData = m_cbRepertoryCard[rand() % FULL_COUNT_Poker]; m_cbStartRandCard = cbRandData; SwapSeat(); for (int i = 0; i < 4; i++) { PrintCards(m_cbCardData[i], m_cbCardDataCount[i]); } //排列扑克 for (WORD i = 0; i < GAME_PLAYER; i++) { m_GameLogic.SortCardList(m_cbCardData[i], m_cbCardDataCount[i], ST_ORDER); } for (int i = 0; i < 4; i++) { PrintCards(m_cbCardData[i], m_cbCardDataCount[i]); } //游戏变量 m_wTurnWiner = INVALID_CHAIR; m_wCurrentUser = m_wBankerUser; CMD_S_GameStart_SK GameStart; ZeroMemory(&GameStart, sizeof(GameStart)); GameStart.wCurrentUser = m_wCurrentUser; //交换位置 for (INT i = 0; i < GAME_PLAYER; i++){ IServerUserItem * pIServerUserItem = m_pITableFrame->GetTableUserItem(i); m_unUserID[i] = pIServerUserItem->GetUserID(); } // CString strUserID; // for (int i = 0; i < m_cbPlayerNum;i++) // { // CString tmp; // tmp.Format(_T("wchaid=%d userid=%d \r\n"),i,m_unUserID[i]); // strUserID += tmp; // } // OutputDebugString(strUserID); for (int i = 0; i < m_cbPlayerNum;i++) { GameStart.lCellScore[i] = m_lGameTatolScore[i]; } ZeroMemory(GameStart.cbPartnerCardData, MAX_COUNT_Poker); GameStart.bTrustee = false; GameStart.cbStartRandCard = m_cbStartRandCard; CopyMemory(GameStart.userSortID, m_unUserID, sizeof(m_unUserID)); GameStart.cbCurrPlay = (BYTE)m_gameConfig.wHadPlayCount; ZeroMemory(GameStart.cbCardData, GAME_PLAYER*MAX_COUNT_Poker); for (int i = 0; i < m_cbPlayerNum;i++) { CopyMemory(GameStart.cbCardData[i], m_cbCardData[i], MAX_COUNT_Poker); } RepayRecord(INVALID_CHAIR, SUB_S_GAME_START_Poker, &GameStart, sizeof(GameStart)); for (int i = 0; i < m_cbPlayerNum;i++) { ZeroMemory(GameStart.cbCardData, GAME_PLAYER*MAX_COUNT_Poker); CopyMemory(GameStart.cbCardData[i], m_cbCardData[i], MAX_COUNT_Poker); m_pITableFrame->SendTableData(i, SUB_S_GAME_START_Poker, &GameStart, sizeof(GameStart)); } ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData));//用户回放 //清手牌 旁观只能发一次 m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_START_Poker, &GameStart, sizeof(GameStart)); m_wCurrentOperate = OPERATE_MASK_OUT_Poker | OPERATE_MASK_HINT_Poker; m_GameLogic.FindAllHit(m_cbCardData[m_wCurrentUser], m_cbCardDataCount[m_wCurrentUser], mHistList); m_cbHintNum = mHistList.size(); return TRUE; } //游戏消息处理 bool CTableFrameSinkPoker::OnGameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem) { WORD wChairId = pIServerUserItem->GetChairID(); // CString str; // str.Format(_T("OnGameMessage wSubCmdID =%d"), wSubCmdID); // OutputDebugString(str); switch (wSubCmdID){ case SUB_C_OPERATE_CALLBACK_Poker:{ //用户操作 出牌/ 过 / 要不起 //效验消息 ASSERT(wDataSize == sizeof(struct CMD_C_OPERATE_CALLBACK_SK )); if (wDataSize != sizeof(CMD_C_OPERATE_CALLBACK_SK)) return false; //消息处理 CMD_C_OPERATE_CALLBACK_SK * pOperateCallback = (CMD_C_OPERATE_CALLBACK_SK *)pDataBuffer; bool ret = OnUserOperate(wChairId, pOperateCallback); // if (ret) // { // OutputDebugString(_T("OnUserOperate Ret True")); // } // else{ // OutputDebugString(_T("OnUserOperate Ret False")); // } return ret; break; } //用户托管 case SUB_C_TRUSTEE_Poker:{ //效验消息 ASSERT(wDataSize == sizeof(CMD_C_Trustee)); if (wDataSize != sizeof(CMD_C_Trustee)) return false; CMD_C_Trustee *pTrustee = (CMD_C_Trustee *)pDataBuffer; m_cbTrustee[wChairId] = pTrustee->bTrustee; m_cbTimeOutCount[wChairId] = 0; //托管广播 CMD_S_Trustee_Poler Trustee = { 0 }; Trustee.cbTrustee = pTrustee->bTrustee; Trustee.wChairID = wChairId; RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE_Poker, &Trustee, sizeof(Trustee)); TRACE("用户托管 %d 是否托管 %d \n", wChairId, pTrustee->bTrustee); //当前玩家托管、立刻响应 if (m_cbTrustee[wChairId]) { if (m_wCurrentUser == wChairId) return TrusteeOut(wChairId); } else if (m_cbTrustee[wChairId] == 0 && m_wCurrentUser == wChairId) { //m_pITableFrame->KillGameTimer(17); //m_pITableFrame->KillGameTimer(18); } return true; break; } } return true; } bool CTableFrameSinkPoker::OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem) { return false; } bool CTableFrameSinkPoker::OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret) { // CString str; // str.Format(L"OnEventSendGameScene wChiarID =%d cbGameStatus=%d ", wChiarID, cbGameStatus); // OutputDebugString(str); switch (cbGameStatus) { case GS_MJ_FREE: //空闲状态 { TRACE("发送场景 wChairID = %d 空闲状态 \n", wChiarID); //发送场景 CMD_S_StatusFree StatusFree = { 0 }; CopyMemory(&StatusFree.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig)); StatusFree.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; CopyMemory(StatusFree.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); StatusFree.UserStat = pIServerUserItem->GetUserInfo()->cbUserStatus; return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusFree, sizeof(StatusFree)); } case GS_MJ_PLAY: //游戏状态 { TRACE("发送场景 wChairID = %d 游戏状态 \n", wChiarID); for (int i = 0; i < m_cbPlayerNum;i++) { m_GameLogic.SortCardList(m_cbCardData[i], m_cbCardDataCount[i]); } try { CMD_S_StatusPlay_SK StatusPlay = {0}; StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0; CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig_Poker)); CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore)); int cfgSize = sizeof(CMD_S_GameConfig_Poker); StatusPlay.wBankerUser = m_wBankerUser; StatusPlay.wCurrentUser = m_wCurrentUser; //如果是 正在出牌的玩家重连 if (m_wCurrentUser == wChiarID) StatusPlay.cbcardType = m_wCurrentOperate; int tmpUser = wChiarID; for (int userindex = 0; userindex < m_cbPlayerNum; userindex++) { StatusPlay.cbOtherOperateType[tmpUser] = m_cbUserOPerate_mask[tmpUser]; //没看懂 tmpUser = (tmpUser - 1) % m_cbPlayerNum; if (tmpUser < 0) tmpUser += m_cbPlayerNum; if (tmpUser == wChiarID && wChiarID == m_wCurrentUser) continue; //记录每个人的操作 if (m_cbResponse[tmpUser] == 1) StatusPlay.cbOtherOperateType[tmpUser] = m_cbUserOPerate_mask[tmpUser]; else if (m_cbResponse[tmpUser] == 2) { BYTE cbLevel; BomoType bomoinof; BYTE cbReplaceCards[27] = { 0 }; m_GameLogic.ReplaceWangCards(m_cbTurnCardData, m_cbTurnCardCount, m_cbJokerReplacePoker[tmpUser], cbReplaceCards); StatusPlay.cbDiscardType = m_GameLogic.GetCardType(cbReplaceCards, m_cbTurnCardCount, cbLevel, bomoinof); StatusPlay.cbOtherOperateType[tmpUser] = OPERATE_MASK_OUT_Poker; std::list::reverse_iterator rIt; for (rIt = m_listOutCard.rbegin(); rIt != m_listOutCard.rend(); rIt++) { if (rIt->wOutCardUser == tmpUser) { memcpy(StatusPlay.cbOutCardData[tmpUser], rIt->cbOutCardData, MAX_COUNT_Poker*sizeof(BYTE)); break; } } } } //扑克数目、玩家手牌 for (BYTE i = 0; i < m_cbPlayerNum; i++) { StatusPlay.cbCardCount[i] = m_cbCardDataCount[i]; StatusPlay.lUserTmpScore[i] = m_lGameTatolScore[i]; StatusPlay.UserGongXianScore[i] = m_lGameGongXianScore[i]; if (i==wChiarID) { if (m_cbCardDataCount[i]==0) { //此时可以看对家的牌 CopyMemory(StatusPlay.cbTeamCardData, m_cbCardData[(i + 2) % GAME_PLAYER],MAX_COUNT_Poker); PrintCards(StatusPlay.cbTeamCardData, MAX_COUNT_Poker); } //我自己的牌 CopyMemory(StatusPlay.cbCardData[i], m_cbCardData[i], MAX_COUNT_Poker); } StatusPlay.cbRankIndex[i] = m_wWinOrder[i]; } StatusPlay.LeftMinPokerVal = m_cbStartRandCard; StatusPlay.cbCurrPlayCount = m_gameConfig.wHadPlayCount; StatusPlay.cbTotaPlayCount = m_gameConfig.wPlayCountRule; StatusPlay.LianXianInfo = m_lastLianxianInfo; CopyMemory(StatusPlay.cbReplaceCard, m_cbJokerReplacePoker, sizeof(m_cbJokerReplacePoker)); // OutputDebugString(L"断线癞子替换"); // PrintCards(StatusPlay.cbReplaceCard,16); // CString strInfo; // strInfo.Format(_T("积分:[%d %d %d %d] 贡献分:[%d %d %d %d] 当前用户[%d] 我的出牌类型[%d] 名次 [%d %d %d %d] 当前扑克->"), // StatusPlay.lUserTmpScore[0], StatusPlay.lUserTmpScore[1], StatusPlay.lUserTmpScore[2], StatusPlay.lUserTmpScore[3], // StatusPlay.UserGongXianScore[0], StatusPlay.UserGongXianScore[1], StatusPlay.UserGongXianScore[2], StatusPlay.UserGongXianScore[3], // StatusPlay.wCurrentUser, StatusPlay.cbcardType, StatusPlay.cbRankIndex[0], StatusPlay.cbRankIndex[1], StatusPlay.cbRankIndex[2], StatusPlay.cbRankIndex[3] // ); // CString csPoker; // for (int i = 0; i < m_cbCardDataCount[wChiarID];i++) // { // CString tmp; // tmp.Format(_T("%02x,"), StatusPlay.cbCardData[wChiarID][i]); // csPoker += tmp; // } // strInfo += csPoker; // OutputDebugString(strInfo); // CString tmp; // for (int i = 0; i < sizeof(StatusPlay);i++) // { // CString strTmp; // strTmp.Format(_T("%02x "), ((BYTE*)&StatusPlay)[i]); // tmp += strTmp; // } // OutputDebugString(tmp); return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusPlay, sizeof(StatusPlay)); } catch (...) {} } } return false; return true; } bool CTableFrameSinkPoker::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState /*= false*/) { TRACE("游戏结束 wChairID = %d cbReason = %#X \n", wChairID, cbReason); bool bFinish = (m_gameConfig.wHadPlayCount >= m_gameConfig.wPlayCountRule) ? 1 : 0; switch (cbReason) { case GER_DELETE_PRIVATE: //bFinish = true; //bDelete = true; //if (!m_pITableFrame->IsGameStarted()) //{ // DeletePrivateTable(bSendState); // return true; //} ConcludeGame(GS_MJ_FREE); DeletePrivateTable(bSendState); return true; case GER_NORMAL: { //常规结束 CMD_S_GameEnd_SK GameEnd = { 0 }; GameEnd.cbEndType = 1; //玩家手牌//名次排行 for (int i = 0; i < m_cbPlayerNum; i++) { GameEnd.cbCardCount[i] = m_cbCardDataCount[i]; CopyMemory(GameEnd.cbCardData[i], m_cbCardData[i], m_cbCardDataCount[i]); } if (m_wWinOrder[0] == (m_wWinOrder[1] + 2) % GAME_PLAYER)//双扣判断 { //游戏积分 胜利玩家 每人+4 ZeroMemory(GameEnd.cbWinorLose, sizeof(GameEnd.cbWinorLose)); //玩家输赢情况 GameEnd.cbWinorLose[m_wWinOrder[0]] = 1; GameEnd.cbWinorLose[(m_wWinOrder[0] + 2) % GAME_PLAYER] = 1; //玩家输赢次数 //双扣分数 for (int i = 0; i < m_cbPlayerNum; i++) { if (i == m_wWinOrder[0] || i == ((m_wWinOrder[0] + 2) % GAME_PLAYER)) { m_winLoseCount[i]++; m_lGameAwardScore[i] += 3; } else { //m_winLoseCount[i]--; m_lGameAwardScore[i] -= 3; } } //切换庄家 m_wBankerUser = rand() % 4; } else //单双扣 判断 if (m_wWinOrder[0] == (m_wWinOrder[2] + 2) % GAME_PLAYER) //单扣判断 { //游戏积分 胜利玩家没人+2 ZeroMemory(GameEnd.cbWinorLose, sizeof(GameEnd.cbWinorLose)); //玩家输赢情况 GameEnd.cbWinorLose[m_wWinOrder[0]] = 1; GameEnd.cbWinorLose[(m_wWinOrder[0]+2)%GAME_PLAYER] = 1; //玩家输赢次数 //双扣分数 for (int i = 0; i < m_cbPlayerNum; i++) { if (i == m_wWinOrder[0] || i == ((m_wWinOrder[0] + 2) % GAME_PLAYER)) { m_winLoseCount[i]++; m_lGameAwardScore[i] += 2; } else { //m_winLoseCount[i]--; m_lGameAwardScore[i] -= 2; } } //切换庄家 m_wBankerUser = m_wWinOrder[0]; }else { BOOL DuiJiabChu = FALSE; for (int i = 0; i < 4; i++) { if (((m_wWinOrder[0] + 2) % GAME_PLAYER) == m_wWinOrder[i]) { DuiJiabChu = TRUE; } } if (DuiJiabChu==FALSE) //平扣判断 { //游戏积分 胜利玩家 没人+1 //玩家输赢情况 GameEnd.cbWinorLose[m_wWinOrder[0]] = 1; GameEnd.cbWinorLose[(m_wWinOrder[0] + 2) % GAME_PLAYER] = 1; //玩家输赢次数 for (int i = 0; i < m_cbPlayerNum; i++) { if (i == m_wWinOrder[0] || i == ((m_wWinOrder[0] + 2) % GAME_PLAYER)) { m_winLoseCount[i]++; m_lGameAwardScore[i] += 1; } else { //m_winLoseCount[i]--; m_lGameAwardScore[i] -= 1; } } //切换庄家 m_wBankerUser = rand() % 4; } } //排名逻辑 单独处理 //特殊处理 游戏结束 排名 BYTE outCrank[4] = { 0xff }; RestartRank(m_wWinOrder, outCrank); for (BYTE i = 0; i < m_cbPlayerNum;i++) { //本局总积分 m_GameScore[i] = m_lGameGongXianScore[i] + m_lGameAwardScore[i]; //16局总积分 m_lGameTatolScore[i] += m_GameScore[i]; //结束消息 //玩家排名 GameEnd.cbRank[i] = outCrank[i]; //输赢次数 GameEnd.cbWinorLoseCount[i] = m_winLoseCount[i]; //本局积分 GameEnd.nWanJiaScore[i] = m_GameScore[i]; //贡献分 GameEnd.GongxianScore[i] = m_lGameGongXianScore[i]; //奖金 GameEnd.AwardScore[i] = m_lGameAwardScore[i]; //16局总积分 GameEnd.cbWanJiaTotalScore[i] = m_lGameTatolScore[i]; } for (BYTE i = 0; i < m_cbPlayerNum;i++) { //流水 m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * m_cbPlayerNum + i] = m_GameScore[i]; } CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui)); /*PrintCards(GameEnd.lGameScoreDetail, sizeof(GameEnd.lGameScoreDetail));*/ //写入积分 稍后写 tagScoreInfo ScoreInfoArray[GAME_PLAYER]; ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray)); for (WORD i = 0; i < m_cbPlayerNum; i++) { IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i); if (NULL == pUserItem) continue; BYTE ScoreKind; if (m_GameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN; else if (m_GameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE; else ScoreKind = SCORE_TYPE_DRAW; ScoreInfoArray[i].lScore = m_GameScore[i]; ScoreInfoArray[i].cbType = ScoreKind; } m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray)); GameEnd.bFinish = bFinish; GameEnd.playGameNum = m_gameConfig.wHadPlayCount; RepayRecord(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); //发送结束信息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); PrintCards((BYTE*)&GameEnd, sizeof(GameEnd)); CString csStr; csStr.Format(_T("名次 [%d %d %d %d] 玩家单局输赢情况 [%d %d %d %d ] 本局积分 [%d %d %d %d] 贡献分[%d %d %d %d] 双扣[%d %d %d %d] 总积分[%d %d %d %d] bfinsh[%d] endType=[%d] 胜局[%d %d %d %d]"), GameEnd.cbRank[0], GameEnd.cbRank[1], GameEnd.cbRank[2], GameEnd.cbRank[3], GameEnd.cbWinorLose[0], GameEnd.cbWinorLose[1], GameEnd.cbWinorLose[2], GameEnd.cbWinorLose[3], GameEnd.nWanJiaScore[0], GameEnd.nWanJiaScore[1], GameEnd.nWanJiaScore[2], GameEnd.nWanJiaScore[3], GameEnd.GongxianScore[0], GameEnd.GongxianScore[1], GameEnd.GongxianScore[2], GameEnd.GongxianScore[3], GameEnd.AwardScore[0], GameEnd.AwardScore[1], GameEnd.AwardScore[2], GameEnd.AwardScore[3], GameEnd.cbWanJiaTotalScore[0], GameEnd.cbWanJiaTotalScore[1], GameEnd.cbWanJiaTotalScore[2], GameEnd.cbWanJiaTotalScore[3], GameEnd.bFinish,GameEnd.cbEndType, m_winLoseCount[0], m_winLoseCount[1], m_winLoseCount[2], m_winLoseCount[3] ); OutputDebugString(csStr); //结束回放 ConcludeGame(GS_MJ_FREE); if (bFinish) { DeletePrivateTable(true); } return true; } case GER_DISMISS: //游戏解散 { //常规结束 CMD_S_GameEnd_SK GameEnd = { 0 }; GameEnd.cbEndType = 2; GameEnd.bFinish = 1; //玩家手牌//名次排行 for (int i = 0; i < m_cbPlayerNum; i++) { GameEnd.cbCardCount[i] = m_cbCardDataCount[i]; CopyMemory(GameEnd.cbCardData[i], m_cbCardData[i], m_cbCardDataCount[i]); } //特殊处理 游戏结束 排名 BYTE outCrank[4] = { 0xff }; RestartRank(m_wWinOrder, outCrank); for (BYTE i = 0; i < m_cbPlayerNum; i++) { //本局总积分 m_GameScore[i] = m_lGameGongXianScore[i] + m_lGameAwardScore[i]; //16局总积分 m_lGameTatolScore[i] += m_GameScore[i]; //结束消息 //玩家排名 GameEnd.cbRank[i] = outCrank[i]; //输赢次数 GameEnd.cbWinorLoseCount[i] = m_winLoseCount[i]; //本局积分 GameEnd.nWanJiaScore[i] = m_GameScore[i]; //贡献分 GameEnd.GongxianScore[i] = m_lGameGongXianScore[i]; //奖金 GameEnd.AwardScore[i] = m_lGameAwardScore[i]; //16局总积分 GameEnd.cbWanJiaTotalScore[i] = m_lGameTatolScore[i]; } for (BYTE i = 0; i < m_cbPlayerNum; i++) { //流水 m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * m_cbPlayerNum + i] = m_GameScore[i]; } CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui)); /*PrintCards(GameEnd.lGameScoreDetail, sizeof(GameEnd.lGameScoreDetail));*/ GameEnd.playGameNum = m_gameConfig.wHadPlayCount; RepayRecord(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); //发送结束信息 m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END_Poker, &GameEnd, sizeof(GameEnd)); if (m_pITableFrame->GetGameStatus() == GS_MJ_FREE) { DeletePrivateTable(true); return true; } //写入积分 稍后写 tagScoreInfo ScoreInfoArray[GAME_PLAYER]; ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray)); for (WORD i = 0; i < m_cbPlayerNum; i++) { IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i); if (NULL == pUserItem) continue; BYTE ScoreKind; if (m_GameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN; else if (m_GameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE; else ScoreKind = SCORE_TYPE_DRAW; ScoreInfoArray[i].lScore = m_GameScore[i]; ScoreInfoArray[i].cbType = ScoreKind; } m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray)); PrintCards((BYTE*)&GameEnd, sizeof(GameEnd)); CString csStr; csStr.Format(_T("名次 [%d %d %d %d] 玩家单局输赢情况 [%d %d %d %d ] 本局积分 [%d %d %d %d] 贡献分[%d %d %d %d] 双扣[%d %d %d %d] 总积分[%d %d %d %d]"), GameEnd.cbRank[0], GameEnd.cbRank[1], GameEnd.cbRank[2], GameEnd.cbRank[3], GameEnd.cbWinorLose[0], GameEnd.cbWinorLose[1], GameEnd.cbWinorLose[2], GameEnd.cbWinorLose[3], GameEnd.nWanJiaScore[0], GameEnd.nWanJiaScore[1], GameEnd.nWanJiaScore[2], GameEnd.nWanJiaScore[3], GameEnd.GongxianScore[0], GameEnd.GongxianScore[1], GameEnd.GongxianScore[2], GameEnd.GongxianScore[3], GameEnd.AwardScore[0], GameEnd.AwardScore[1], GameEnd.AwardScore[2], GameEnd.AwardScore[3], GameEnd.cbWanJiaTotalScore[0], GameEnd.cbWanJiaTotalScore[1], GameEnd.cbWanJiaTotalScore[2], GameEnd.cbWanJiaTotalScore[3] ); OutputDebugString(csStr); //结束回放 ConcludeGame(GS_MJ_FREE); DeletePrivateTable(bSendState); return true; } case GER_NETWORK_ERROR: //网络错误 case GER_USER_LEAVE: //用户强退 { if (pIServerUserItem!=NULL) { DWORD dwUserID = pIServerUserItem->GetUserID(); m_cbOffline[dwUserID] = 1; } return true; } } //错误断言 ASSERT(FALSE); return false; } bool CTableFrameSinkPoker::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam) { return true; } bool CTableFrameSinkPoker::OnDataBaseMessage(WORD wRequestID, VOID * pData, WORD wDataSize) { return true; } bool CTableFrameSinkPoker::OnUserScroeNotify(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason) { return true; } bool CTableFrameSinkPoker::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 CTableFrameSinkPoker::RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize) { 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 CTableFrameSinkPoker::RepayRecordEnd() { TRACE("回放 RepayRecordEnd:m_bReplayRecordStart = %d \n", m_bReplayRecordStart); if (!m_bReplayRecordStart) return false; m_bReplayRecordStart = false; CMD_GR_ReplayRecordResp_Poker urr; ZeroMemory(&urr, sizeof(CMD_GR_ReplayRecordResp_Poker)); 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 < m_cbPlayerNum; ++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;*/ /*delete[] grp.pData; grp.pData = NULL;*/ } //m_UserReplayRecord.clear(); //std::vector(m_UserReplayRecord).swap(m_UserReplayRecord); //FILE *fp = NULL; //fp = fopen("test.bin", "wb"); //fwrite(replyRecordData, totalSize, 1, fp); //fclose(fp); m_pITableFrame->SaveReplayRecord(replyRecordData, totalSize); //delete replyRecordData;不能删除,已托管给SaveReplayRecord函数 return true; } bool CTableFrameSinkPoker::OnUserOperate(WORD wChairID, CMD_C_OPERATE_CALLBACK_SK* pOperateCallback, BYTE cbType /*= 0*/) { m_cbTimeOutCount[wChairID] = 0; TRACE("用户操作 wChairID = %d 操作类型: %d \n", wChairID, pOperateCallback->wOperateType); m_cbUserOPerate_mask[wChairID] = pOperateCallback->wOperateType; switch (pOperateCallback->wOperateType) { case OPERATE_MASK_OUT_Poker: //出牌 { BYTE cbCardCount = m_GameLogic.GetCardCount(pOperateCallback->cbCardData); BYTE LianxianInfo = pOperateCallback->LianxianInfo; return OnUserOutCard(wChairID, pOperateCallback->cbCardData, cbCardCount, pOperateCallback->cbCardType, pOperateCallback->cbJokerReplacePoker, LianxianInfo); } case OPERATE_MASK_NOOUT_Poker: //要不起 case OPERATE_MASK_PASS_Poker: //不出 { m_cbResponse[wChairID] = 1; /* struct CMD_S_Out_Broadcast_SK { WORD wOutCardUser; //出牌用户 WORD cbOperateType; //操作类型 WORD cbCardType; //出牌牌型 BYTE cbJokerReplacePoker[4];//替换癞子的牌 BYTE cbOutCardData[27]; //出牌扑克 BYTE cbIsFreeOut; //是否自由出牌 BYTE cbIsTrusteeOut; //是否托管出牌 BYTE cbLeftCount; //剩余牌数 BYTE cbRanking; //当前名次 }; */ //出牌广播 CMD_S_Out_Broadcast_SK outCard = { 0 }; outCard.wOutCardUser = wChairID; outCard.cbOperateType = pOperateCallback->wOperateType; outCard.cbCardType = CT_ERROR; CopyMemory(outCard.cbJokerReplacePoker, pOperateCallback->cbJokerReplacePoker, sizeof(pOperateCallback->cbJokerReplacePoker)); //CopyMemory(outCard.cbOutCardData, pOperateCallback->bCardData, 0); outCard.cbIsFreeOut = FALSE; outCard.cbIsTrusteeOut = 0; outCard.cbLeftCount = m_cbCardDataCount[wChairID]; outCard.cbRanking[0] =m_wWinOrder[0]; outCard.cbRanking[1] = m_wWinOrder[1]; outCard.cbRanking[2] = m_wWinOrder[2]; outCard.cbRanking[3] = m_wWinOrder[3]; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); RepayRecord(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); return NextOperate(wChairID); } case OPERATE_MASK_HINT_Poker: //提示 return OnUserHint(wChairID); default: CString tmp; tmp.Format(_T("OnUserOperate 收到 %d "), pOperateCallback->wOperateType); break; } return true; } //去花色排序 void CTableFrameSinkPoker::SortCard(BYTE cbCardData[], BYTE cbCardCount) { BYTE tmp = 0; for (BYTE i = 0; i < cbCardCount; ++i) { cbCardData[i] &= 0x0f; tmp = cbCardData[i]; cbCardData[i] = m_GameLogic.GetCardLogicValue(tmp); } sort(cbCardData, cbCardData + cbCardCount); for (BYTE i = 0; i < cbCardCount; ++i) { tmp = cbCardData[i]; cbCardData[i] = m_GameLogic.GetCardValue(tmp); } } bool CTableFrameSinkPoker::IsTeShuCard(BYTE cbCardData[], BYTE cbCount, BomoType& BomoInfo, WORD&WinScore) { BYTE cbLevel; BYTE CardType=m_GameLogic.GetCardType(cbCardData, cbCount, cbLevel, BomoInfo); if ((CardType == 7 && cbCount >= 5) ||CardType>7) { BYTE tmpXian =0; if (CardType==7) { tmpXian = cbCount; } else { tmpXian = BomoInfo.Level; } //计算分数 switch (tmpXian) { case 5: WinScore = 1*(m_cbPlayerNum-1); break; case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: WinScore = pow(2, tmpXian-5)*3; break; default: break; } return TRUE; } return false; } BOOL CTableFrameSinkPoker::IsWinByChairID(BYTE wChairID) { for (int i = 0; i < m_cbPlayerNum;i++) { if (m_wWinOrder[i] == wChairID) { return TRUE; } } return FALSE; } void CTableFrameSinkPoker::WithByteAnalyzeCardFlags(BYTE lianxianinfo,BomoType &BomoInfo) { //第一位 0 标示付 1 表示连 //2-4 标示 几付 /几连 //最后4位 表示 几线 BOOL IsLian = lianxianinfo >> 7; BYTE fuOrLian = (lianxianinfo & 0x70) >> 4; BYTE xian = (lianxianinfo & 15) >> 1; if (lianxianinfo>0) { BomoInfo.BomoTypes = IsLian == 0? BomoTypeXian : BomoTypeLian; if (IsLian) { BomoInfo.tong = xian; BomoInfo.lian = fuOrLian; } else { BomoInfo.fu = fuOrLian; BomoInfo.xian = xian; } m_GameLogic.SetBomoLevel(BomoInfo); } } void CTableFrameSinkPoker::SetCardFlags(BOOL IsLian, BYTE fuOrLian, BYTE xian) { //第一位 0 标示付 1 表示连 //2-4 标示 几付 /几连 //最后4位 表示 几线 BYTE lianxinfo; lianxinfo = IsLian << 7; lianxinfo |= fuOrLian << 4; lianxinfo |= xian << 1; BomoType BomoInfo; WithByteAnalyzeCardFlags(lianxinfo, BomoInfo); } //托管出牌 全部发要不起 bool CTableFrameSinkPoker::TrusteeOut(WORD wChairID) { if (BeOutCardFree(wChairID)){ BYTE cbCardData[1]; BYTE cbCardCount = 1; cbCardData[0] = m_cbCardData[wChairID][0]; BYTE Joker[4] = { 0 }; return OnUserOutCard(wChairID, cbCardData, cbCardCount, CT_SINGLE, Joker,0); } else { //出牌广播 CMD_S_Out_Broadcast_SK OutCard = { 0 }; OutCard.wOutCardUser = wChairID; OutCard.cbOperateType = OPERATE_MASK_NOOUT_Poker; OutCard.cbIsTrusteeOut = 1; OutCard.cbLeftCount = m_cbCardDataCount[wChairID]; m_pITableFrame->SendTableData(INVALID_CHAIR, OPERATE_MASK_NOOUT_Poker, &OutCard, sizeof(OutCard)); m_pITableFrame->SendLookonData(INVALID_CHAIR, OPERATE_MASK_NOOUT_Poker, &OutCard, sizeof(OutCard)); RepayRecord(INVALID_CHAIR, OPERATE_MASK_NOOUT_Poker, &OutCard, sizeof(OutCard)); return NextOperate(wChairID); } } bool CTableFrameSinkPoker::SendTeamfrindCards(WORD MyWchairID) { //myWchirID 标示 把我的牌 发给我的队友 WORD myTeamFrindChirID = (MyWchairID + 2 )% GAME_PLAYER; if (IsWinByChairID(myTeamFrindChirID)) { //队友手牌 // struct CMD_S_TEAMMATE_HANDCARD // { // WORD wTeammateChairID; //队友座位 // BYTE cbCardData[27]; //队友手牌 // }; CMD_S_TEAMMATE_HANDCARD st = { 0 }; st.wTeammateChairID = myTeamFrindChirID; CopyMemory(st.cbCardData, m_cbCardData[MyWchairID], m_cbCardDataCount[MyWchairID]); m_pITableFrame->SendTableData(myTeamFrindChirID, SUB_S_TEAMMATE_HANDCARD_Poker, &st, sizeof(st)); //RepayRecord(myTeamFrindChirID, SUB_S_TEAMMATE_HANDCARD_Poker, &st, sizeof(st)); } return true; } bool CTableFrameSinkPoker::RestartRank(const BYTE cbRank[4], BYTE outRandToEnd[4]) { memset(outRandToEnd, 0xff, 4); for (int i = 0; i < 4;i++) { for (int j = 0; j < 4;j++) { if (cbRank[j]==i) { outRandToEnd[i] = j+1; } } } return 0; } BOOL CTableFrameSinkPoker::DeleteListOutCardRecord(DWORD wChairID) { list::iterator it; for (it = m_listOutCard.begin(); it != m_listOutCard.end();) { if (it->wOutCardUser == wChairID) it = m_listOutCard.erase(it); //返回下一个有效的迭代器,无需+1 else ++it; } return TRUE; } void CTableFrameSinkPoker::ReadGameData() { CString strFileName; strFileName = _T("Table.dat"); if (!PathFileExists(_T("Table.dat"))) { return; } HANDLE hFile = CreateFile(strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwRead; DWORD dwFileSize; DWORD fileSize = GetFileSize(hFile, &dwFileSize); if (fileSize != 108) { CloseHandle(hFile); return; } SetFilePointer(hFile, 0, 0, FILE_BEGIN); ReadFile(hFile, m_cbRepertoryCard, 108, &dwRead, NULL); CloseHandle(hFile); } } BOOL CTableFrameSinkPoker::IsHaveBoomCountScore(BYTE wCharid, BYTE cbCardCount, WORD & WinScore) { int nFu = m_BoomCountInfo[wCharid][cbCardCount - 4]; int nXian = cbCardCount; if (nFu<3) { return FALSE; } if (nFu==3&&nXian<=5) { return FALSE; } int tmpXian = 0; switch (nXian) { case 4: tmpXian = nFu + 1; break; case 5: tmpXian = nFu + 4; break; case 6: case 7: case 8: case 9:{ tmpXian = nFu + nXian; break; } default: break; } //计算分数 switch (tmpXian) { case 5: WinScore = 1 * (m_cbPlayerNum - 1); break; case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: WinScore = pow(2, tmpXian - 5) * 3; break; default: break; } return TRUE; } bool CTableFrameSinkPoker::OnUserOutCard(WORD wChairID, BYTE bCardData[], BYTE bCardCount, BYTE cbCardType, BYTE cbJokerReplacePoker[4],BYTE LianxianInfo) { m_lastLianxianInfo = LianxianInfo; // OutputDebugString(_T("OnUserOutCard ")); CopyMemory(m_cbJokerReplacePoker[wChairID], cbJokerReplacePoker, sizeof(cbJokerReplacePoker)); // PrintCards(cbJokerReplacePoker,sizeof(cbJokerReplacePoker)); //效验状态 if (wChairID != m_wCurrentUser) { OutputDebugString(L"当前玩家和出牌玩家不是一个 返回失败"); return false; } //生成出牌数据(不带花色) OutCard struOutCard = { 0 }; struOutCard.wOutCardUser = wChairID; memcpy(struOutCard.cbOutCardData, bCardData, bCardCount*sizeof(BYTE)); SortCard(struOutCard.cbOutCardData, bCardCount); struOutCard.cbOutCardCount = bCardCount; struOutCard.cbOutCardType = cbCardType; //变幻扑克 //[10040] 1b,1b,0b,1c,0c,0c,3d,0d,0d,4e,4f,4f, PrintCards(bCardData, bCardCount); PrintCards(cbJokerReplacePoker, 4);//[10040] 0b,0c,0d,00, //将王牌替换 BYTE cbMagicCardData[MAX_COUNT_Poker] = { 0 }; CopyMemory(cbMagicCardData, bCardData, bCardCount); m_GameLogic.ReplaceWangCards(bCardData, bCardCount, cbJokerReplacePoker, cbMagicCardData); //m_GameLogic.MagicCardData(bCardData, bCardCount, cbMagicCardData); PrintCards(cbMagicCardData, bCardCount); //[10040] 1b,1b,0b,1c,0c,0c,3d,0d,0d,4e,4f,4f, //判断是否为自由出牌 BYTE cbIsFreeOut = BeOutCardFree(wChairID); ////出牌判断 目前前端已经判断 稍后重构这部分判断 if (m_cbTurnCardCount != 0 && cbIsFreeOut == false) { //对比扑克 if (m_GameLogic.CompareCard(m_cbMagicCardData, cbMagicCardData, m_cbTurnCardCount, bCardCount) == false) { ASSERT(FALSE); OutputDebugString(L"扑克比较 失败,出牌玩家的牌没有上家大 返回失败"); return false; } } //类型判断 BYTE cbStarLevel; BomoType bomoinof; BYTE bCardType = m_GameLogic.GetCardType(cbMagicCardData, bCardCount, cbStarLevel, bomoinof); if (bCardType == 7 && bCardCount == 4) { m_BomoCouut[wChairID]++; } if (bCardType == CT_BOMB&&bCardCount>=4) { m_BoomCountInfo[wChairID][bCardCount - 4]++; } if (bCardType>=10) { bCardType = 10; } //删除扑克 if (m_GameLogic.RemoveCard(bCardData, bCardCount, m_cbCardData[wChairID], m_cbCardDataCount[wChairID]) == false) { OutputDebugString(_T("删除扑克失败失败")); ASSERT(FALSE); return false; } //出牌记录 memset(&m_struOutCard, 0, sizeof(OutCard)); memcpy(&m_struOutCard, &struOutCard, sizeof(OutCard)); memcpy(struOutCard.cbOutCardData, bCardData, bCardCount*sizeof(BYTE)); m_listOutCard.push_back(struOutCard); //设置变量 m_cbTurnCardCount = bCardCount; m_cbCardDataCount[wChairID] -= bCardCount; CopyMemory(m_cbTurnCardData, bCardData, sizeof(BYTE)*bCardCount); CopyMemory(m_cbMagicCardData, cbMagicCardData, sizeof(BYTE)*bCardCount); /* struct CMD_S_Out_Broadcast_SK { WORD wOutCardUser; //出牌用户 WORD cbOperateType; //操作类型 WORD cbCardType; //出牌牌型 BYTE cbJokerReplacePoker[4];//替换癞子的牌 BYTE cbOutCardData[27]; //出牌扑克 BYTE cbIsFreeOut; //是否自由出牌 BYTE cbIsTrusteeOut; //是否托管出牌 BYTE cbLeftCount; //剩余牌数 BYTE cbRanking; //当前名次 }; */ if (m_cbCardDataCount[wChairID] == 0){ //设置用户 m_wWinOrder[m_wWinCount++] = wChairID; m_wTurnWiner = wChairID; } m_cbResponse[wChairID] = 2; CMD_S_Out_Broadcast_SK outCard = { 0 }; outCard.wOutCardUser = wChairID; outCard.cbOperateType = OPERATE_MASK_OUT_Poker; outCard.cbCardType = bCardType; CopyMemory(outCard.cbJokerReplacePoker, cbJokerReplacePoker, sizeof(cbJokerReplacePoker)); CopyMemory(outCard.cbOutCardData, bCardData, bCardCount*sizeof(BYTE)); outCard.cbIsFreeOut = cbIsFreeOut; outCard.cbIsTrusteeOut = 0; outCard.cbLeftCount = m_cbCardDataCount[wChairID]; outCard.cbRanking[0] = m_wWinOrder[0]; outCard.cbRanking[1] = m_wWinOrder[1]; outCard.cbRanking[2] = m_wWinOrder[2]; outCard.cbRanking[3] = m_wWinOrder[3]; outCard.LianXianInfo = LianxianInfo; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); RepayRecord(INVALID_CHAIR, SUB_S_OUT_BROADCAST_Poker, &outCard, sizeof(outCard)); PrintCards((const BYTE*)&outCard, sizeof(CMD_S_Out_Broadcast_SK)); //胜利判断 if (m_cbCardDataCount[wChairID] == 0) { //用户统计 if (m_cbCardDataCount[(wChairID + 2) % GAME_PLAYER] == 0) m_wCurrentUser = INVALID_CHAIR; //把队友的牌发给我 BYTE TeamFrindChairid = (wChairID + 2) % GAME_PLAYER; SendTeamfrindCards(TeamFrindChairid); //m_cbResponse[wChairID] = 0; } else { SendTeamfrindCards(wChairID); } if (m_gameConfig.HaveBoomScore) { //判断是否是大牌 BomoType BomoInfo; WORD WinScore = 0; if (IsTeShuCard(cbMagicCardData, bCardCount, BomoInfo, WinScore)) { if (bCardType==CT_BOMB) { IsHaveBoomCountScore(wChairID, bCardCount, WinScore); } OutputDebugString(_T("特殊牌")); PrintCards(cbMagicCardData, bCardCount); CMD_S_JiangJin jiangjin; jiangjin.wOperateUser = wChairID; ZeroMemory(jiangjin.cbCardData, MAX_COUNT_Poker); CopyMemory(jiangjin.cbCardData, bCardData, bCardCount); cbCardType = bCardType; m_BomoCouut[wChairID]++; //这个tmp 应该是计算出来的 int tmpScore = WinScore; if (m_BomoCouut[wChairID] >= 4) { tmpScore += (m_BomoCouut[wChairID] - 3) * 3; CString strInfo; strInfo.Format(_T("tmpScore =%d m_BomoCouut[wChairID] =%d"), tmpScore, m_BomoCouut[wChairID]); OutputDebugString(strInfo); } jiangjin.Scores[wChairID] = tmpScore; m_lGameGongXianScore[wChairID] += tmpScore; jiangjin.TureScores[wChairID] = m_lGameGongXianScore[wChairID]; for (int i = 0; i < m_cbPlayerNum; i++) { if (wChairID == i) { continue; } jiangjin.Scores[i] = 0 - tmpScore / 3; m_lGameGongXianScore[i] += jiangjin.Scores[i]; jiangjin.TureScores[i] = m_lGameGongXianScore[i]; CString strInfo; strInfo.Format(_T("ID=%d jiangjin.Scores =%d m_lGameGongXianScore =%d\r\n"), i, jiangjin.Scores[i], m_lGameGongXianScore[i]); OutputDebugString(strInfo); } m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); RepayRecord(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); } else if (bCardType == 7 && bCardCount == 4 && m_BomoCouut[wChairID] >= 4) { int tmpScore = 0; if (m_BomoCouut[wChairID] >= 4) { tmpScore += (m_BomoCouut[wChairID] - 3) * 3; } if (bCardType == CT_BOMB) { WORD WinScore = 0; IsHaveBoomCountScore(wChairID, bCardCount, WinScore); tmpScore += WinScore; } CMD_S_JiangJin jiangjin; jiangjin.wOperateUser = wChairID; ZeroMemory(jiangjin.cbCardData, MAX_COUNT_Poker); CopyMemory(jiangjin.cbCardData, bCardData, bCardCount); jiangjin.Scores[wChairID] = tmpScore; m_lGameGongXianScore[wChairID] += tmpScore; jiangjin.TureScores[wChairID] = m_lGameGongXianScore[wChairID]; for (int i = 0; i < m_cbPlayerNum; i++) { if (wChairID == i) { continue; } jiangjin.Scores[i] = 0 - tmpScore / 3; m_lGameGongXianScore[i] += jiangjin.Scores[i]; jiangjin.TureScores[i] = m_lGameGongXianScore[i]; } m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); RepayRecord(INVALID_CHAIR, SUB_S_GAME_JiangJin_Poker, &jiangjin, sizeof(jiangjin)); // OutputDebugString(_T("普通")); // PrintCards(cbMagicCardData, bCardCount); } } //结束判断 if (m_wCurrentUser == INVALID_CHAIR) { OnEventGameConclude(wChairID, NULL, GER_NORMAL); return true; } return NextOperate(wChairID); } bool CTableFrameSinkPoker::BeOutCardFree(WORD wChairID) { for (BYTE i = 0; i < GAME_PLAYER; ++i) { if (i == wChairID) continue; if (m_cbResponse[i] == 2) return false; } ZeroMemory(m_cbResponse, sizeof(m_cbResponse)); MyZeroMemory(m_cbUserOPerate_mask); return true; } bool CTableFrameSinkPoker::NextOperate(WORD wChairID) { //切换用户 PrintCards(m_cbResponse, 4); do { //设置用户 m_wCurrentUser = (m_wCurrentUser + 1) % GAME_PLAYER; //完成判断 if (m_wCurrentUser == m_wTurnWiner) { //设置变量 //m_cbTurnCardCount = 0; if (BeOutCardFree(m_wCurrentUser)) { //接风处理 if (m_cbCardDataCount[m_wTurnWiner] == 0) { m_wCurrentUser = (m_wTurnWiner + 2) % GAME_PLAYER; } m_wTurnWiner = INVALID_CHAIR; ZeroMemory(m_cbResponse, sizeof(m_cbResponse)); MyZeroMemory(m_cbUserOPerate_mask); break; } else { m_cbResponse[m_wTurnWiner] = 0; m_cbUserOPerate_mask[m_wTurnWiner] = 0; m_wTurnWiner = INVALID_CHAIR; } } //继续处理 if (m_cbCardDataCount[m_wCurrentUser] != 0){ break; } else { if (m_cbResponse[m_wCurrentUser] == 2 && m_wWinCount==2) { m_cbResponse[m_wCurrentUser] = 0; } } } while (true); /* struct CMD_S_Operate_SK { WORD wOperateUser; //操作用户 WORD wOperateType; //操作掩码 BYTE cbOptTime; //操作时间(秒) BYTE cbIsFreeOut; //是否自由出牌 }; */ PrintCards(m_cbResponse, 4);//1 0 2 1 CMD_S_Operate_SK Operate = { 0 }; Operate.wOperateUser = m_wCurrentUser; if (!BeOutCardFree(m_wCurrentUser)) { Operate.cbIsFreeOut = 0; m_cbHintNum = 0; m_cbCurrentHintNum = 0; mHistList.clear(); if (m_GameLogic.bCanOutCard(m_cbMagicCardData, m_cbTurnCardCount, m_cbCardData[m_wCurrentUser], m_cbCardDataCount[m_wCurrentUser],mHistList)) { //要得起 Operate.wOperateType = OPERATE_MASK_OUT_Poker | OPERATE_MASK_HINT_Poker | OPERATE_MASK_PASS_Poker; } else { //要不起 Operate.wOperateType = OPERATE_MASK_NOOUT_Poker ; } m_cbHintNum = mHistList.size(); DeleteListOutCardRecord(m_wCurrentUser); } else {//自由 mHistList.clear(); m_GameLogic.FindAllHit(m_cbCardData[m_wCurrentUser], m_cbCardDataCount[m_wCurrentUser], mHistList); m_cbHintNum = mHistList.size(); Operate.cbIsFreeOut = 1; Operate.wOperateType = OPERATE_MASK_OUT_Poker | OPERATE_MASK_HINT_Poker; // CString strOut; // strOut.Format(_T("有玩家自由 清空替换牌WID =%d"), m_wCurrentUser); // OutputDebugString(strOut); PrintCards(m_cbJokerReplacePoker[0], 16); ZeroMemory(m_cbJokerReplacePoker, sizeof(m_cbJokerReplacePoker)); m_listOutCard.clear(); } //清空当前玩家出过的牌 m_wCurrentOperate = Operate.wOperateType; Operate.cbOptTime = GAME_TIMEOUT; Operate.LianXianInfo = m_lastLianxianInfo; m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_Poker, &Operate, sizeof(Operate)); m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_Poker, &Operate, sizeof(Operate)); RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_Poker, &Operate, sizeof(Operate)); //if (wChairID == m_wTurnWiner&&m_cbResponse[wChairID]!=0) //{ // m_cbResponse[wChairID] = 0; //} return true; } void CTableFrameSinkPoker::PrintCards(const BYTE cbCardData[], short cbCount) { CString strPrint; for (int i = 0; i < cbCount;i++) { CString str; str.Format(_T("%02x,"),cbCardData[i]); strPrint += str; } CString tmp1; tmp1.Format(L" 字节数=%d", cbCount); strPrint += tmp1; strPrint.Append(_T("\r\n")); OutputDebugString(strPrint); } void CTableFrameSinkPoker::FindCardOwner(BOOL &bSwitchChair) { /* 开始计算变换位置 */ bSwitchChair = false; WORD wSourceID[] = { INVALID_CHAIR, INVALID_CHAIR }; if (m_wBankerUser == INVALID_CHAIR) { //寻找庄家用户 for (WORD userIndex = 0; userIndex < m_cbPlayerNum; userIndex++) { for (BYTE j = 0; j < MAX_COUNT_Poker; j++) { if (m_cbCardData[userIndex][j] == m_cbStartRandCard) { m_wBankerUser = userIndex; break; } } if (m_wBankerUser != INVALID_CHAIR) break; } ASSERT(m_wBankerUser != INVALID_CHAIR); //wGetRandCardID[0] = m_wBankerUser; //寻找对家 分2中情况 1:庄家全有 2 任意一家有 for (WORD UserIndex = 0; UserIndex < m_cbPlayerNum; UserIndex++) { BYTE TmpCardPosition[2] = { 0 }; if (UserIndex == m_wBankerUser) { if (m_GameLogic.FindHaveCardCount(m_cbCardData[UserIndex], m_cbCardDataCount[UserIndex], m_cbStartRandCard, TmpCardPosition) == 2) { break; } } if (m_GameLogic.FindHaveCardCount(m_cbCardData[UserIndex], m_cbCardDataCount[UserIndex], m_cbStartRandCard, TmpCardPosition) == 1) { //2中情况 拥有该牌的玩家 坐在庄家对边 和没做在庄家对面 if (UserIndex != m_wBankerUser&&UserIndex != (m_wBankerUser + 2) % m_cbPlayerNum) { //拥有一样的牌的玩家,并没有坐在庄家对面 m_wSourceID[0] = UserIndex; m_wSourceID[1] = (m_wBankerUser + 2) % m_cbPlayerNum; //对家找到了 bSwitchChair = true; } if (UserIndex != m_wBankerUser&&UserIndex == (m_wBankerUser + 2) % m_cbPlayerNum) { //拥有一样的牌的玩家,坐在对面了 //对家找到了 } } if (bSwitchChair == TRUE) { break; } } } // CString str; // str.Format(_T("变换完毕 是否变换=%d 变换玩家的ID=%d %d CardData=0x%x"), bSwitchChair, wSourceID[0], wSourceID[1], m_cbStartRandCard); // OutputDebugString(str); }