诸暨麻将添加redis
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

4583 řádky
147 KiB

  1. #include "StdAfx.h"
  2. #include "TableFrameSink_dcs.h"
  3. #include <algorithm>
  4. #include "../俱乐部/Source/MessageDef/Pb_SparrowMaJiang.pb.h"
  5. #include "../俱乐部/Source/MessageDef/Pb_RecordPacket.pb.h"
  6. //#include "../俱乐部/Source/GlobalDef/Util.h"
  7. //构造函数
  8. CTableFrameSink_dcs::CTableFrameSink_dcs() :m_GameLogic(this)
  9. {
  10. //游戏变量
  11. m_startTime = 0;
  12. mPlayGameUserCount = 4;
  13. m_lSiceCount = 0;
  14. m_wBankerUser = INVALID_CHAIR;
  15. ZeroMemory(m_cbCardIndex, sizeof(m_cbCardIndex));
  16. ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
  17. ZeroMemory(m_bPlayStatus, sizeof(m_bPlayStatus));
  18. ZeroMemory(m_lGameScore, sizeof(m_lGameScore));
  19. ZeroMemory(m_lGameTatolScore, sizeof(m_lGameTatolScore));
  20. ZeroMemory(m_HuPai, sizeof(m_HuPai));
  21. ZeroMemory(m_PaiQuan, sizeof(m_PaiQuan));
  22. ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数
  23. ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌
  24. ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  25. ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  26. //出牌信息
  27. m_cbOutCardData = 0;
  28. m_cbOutCardCount = 0;
  29. m_wOutCardUser = INVALID_CHAIR;
  30. ZeroMemory(m_cbDiscardCard, sizeof(m_cbDiscardCard));
  31. ZeroMemory(m_cbDiscardCount, sizeof(m_cbDiscardCount));
  32. ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData));
  33. ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount));
  34. ZeroMemory(LianXuHuPai, sizeof(LianXuHuPai));
  35. //发牌信息
  36. m_cbSendCardData = 0;
  37. m_cbSendCardCount = 0;
  38. m_cbLeftCardCount = 0;
  39. m_cbShiJiLeftCardCount = 0;
  40. ZeroMemory(m_cbRepertoryCard, sizeof(m_cbRepertoryCard));
  41. m_cbGangCount = 0;//打了几个杠
  42. //运行变量
  43. m_cbProvideCard = 0;
  44. m_wResumeUser = INVALID_CHAIR;
  45. m_wCurrentUser = INVALID_CHAIR;
  46. m_wProvideUser = INVALID_CHAIR;
  47. //状态变量
  48. //m_bSendStatus=false;
  49. // m_bGangStatus = false;
  50. m_GangPrivedUserID = -1;
  51. m_bGangOption = 0;
  52. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  53. m_bQiangGang = false;
  54. //用户状态
  55. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  56. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  57. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  58. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  59. ZeroMemory(m_cbOperateCaiCard, sizeof(m_cbOperateCaiCard));
  60. //组合扑克
  61. ZeroMemory(m_WeaveItemArray, sizeof(m_WeaveItemArray));
  62. ZeroMemory(m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  63. //结束信息
  64. ZeroMemory(m_HuPai, sizeof(m_HuPai));
  65. ZeroMemory(m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));
  66. //组件变量
  67. m_pITableFrame = NULL;
  68. m_pGameServiceOption = NULL;
  69. bIsHuang = false;
  70. mMaxTaiNum = 5;
  71. //////////////////////////////////////////////////////////////////////////
  72. CString strCfgFile;
  73. GetModuleFileName(NULL, strCfgFile.GetBufferSetLength(MAX_PATH), MAX_PATH);
  74. strCfgFile.ReleaseBuffer();
  75. WCHAR* pTmp = wcsrchr(strCfgFile.GetBuffer(), L'\\');
  76. if (pTmp)
  77. {
  78. *pTmp = 0;
  79. }
  80. PathAppend(strCfgFile.GetBufferSetLength(MAX_PATH), _T("cfg.ini"));
  81. strCfgFile.ReleaseBuffer();
  82. GetPrivateProfileString(_T("datpath"), _T("value"), _T(""), mTableDatastrPath.GetBufferSetLength(MAX_PATH), MAX_PATH, strCfgFile.GetBuffer());
  83. mTableDatastrPath.ReleaseBuffer();
  84. mBWriteTableData = GetPrivateProfileInt(_T("writedata"), _T("value"), 0, strCfgFile.GetBuffer());
  85. //////////////////////////////////////////////////////////////////////////
  86. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  87. ZeroMemory(mCmd_NotifyQianggh, sizeof(mCmd_NotifyQianggh));
  88. mBCanShowLeft = TRUE;
  89. //ZeroMemory(mCanDingCaiCard, MAX_INDEX);
  90. memset(mCanDingCaiCardArray, 4, MAX_INDEX*GAME_PLAYER);
  91. //memset(mLastCaiCardCountArray, 0, GAME_PLAYER);
  92. m_bTwoPlayerFlag = FALSE;
  93. return;
  94. }
  95. //析构函数
  96. CTableFrameSink_dcs::~CTableFrameSink_dcs(void)
  97. {
  98. }
  99. //接口查询
  100. void * CTableFrameSink_dcs::QueryInterface(const IID & Guid, DWORD dwQueryVer)
  101. {
  102. //查询接口
  103. //#define QUERYINTERFACE(Interface,Guid,dwQueryVer)
  104. if ((Guid == IID_ITableFrameSink) && (InterfaceVersionCompare(dwQueryVer, VER_ITableFrameSinkCxz)))
  105. return static_cast<ITableFrameSink *>(this);
  106. if ((Guid == IID_ITableUserAction) && (InterfaceVersionCompare(dwQueryVer, VER_ITableUserAction)))
  107. return static_cast<ITableUserAction *>(this);
  108. //查询接口
  109. //#define QUERYINTERFACE_IUNKNOWNEX(BaseInterface,Guid,dwQueryVer)
  110. if ((Guid == IID_IUnknownEx) && (InterfaceVersionCompare(dwQueryVer, VER_IUnknownEx)))
  111. return static_cast<IUnknownEx *>(static_cast<ITableFrameSink *>(this));
  112. //
  113. // QUERYINTERFACE(ITableFrameSink,Guid,dwQueryVer);
  114. // QUERYINTERFACE(ITableUserAction,Guid,dwQueryVer);
  115. // QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink,Guid,dwQueryVer);
  116. return NULL;
  117. }
  118. //初始化
  119. bool CTableFrameSink_dcs::Initialization(IUnknownEx * pIUnknownEx)
  120. {
  121. //查询接口
  122. ASSERT(pIUnknownEx != NULL);
  123. m_pITableFrame = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableFrame);
  124. if (m_pITableFrame == NULL)
  125. return false;
  126. //获取参数
  127. m_pGameServiceOption = m_pITableFrame->GetGameServiceOption();
  128. ASSERT(m_pGameServiceOption != NULL);
  129. //开始模式
  130. m_pITableFrame->SetStartMode(START_MODE_FULL_READY);
  131. return true;
  132. }
  133. //复位桌子
  134. VOID CTableFrameSink_dcs::RepositionSink()
  135. {
  136. //游戏变量
  137. m_startTime = time(0);
  138. m_startTime = 0;
  139. m_lSiceCount = 0;
  140. ZeroMemory(m_cbCardIndex, sizeof(m_cbCardIndex));
  141. ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
  142. //ZeroMemory( m_cbGenCount,sizeof(m_cbGenCount) );
  143. ZeroMemory(m_bPlayStatus, sizeof(m_bPlayStatus));
  144. //m_cbWinCount = 0;
  145. //memset( m_wWinOrder,INVALID_CHAIR,sizeof(m_wWinOrder) );
  146. //ZeroMemory( m_lGameTax,sizeof(m_lGameTax) );
  147. ZeroMemory(m_PaiQuan, sizeof(m_PaiQuan));
  148. ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数
  149. ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌
  150. ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  151. ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  152. //出牌信息
  153. m_cbOutCardData = 0;
  154. m_cbOutCardCount = 0;
  155. m_wOutCardUser = INVALID_CHAIR;
  156. ZeroMemory(m_cbDiscardCard, sizeof(m_cbDiscardCard));
  157. ZeroMemory(m_cbDiscardCount, sizeof(m_cbDiscardCount));
  158. ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData));
  159. ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount));
  160. //发牌信息
  161. m_cbSendCardData = 0;
  162. m_cbSendCardCount = 0;
  163. m_cbLeftCardCount = 0;
  164. m_cbShiJiLeftCardCount = 0;
  165. ZeroMemory(m_cbRepertoryCard, sizeof(m_cbRepertoryCard));
  166. m_cbGangCount = 0;//打了几个杠
  167. //运行变量
  168. m_cbProvideCard = 0;
  169. m_wResumeUser = INVALID_CHAIR;
  170. m_wCurrentUser = INVALID_CHAIR;
  171. m_wProvideUser = INVALID_CHAIR;
  172. m_wBankerUser = INVALID_CHAIR;
  173. //状态变量
  174. //m_bSendStatus=false;
  175. // m_bGangStatus = false;
  176. m_GangPrivedUserID = -1;
  177. m_bGangOption = 0;
  178. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  179. m_bQiangGang = false;
  180. //用户状态
  181. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  182. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  183. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  184. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  185. ZeroMemory(m_cbOperateCaiCard, sizeof(m_cbOperateCaiCard));
  186. //组合扑克
  187. ZeroMemory(m_WeaveItemArray, sizeof(m_WeaveItemArray));
  188. ZeroMemory(m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  189. //结束信息
  190. m_cbMagicFirstData = 0;
  191. m_cbMagicSecondData = 0;
  192. bIsHuang = false;
  193. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  194. ZeroMemory(mCmd_NotifyQianggh, sizeof(mCmd_NotifyQianggh));
  195. mBCanShowLeft = true;
  196. memset(mCanDingCaiCardArray, 4, MAX_INDEX*GAME_PLAYER);
  197. //memset(mLastCaiCardCountArray, 0, GAME_PLAYER);
  198. return;
  199. }
  200. bool CTableFrameSink_dcs::RepayRecordStart()
  201. {
  202. m_bReplayRecordStart = true;
  203. m_UserReplayRecord.clear();
  204. return true;
  205. }
  206. bool CTableFrameSink_dcs::RepayRecordEnd()
  207. {
  208. if (!m_bReplayRecordStart)
  209. return false;
  210. m_bReplayRecordStart = false;
  211. CMD_GR_ReplayRecordResp urr;
  212. ZeroMemory(&urr, sizeof(CMD_GR_ReplayRecordResp));
  213. urr.m_UUID = 0;
  214. urr.m_UserId = 0;
  215. urr.m_startTime = m_startTime;
  216. urr.m_endTime = time(0);
  217. urr.m_gameconfig = m_gameConfig;
  218. //urr.m_UserId = pIServerUserItem->GetUserID();
  219. for (int j = 0; j < mPlayGameUserCount; ++j)
  220. {
  221. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  222. {
  223. continue;
  224. }
  225. IServerUserItem * pIServerUserItem = m_pITableFrame->GetTableUserItem(j);
  226. if ((pIServerUserItem == NULL) /*|| (pIServerUserItem->IsClientReady() == false)*/)
  227. continue;
  228. auto& chairInfo = urr.m_chairList[j];
  229. chairInfo.dwUserId = pIServerUserItem->GetUserID();
  230. chairInfo.wChairId = pIServerUserItem->GetChairID();
  231. lstrcpy(chairInfo.userName, pIServerUserItem->GetNickName());
  232. lstrcpy(chairInfo.headUrl, pIServerUserItem->GetUserInfo()->szHeadUrl);
  233. }
  234. urr.m_recordCount = m_UserReplayRecord.size();
  235. RecordPacket::PB_CS_S_ReplayRecordResp RecordResp;
  236. RecordResp.set_m_uuid(urr.m_UUID);
  237. RecordResp.set_m_userid(urr.m_UserId);
  238. RecordResp.set_m_starttime(urr.m_startTime);
  239. RecordResp.set_m_endtime(urr.m_endTime);
  240. RecordResp.mutable_m_gameconfig()->set_bduolai(m_gameConfig.bDuoLai);
  241. RecordResp.mutable_m_gameconfig()->set_isowner(m_gameConfig.IsOwner);
  242. RecordResp.mutable_m_gameconfig()->set_roomid(m_gameConfig.RoomId);
  243. std::string sPrivateTableID = CW2AEX<1024>(m_gameConfig.sPrivateTableID, CP_UTF8).m_psz;
  244. RecordResp.mutable_m_gameconfig()->set_sprivatetableid(sPrivateTableID);
  245. RecordResp.mutable_m_gameconfig()->set_tmp1(m_gameConfig.tmp1);
  246. RecordResp.mutable_m_gameconfig()->set_tmp2(m_gameConfig.tmp2);
  247. RecordResp.mutable_m_gameconfig()->set_wdiscore(m_gameConfig.wDiScore);
  248. RecordResp.mutable_m_gameconfig()->set_wfanfei(m_gameConfig.wFanFei);
  249. RecordResp.mutable_m_gameconfig()->set_wfengding(m_gameConfig.wFengDing);
  250. RecordResp.mutable_m_gameconfig()->set_whadplaycount(m_gameConfig.wHadPlayCount);
  251. RecordResp.mutable_m_gameconfig()->set_wiplimit(m_gameConfig.wIpLimit);
  252. RecordResp.mutable_m_gameconfig()->set_wplaycountrule(m_gameConfig.wPlayCountRule);
  253. RecordResp.mutable_m_gameconfig()->set_wsubgameid(m_gameConfig.wSubGameID);
  254. for (WORD i = 0; i < mPlayGameUserCount; i++)
  255. {
  256. RecordPacket::pb_ChairRecord* Record = RecordResp.add_m_chairlist();
  257. Record->set_wchairid(urr.m_chairList[i].wChairId);
  258. Record->set_dwuserid(urr.m_chairList[i].dwUserId);
  259. std::string userName = CW2AEX<1024>(urr.m_chairList[i].userName, CP_UTF8).m_psz;
  260. std::string headUrl = CW2AEX<1024>(urr.m_chairList[i].headUrl, CP_UTF8).m_psz;
  261. Record->set_username(userName);
  262. Record->set_headurl(headUrl);
  263. }
  264. for (auto& grp : m_UserReplayRecord)
  265. {
  266. RecordPacket::pb_GameRecordPacket* Packet = RecordResp.add_precordpacket();
  267. Packet->set_wchairid(grp.wchairid());
  268. Packet->set_wsubcmdid(grp.wsubcmdid());
  269. Packet->set_wmaincmdid(grp.wmaincmdid());
  270. Packet->set_pdata(grp.pdata());
  271. }
  272. std::string pbresp = RecordResp.SerializePartialAsString();
  273. m_pITableFrame->SaveReplayRecord((void*)pbresp.c_str(), pbresp.length());
  274. m_UserReplayRecord.clear();
  275. //delete replyRecordData;不能删除,已托管给SaveReplayRecord函数
  276. return true;
  277. }
  278. bool CTableFrameSink_dcs::RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize)
  279. {
  280. RecordPacket::pb_GameRecordPacket pRecordPacket;
  281. pRecordPacket.set_wchairid(wChairID);
  282. pRecordPacket.set_wsubcmdid(wSubCmdId);
  283. pRecordPacket.set_wmaincmdid(MDM_GF_GAME);
  284. pRecordPacket.set_pdata((char*)pData, wSize);
  285. m_UserReplayRecord.push_back(pRecordPacket);
  286. return true;
  287. }
  288. //游戏开始
  289. bool CTableFrameSink_dcs::OnEventGameStart()
  290. {
  291. ZeroMemory(m_lGameScore, sizeof(m_lGameScore));
  292. srand((unsigned)time(NULL)*mGameTableId);
  293. m_cbMagicFirstData = 0;
  294. m_cbMagicSecondData = 0;
  295. //椅子数量
  296. WORD wChairCount = m_pITableFrame->GetChairCount();
  297. //开始记录回放数据
  298. RepayRecordStart();
  299. //重置发牌状态
  300. m_isCanOutCard = false;
  301. //重置掉线玩家列表
  302. m_offlineUsers.clear();
  303. //设置状态
  304. m_pITableFrame->SetGameStatus(GS_MJ_PLAY);
  305. //打印时间
  306. DWORD timet = GetTickCount();
  307. m_gameConfig.wHadPlayCount++;
  308. //混乱扑克,洗牌
  309. m_lSiceCount = MAKELONG(MAKEWORD(rand() % 6 + 1, rand() % 6 + 1), MAKEWORD(rand() % 6 + 1, rand() % 6 + 1));
  310. if (m_bTwoPlayerFlag)
  311. {
  312. m_cbLeftCardCount = m_GameLogic.RandCardData_Two(m_cbRepertoryCard);
  313. }
  314. else
  315. {
  316. m_cbLeftCardCount = m_GameLogic.RandCardData(m_cbRepertoryCard);
  317. }
  318. WritePaiCardData(m_gameConfig.sPrivateTableID, m_gameConfig.wHadPlayCount);
  319. if (1 == m_gameConfig.wHadPlayCount || m_wNextBankerUser == INVALID_CHAIR)
  320. {
  321. m_wBankerUser = 0;
  322. }
  323. else
  324. {
  325. m_wBankerUser = m_wNextBankerUser;
  326. }
  327. m_wNextBankerUser = INVALID_CHAIR;
  328. //BYTE byTest[] = {
  329. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  330. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  331. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  332. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  333. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  334. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  335. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  336. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  337. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  338. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  339. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  340. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  341. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  342. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  343. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  344. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北 中发白
  345. //};
  346. //if (m_GameLogic.PeiPai(byTest))
  347. // CopyMemory(m_cbRepertoryCard, byTest, sizeof(byTest));
  348. //////////////////////////////////////////////////////////////////////////
  349. ReadGameData();
  350. /*m_wBankerUser = 2;*/
  351. //////////////////////////////////////////////////////////////////////////
  352. //分发扑克
  353. for (WORD i = 0; i < mPlayGameUserCount; i++)
  354. {
  355. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  356. {
  357. continue;
  358. }
  359. m_bPlayStatus[i] = true;
  360. m_cbLeftCardCount -= (MAX_COUNT - 1);//每一个玩家都发出去13张牌,还剩多少
  361. m_cbSendCardCount += (MAX_COUNT - 1);//每个玩家加13张牌
  362. m_GameLogic.SwitchToCardIndex(&m_cbRepertoryCard[m_cbLeftCardCount], MAX_COUNT - 1, m_cbCardIndex[i]);
  363. }
  364. //发送扑克,庄家摸牌
  365. m_cbSendCardCount++;//第十四张牌
  366. m_cbSendCardData = m_cbRepertoryCard[--m_cbLeftCardCount];
  367. //设置变量
  368. m_cbProvideCard = 0;
  369. m_wProvideUser = m_wBankerUser & 0x000F;
  370. m_wCurrentUser = m_wBankerUser & 0x000F;
  371. WORD ActionCard[6] = { 0 };
  372. m_GameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  373. // 胡牌判断
  374. CChiHuRight chr;
  375. BYTE TaiShu = 0;
  376. m_cbUserAction[m_wCurrentUser] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[m_wCurrentUser], NULL, 0, m_cbSendCardData, chr, TaiShu);
  377. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  378. if (m_cbUserAction[m_wCurrentUser] & WIK_ZI_MO)
  379. {
  380. m_cbUserAction[m_wCurrentUser] = WIK_TIAN_ZI_MO;
  381. }
  382. std::vector<CanDcsSt> vCards;
  383. if (GetMagicCardAndTaiNum(m_cbCardIndex[m_wCurrentUser], m_wCurrentUser, m_cbSendCardData, vCards, TRUE))
  384. {
  385. m_cbUserAction[m_wCurrentUser] |= WIK_CanDingMagic;
  386. }
  387. //杠牌判断
  388. tagGangCardResult GangCardResult;
  389. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  390. m_cbUserAction[m_wCurrentUser] |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[m_wCurrentUser], NULL, 0, GangCardResult);
  391. for (BYTE i = 0; i < GangCardResult.cbCardCount; i++)
  392. {
  393. ActionCard[i] = GangCardResult.cbCardData[i];
  394. }
  395. m_cbProvideCard = m_cbSendCardData;
  396. m_wResumeUser = m_wCurrentUser;
  397. //保存实际剩余的牌
  398. m_cbShiJiLeftCardCount = m_cbLeftCardCount;
  399. //牌位第十三顿 截止 倒数第十四牌打完 没人胡牌 流局
  400. //根据这个规则 删除26张牌 剩余的牌出完 没人胡牌 就是 流局
  401. m_cbLeftCardCount -= 26;//
  402. //构造数据
  403. CMD_S_GameStart GameStart;
  404. GameStart.wBankerUser = m_wBankerUser;
  405. GameStart.cbLeftCardCount = m_cbLeftCardCount;
  406. // [9/22/2017 Zoro] 翻财神和包麻将 不需要这个2个值,但发送时必须给0
  407. GameStart.cbSliceCheckBankUser[0] = 0;
  408. GameStart.cbSliceCheckBankUser[1] = 0;
  409. //////////////////////////////////////////////////////////////////////////
  410. WORD wSice = WORD(m_lSiceCount & 0xffff);
  411. GameStart.cbSiceLaiZi[0] = HIBYTE(wSice);//骰子
  412. GameStart.cbSiceLaiZi[1] = LOBYTE(wSice);//骰子
  413. GameStart.cbSiceLaiZi[2] = 0;//财神
  414. GameStart.cbSiceLaiZi[3] = 0;//财神
  415. if (m_bTwoPlayerFlag)
  416. {
  417. GameStart.cbTotalCardCount = MAX_REPERTORY_ZJ_Two; //麻将总数
  418. }
  419. else
  420. {
  421. GameStart.cbTotalCardCount = MAX_REPERTORY_ZJ; //麻将总数
  422. }
  423. GameStart.cbCurrPlay = m_gameConfig.wHadPlayCount;//当前局数
  424. GameStart.cbOptTime = GAME_TIMEOUT;//出牌超时时间
  425. ZeroMemory(GameStart.ActionCard, sizeof(GameStart.ActionCard));
  426. CopyMemory(GameStart.ActionCard, ActionCard, sizeof(ActionCard));
  427. TingCard(m_wCurrentUser);
  428. //打印时间
  429. //DWORD t2 = GetTickCount();
  430. //DWORD hh = t2 - timet;
  431. //CString csTemp;
  432. //csTemp.Format(L"时间:%d \r\n", hh);
  433. //OutputDebugString(csTemp);
  434. //发送数据
  435. SparrowMaJiang::PB_CS_S_GameStart GameStarts;
  436. GameStarts.set_wbankeruser(GameStart.wBankerUser);
  437. GameStarts.set_cbleftcardcount(GameStart.cbLeftCardCount);
  438. GameStarts.set_cbtotalcardcount(GameStart.cbTotalCardCount);
  439. GameStarts.set_cbopttime(GameStart.cbOptTime);
  440. GameStarts.set_cbcurrplay(GameStart.cbCurrPlay);
  441. for (WORD j = 0; j < 4; j++)
  442. {
  443. GameStarts.add_cbsicelaizi(GameStart.cbSiceLaiZi[j]);
  444. }
  445. for (WORD j = 0; j < 6; j++)
  446. {
  447. GameStarts.add_actioncard(GameStart.ActionCard[j]);
  448. }
  449. for (WORD j = 0; j < 2; j++)
  450. {
  451. GameStarts.add_cbslicecheckbankuser(GameStart.cbSliceCheckBankUser[j]);
  452. }
  453. //发送数据
  454. for (WORD i = 0; i < wChairCount; i++)
  455. {
  456. //设置变量
  457. GameStart.wCurrentUser = i;
  458. GameStart.cbUserAction = m_cbUserAction[i];
  459. //把庄家 刚刚放入手里的牌剪掉 然后统一 发送数据
  460. if (i == m_wCurrentUser)
  461. {
  462. if (m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)] > 0 && m_wCurrentUser == i)
  463. {
  464. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;//从手上去掉抓的牌
  465. }
  466. else
  467. {
  468. return false;
  469. }
  470. }
  471. ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData));
  472. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT*i]);
  473. if (i == m_wCurrentUser)
  474. {
  475. GameStart.cbCardData[i * 14 + 13] = m_cbSendCardData;//把去掉的牌加到数组末尾,
  476. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;//把去掉的加进来
  477. }
  478. GameStarts.set_wcurrentuser(GameStart.wCurrentUser);
  479. GameStarts.set_cbuseraction(GameStart.cbUserAction);
  480. for (WORD j = 0; j < MAX_COUNT * GAME_PLAYER; j++)
  481. {
  482. if (i == 0)
  483. {
  484. GameStarts.add_cbcarddata(GameStart.cbCardData[j]);
  485. }
  486. else
  487. {
  488. GameStarts.set_cbcarddata(j, GameStart.cbCardData[j]);
  489. }
  490. }
  491. //发送数据
  492. std::string pbdata = GameStarts.SerializePartialAsString();
  493. //发送数据
  494. m_pITableFrame->SendTableData(i, SUB_S_GAME_START, (void*)pbdata.c_str(), pbdata.length());
  495. }
  496. //用户回放
  497. ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData));
  498. for (WORD i = 0; i < MAX_COUNT * GAME_PLAYER; i++)
  499. {
  500. GameStarts.set_cbcarddata(i, GameStart.cbCardData[i]);
  501. }
  502. //清手牌 旁观只能发一次
  503. std::string pbdata = GameStarts.SerializePartialAsString();
  504. //发送数据
  505. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_START, (void*)pbdata.c_str(), pbdata.length());
  506. for (WORD i = 0; i < wChairCount; i++)
  507. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT*i]);
  508. for (WORD i = 0; i < MAX_COUNT * GAME_PLAYER; i++)
  509. {
  510. GameStarts.set_cbcarddata(i, GameStart.cbCardData[i]);
  511. }
  512. std::string pbrecord = GameStarts.SerializePartialAsString();
  513. RepayRecord(INVALID_CHAIR, SUB_S_GAME_START, (void*)pbrecord.c_str(), pbrecord.length());
  514. if (m_TabbOutCardCout[m_wCurrentUser] > 0)
  515. HttpTingCard(m_wCurrentUser);
  516. return true;
  517. return true;
  518. }
  519. void CTableFrameSink_dcs::DeletePrivateTable(bool bSendState)
  520. {
  521. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  522. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  523. WORD wChairCount = m_pITableFrame->GetChairCount();
  524. for (int i = 0; i < wChairCount; ++i)
  525. {
  526. IServerUserItem *pIUserItem = m_pITableFrame->GetTableUserItem(i);
  527. if (pIUserItem == NULL)
  528. continue;
  529. ScoreInfoArray[i].cbType = SCORE_TYPE_END;
  530. ScoreInfoArray[i].lScore = 0;// m_lUserTmpScore[i] - TEMP_MAX_SCORE; //记录临时分
  531. }
  532. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  533. ConcludeGame(GAME_STATUS_DELETE, bSendState);
  534. m_pITableFrame->DeletePrivateTableNow();
  535. }
  536. //游戏结束
  537. bool CTableFrameSink_dcs::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState)
  538. {
  539. bool bFinish = (m_gameConfig.wHadPlayCount >= m_gameConfig.wPlayCountRule) ? 1 : 0;
  540. switch (cbReason)
  541. {
  542. case GER_DELETE_PRIVATE:
  543. //bFinish = 1;
  544. //bDelete = true;
  545. //if (!m_pITableFrame->IsGameStarted())
  546. //{
  547. // DeletePrivateTable(bSendState);
  548. // return true;
  549. //}
  550. ConcludeGame(GS_MJ_FREE);
  551. DeletePrivateTable(bSendState);
  552. return true;
  553. //下坠
  554. case GER_NORMAL: //常规结束
  555. {
  556. //变量定义
  557. CMD_S_GameEnd GameEnd;
  558. ZeroMemory(&GameEnd, sizeof(GameEnd));
  559. GameEnd.bFinish = bFinish;//1……
  560. if (m_cbLeftCardCount <= 0 && bIsHuang)//荒庄了
  561. {
  562. {
  563. GameEnd.bOptType = 2;
  564. //黄装了
  565. if (m_gameConfig.wHadPlayCount > 1)
  566. {
  567. m_wNextBankerUser = m_wBankerUser;
  568. m_wNextBankerUser = m_wNextBankerUser | 0x0100;
  569. int userID;
  570. if (m_wBankerUser > 4)
  571. {
  572. userID = m_wBankerUser & 0x00ff;
  573. }
  574. else
  575. {
  576. userID = m_wBankerUser;
  577. }
  578. LianXuHuPai[userID]++;
  579. }
  580. else
  581. {
  582. /* m_wNextBankerUser = m_wBankerUser;
  583. m_wNextBankerUser = m_wNextBankerUser | 0x0100;*/
  584. LianXuHuPai[m_wBankerUser & 0x00ff]++;
  585. }
  586. //黄庄了
  587. //统计玩家积分,牌值
  588. for (WORD i = 0; i < mPlayGameUserCount; i++)
  589. {
  590. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  591. {
  592. continue;
  593. }
  594. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分4…………
  595. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  596. }
  597. }
  598. }
  599. else
  600. {
  601. GameEnd.bOptType = 1;
  602. GameEnd.HuPaiCard = m_cbProvideCard;
  603. GameEnd.wDianpao = m_wProvideUser;
  604. BYTE TempWanJiaCardCount = 0;
  605. m_wNextBankerUser = wChairID; //得到下一个坐庄的玩家
  606. if (LianXuHuPai[wChairID] > 1)
  607. m_wNextBankerUser = m_wNextBankerUser | 0x0100;
  608. //统计积分,胡牌得分,玩家牌值
  609. //保存本局所有用户的积分变动 除了胡牌玩家的
  610. for (WORD i = 0; i < mPlayGameUserCount; i++)
  611. {
  612. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  613. {
  614. continue;
  615. }
  616. //m_lGameTatolScore[i] += m_lGameScore[i];
  617. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3…………
  618. if (i == wChairID && m_wProvideUser == wChairID){
  619. continue;
  620. }
  621. if (m_wProvideUser != wChairID&&i == wChairID)
  622. {
  623. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]--;
  624. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  625. }
  626. else
  627. {
  628. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  629. }
  630. }
  631. //自摸
  632. if (m_wProvideUser == wChairID)
  633. {
  634. //先减去 胡的这张牌
  635. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]--;
  636. //把剩下的手牌保存到cbCardData
  637. m_GameLogic.SwitchToCardData(m_cbCardIndex[wChairID], GameEnd.cbCardData[wChairID]);
  638. //保存手牌数目
  639. TempWanJiaCardCount = m_GameLogic.GetCardCount(m_cbCardIndex[wChairID]);
  640. //最后一张牌 加上刚刚减去的牌
  641. GameEnd.cbCardData[wChairID][TempWanJiaCardCount] = m_cbProvideCard;//手牌数据4……
  642. //还原减去的牌
  643. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]++;
  644. }
  645. }
  646. GameEnd.bWanJiaId = wChairID;//玩家座位号 5……
  647. //保存实际桌子剩下多少能够抓的牌
  648. GameEnd.bLeftCardCount = m_cbShiJiLeftCardCount;//m_cbLeftCardCount + 26 + m_cbGangCount * 6;//剩余牌输量6…………
  649. CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, GameEnd.bLeftCardCount);//剩余牌值7………………
  650. //保存每个玩家的胡牌次数
  651. CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8…………
  652. //本次胡牌玩家的id
  653. GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9……//胡牌玩家id
  654. GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10…………
  655. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  656. {
  657. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  658. {
  659. continue;
  660. }
  661. //保存16局 胡牌积分流水
  662. m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * 4 + i] = m_lGameScore[i];
  663. }
  664. CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10…………
  665. for (int i = 0; i < m_gameConfig.wHadPlayCount; i++)
  666. {
  667. /*CString strTmp;
  668. strTmp.Format(_T("胡牌流水->第%d局 %d,%d,%d,%d"), i,m_HuPaiLiuShui[i*4 + 0], m_HuPaiLiuShui[i*4 + 1], m_HuPaiLiuShui[i*4 + 2] , m_HuPaiLiuShui[i*4 + 3]);*/
  669. //OutputDebugString(strTmp);
  670. }
  671. SparrowMaJiang::PB_CS_S_GameEnd pGameEnd;
  672. pGameEnd.set_bopttype(GameEnd.bOptType);
  673. pGameEnd.set_bwanjiaid(GameEnd.bWanJiaId);
  674. pGameEnd.set_wdianpao(GameEnd.wDianpao);
  675. pGameEnd.set_hupaicard(GameEnd.HuPaiCard);
  676. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  677. {
  678. pGameEnd.add_cbwanjiascore(GameEnd.cbWanJiaScore[i]);
  679. pGameEnd.add_bzimo(GameEnd.bZimo[i]);
  680. }
  681. pGameEnd.set_bfinish(GameEnd.bFinish);
  682. pGameEnd.set_dwownerid(GameEnd.dwOwnerID);
  683. pGameEnd.set_bleftcardcount(GameEnd.bLeftCardCount);
  684. for (BYTE i = 0; i < GameEnd.bLeftCardCount; i++)
  685. {
  686. pGameEnd.add_bleftcarddada(GameEnd.bLeftCardDada[i]);
  687. }
  688. pGameEnd.set_playgamenum(GameEnd.playGameNum);
  689. for (BYTE i = 0; i < mPlayGameUserCount * 16; i++)
  690. {
  691. pGameEnd.add_lgamescoredetail(GameEnd.lGameScoreDetail[i]);
  692. }
  693. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  694. {
  695. SparrowMaJiang::pb_cbCardData* CardData = pGameEnd.add_cbcarddata();
  696. for (BYTE j = 0; j < 14; j++)
  697. {
  698. CardData->add_cbcarddatas(GameEnd.cbCardData[i][j]);
  699. }
  700. }
  701. std::string pbdata = pGameEnd.SerializePartialAsString();
  702. RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  703. //发送结束信息
  704. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  705. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  706. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  707. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  708. for (WORD i = 0; i < mPlayGameUserCount; i++)
  709. {
  710. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  711. {
  712. continue;
  713. }
  714. IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i);
  715. if (NULL == pUserItem) continue;
  716. BYTE ScoreKind;
  717. if (m_lGameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN;
  718. else if (m_lGameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE;
  719. else ScoreKind = SCORE_TYPE_DRAW;
  720. ScoreInfoArray[i].lScore = m_lGameScore[i];
  721. ScoreInfoArray[i].cbType = ScoreKind;
  722. //if (i == wChairID)continue;
  723. //m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  724. }
  725. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  726. ConcludeGame(GS_MJ_FREE);
  727. if (bFinish)
  728. {
  729. DeletePrivateTable(true);
  730. }
  731. return true;
  732. }
  733. case GER_DISMISS: //游戏解散
  734. {
  735. //变量定义
  736. CMD_S_GameEnd GameEnd;
  737. ZeroMemory(&GameEnd, sizeof(GameEnd));
  738. GameEnd.bFinish = 1;
  739. GameEnd.bOptType = 3;
  740. GameEnd.bWanJiaId = wChairID;//玩家座位号 5……
  741. //保存实际桌子剩下多少能够抓的牌
  742. GameEnd.bLeftCardCount = m_cbShiJiLeftCardCount;//m_cbLeftCardCount + 26 + m_cbGangCount * 6;//剩余牌输量6…………
  743. CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, GameEnd.bLeftCardCount);//剩余牌值7………………
  744. //保存每个玩家的胡牌次数
  745. CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8…………
  746. //本次胡牌玩家的id
  747. GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9……//胡牌玩家id
  748. GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10…………
  749. for (BYTE i = 0; i < GAME_PLAYER; i++)
  750. {
  751. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  752. m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * 4 + i] = m_lGameScore[i];
  753. }
  754. CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10…………
  755. //统计积分,胡牌得分,玩家牌值
  756. //保存本局所有用户的积分变动 除了胡牌玩家的
  757. for (WORD i = 0; i < mPlayGameUserCount; i++)
  758. {
  759. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  760. {
  761. continue;
  762. }
  763. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3…………
  764. }
  765. SparrowMaJiang::PB_CS_S_GameEnd pGameEnd;
  766. pGameEnd.set_bopttype(GameEnd.bOptType);
  767. pGameEnd.set_bwanjiaid(GameEnd.bWanJiaId);
  768. pGameEnd.set_wdianpao(GameEnd.wDianpao);
  769. pGameEnd.set_hupaicard(GameEnd.HuPaiCard);
  770. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  771. {
  772. pGameEnd.add_cbwanjiascore(GameEnd.cbWanJiaScore[i]);
  773. pGameEnd.add_bzimo(GameEnd.bZimo[i]);
  774. }
  775. pGameEnd.set_bfinish(GameEnd.bFinish);
  776. pGameEnd.set_dwownerid(GameEnd.dwOwnerID);
  777. pGameEnd.set_bleftcardcount(GameEnd.bLeftCardCount);
  778. for (BYTE i = 0; i < GameEnd.bLeftCardCount; i++)
  779. {
  780. pGameEnd.add_bleftcarddada(GameEnd.bLeftCardDada[i]);
  781. }
  782. pGameEnd.set_playgamenum(GameEnd.playGameNum);
  783. for (BYTE i = 0; i < mPlayGameUserCount * 16; i++)
  784. {
  785. pGameEnd.add_lgamescoredetail(GameEnd.lGameScoreDetail[i]);
  786. }
  787. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  788. {
  789. SparrowMaJiang::pb_cbCardData* CardData = pGameEnd.add_cbcarddata();
  790. for (BYTE j = 0; j < 14; j++)
  791. {
  792. CardData->add_cbcarddatas(GameEnd.cbCardData[i][j]);
  793. }
  794. }
  795. std::string pbdata = pGameEnd.SerializePartialAsString();
  796. RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  797. //发送结束信息
  798. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  799. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  800. if (m_pITableFrame->GetGameStatus() == GS_MJ_FREE)
  801. {
  802. DeletePrivateTable(true);
  803. return true;
  804. }
  805. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  806. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  807. for (WORD i = 0; i < mPlayGameUserCount; i++)
  808. {
  809. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  810. {
  811. continue;
  812. }
  813. IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i);
  814. if (NULL == pUserItem) continue;
  815. BYTE ScoreKind;
  816. if (m_lGameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN;
  817. else if (m_lGameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE;
  818. else ScoreKind = SCORE_TYPE_DRAW;
  819. ScoreInfoArray[i].lScore = m_lGameScore[i];
  820. ScoreInfoArray[i].cbType = ScoreKind;
  821. //if (i == wChairID)continue;
  822. //m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  823. }
  824. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  825. ConcludeGame(GS_MJ_FREE);
  826. DeletePrivateTable(bSendState);
  827. return true;
  828. }
  829. case GER_NETWORK_ERROR: //网络错误
  830. case GER_USER_LEAVE: //用户强退
  831. {
  832. if (pIServerUserItem!=NULL)
  833. {
  834. DWORD dwUserID = pIServerUserItem->GetUserID();
  835. m_offlineUsers.push_back(dwUserID);
  836. }
  837. return true;
  838. }
  839. }
  840. //错误断言
  841. ASSERT(FALSE);
  842. return false;
  843. }
  844. //发送场景duanxian用户断线重连
  845. bool CTableFrameSink_dcs::OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret)
  846. {
  847. try
  848. {
  849. switch (cbGameStatus)
  850. {
  851. case GS_MJ_FREE: //空闲状态
  852. {
  853. //变量定义
  854. CMD_S_StatusFree StatusFree;
  855. memset(&StatusFree, 0, sizeof(StatusFree));
  856. //游戏房主基础配置
  857. CopyMemory(&StatusFree.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  858. for (int i = 0; i < mPlayGameUserCount; i++)
  859. {
  860. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  861. {
  862. continue;
  863. }
  864. StatusFree.lUserTmpScore[i] = (INT)m_lGameTatolScore[i];
  865. }
  866. StatusFree.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  867. //构造数据
  868. StatusFree.UserStat = pIServerUserItem->GetUserInfo()->cbUserStatus;
  869. //发送场景
  870. return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusFree, sizeof(StatusFree));
  871. }
  872. case GS_MJ_PLAY: //游戏状态
  873. {
  874. //变量定义
  875. CMD_S_StatusPlay StatusPlay;
  876. memset(&StatusPlay, 0, sizeof(StatusPlay));
  877. //游戏房主基础配置
  878. CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  879. CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore));
  880. StatusPlay.cbTotalCardCount = m_cbTotalCardCount;
  881. // if (mBCanShowLeft==TRUE)
  882. // {
  883. StatusPlay.cbLeftCardCount = m_cbLeftCardCount;
  884. // }
  885. // else
  886. // {
  887. // StatusPlay.cbLeftCardCount = mTempLeftCount;
  888. // }
  889. StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  890. //游戏变量
  891. StatusPlay.wBankerUser = m_wBankerUser;
  892. WORD wSice = WORD(m_lSiceCount & 0xffff);
  893. StatusPlay.lSiZi[0] = HIBYTE(wSice);
  894. StatusPlay.lSiZi[1] = LOBYTE(wSice);
  895. StatusPlay.lSiZi[2] = 0;
  896. StatusPlay.lSiZi[3] = 0;
  897. StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();
  898. CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard));
  899. CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount));
  900. StatusPlay.totalOptTime = 10;
  901. StatusPlay.leftOptTime = 0;
  902. //组合扑克
  903. CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray));
  904. CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  905. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  906. {
  907. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  908. {
  909. continue;
  910. }
  911. //StatusPlay.bWanLaiZi[i] = m_OutLaiZi[i];
  912. //StatusPlay.bWanLaiZi[i] |= (m_OutHongZhongGang[i] << 4);
  913. //StatusPlay.bWanLaiZi[i] |= (m_OutFaCaiGang[i] << 8);
  914. StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]);
  915. }
  916. m_GameLogic.SwitchToCardData(m_cbCardIndex[wChiarID], StatusPlay.cbCardData);//手牌数据
  917. StatusPlay.cbActionMask = m_cbUserAction[wChiarID]; //需要用到操作码
  918. if (m_cbUserAction[wChiarID] & (WIK_AN_GANG | WIK_BU_GANG | WIK_DAN_BU_GANG | WIK_DAN_AN_GANG | WIK_SHUANG_AN_GANG | WIK_SAN_AN_GANG | WIK_QUANG_AN_GANG))
  919. {
  920. tagGangCardResult GangCardResult;
  921. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  922. m_GameLogic.AnalyseGangCard(m_cbCardIndex[wChiarID], m_WeaveItemArray[wChiarID], m_cbWeaveItemCount[wChiarID], GangCardResult);
  923. for (BYTE i = 0; i < GangCardResult.cbCardCount; i++)
  924. {
  925. StatusPlay.gangCards[i] = GangCardResult.cbCardData[i];
  926. }
  927. }
  928. ASSERT(m_wProvideUser >= 0 && m_wProvideUser <= 3);
  929. //当前到谁家
  930. StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser);
  931. BYTE OldUser = 0;//定义一个最后出牌用户
  932. if ((m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR) || (m_wProvideUser == m_wCurrentUser&&m_wResumeUser == m_wCurrentUser && m_cbProvideCard == 0))//牌权是摸牌得且没出牌
  933. {
  934. if (m_bTwoPlayerFlag)
  935. {
  936. OldUser = (m_wProvideUser - 2 + GAME_PLAYER) % GAME_PLAYER;
  937. }
  938. else
  939. {
  940. OldUser = (m_wProvideUser - 1 + mPlayGameUserCount) % mPlayGameUserCount;
  941. }
  942. BYTE TempIndex = 0;
  943. BYTE bDiscardCount = (m_cbDiscardCount[OldUser] - 1) >= 0 ? (m_cbDiscardCount[OldUser] - 1) : 0;
  944. for (BYTE i = bDiscardCount; i < 40; i++)
  945. {
  946. if (m_cbDiscardCard[OldUser][i] == 0)
  947. {
  948. TempIndex = i - 1;
  949. break;
  950. }
  951. }
  952. TempIndex = (TempIndex == 255) ? 0 : TempIndex;
  953. StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex];
  954. StatusPlay.bPutCardData[wChiarID] = 255;
  955. //}
  956. }
  957. if (m_wProvideUser == m_wOutCardUser && m_wCurrentUser == INVALID_CHAIR)//当有人可以碰且没有碰时候
  958. {
  959. StatusPlay.bPutCardData[m_wProvideUser] = m_cbProvideCard;
  960. StatusPlay.cbDiscardCard[m_wProvideUser][StatusPlay.cbDiscardCount[m_wProvideUser]++] = m_cbProvideCard;
  961. }
  962. if (wChiarID == StatusPlay.wCurrentUser&&m_wCurrentUser != INVALID_CHAIR&&m_wCurrentUser != m_wProvideUser)//表示当前牌权就在断线玩家手里,且是轮到他出牌(牌权碰来得)
  963. {
  964. ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData));
  965. BYTE TempCardData[MAX_INDEX];
  966. CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData));
  967. BYTE TempEndCardData = m_GameLogic.GetEndCard(TempCardData);
  968. BYTE TempCardIndex = m_GameLogic.SwitchToCardIndex(TempEndCardData);
  969. if (TempCardData[TempCardIndex] == 0){ ASSERT(false); return false; }
  970. TempCardData[TempCardIndex]--;
  971. BYTE cardNum = m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData);
  972. StatusPlay.cbCardData[cardNum] = TempEndCardData;
  973. }
  974. if (wChiarID == StatusPlay.wCurrentUser && m_wCurrentUser != INVALID_CHAIR && m_wCurrentUser == m_wProvideUser)//牌权是轮到他抓牌,未打出
  975. {
  976. ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData));
  977. BYTE TempCardData[MAX_INDEX];
  978. CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData));
  979. BYTE TempCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard);
  980. if (m_cbCardIndex[wChiarID][TempCardIndex] == 0)ASSERT(false);
  981. TempCardData[TempCardIndex]--;
  982. BYTE cardNum = m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData);
  983. StatusPlay.cbCardData[cardNum] = m_GameLogic.SwitchToCardData(TempCardIndex);//处理得到最后一张牌数据放最后
  984. StatusPlay.bPutCardData[wChiarID] = 255;
  985. }
  986. if (wChiarID != m_wProvideUser&&m_cbUserAction[wChiarID] & WIK_Qiang_GANG)
  987. {
  988. StatusPlay.bPutCardData[wChiarID] = 255;
  989. StatusPlay.bPutCardData[m_wProvideUser] = m_cbProvideCard;
  990. }
  991. //发送场景
  992. return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusPlay, sizeof(StatusPlay));
  993. }
  994. }
  995. return false;
  996. }
  997. catch (...)
  998. {
  999. OutputDebugString(_T("CTableFrameSink::OnEventSendGameScene... 触发异常\r\n"));
  1000. return false;
  1001. }
  1002. }
  1003. //定时器事件
  1004. bool CTableFrameSink_dcs::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam)
  1005. {
  1006. return false;
  1007. }
  1008. //游戏消息处理
  1009. void CTableFrameSink_dcs::SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId)
  1010. {
  1011. tagGameConfig* ppConfig = (tagGameConfig*)pDataBuffer;
  1012. m_gameConfig.wSubGameID = ppConfig->wSubGameID;
  1013. m_gameConfig.wDiScore = ppConfig->wPlayRule;
  1014. m_gameConfig.wFanFei = ppConfig->wMaxFanRule;
  1015. m_gameConfig.wIpLimit = ppConfig->wMaxScore;
  1016. m_gameConfig.wPlayCountRule = ppConfig->wPlayCountRule;
  1017. m_gameConfig.RoomId = ppConfig->wHadPlayCount;
  1018. m_gameConfig.wHadPlayCount = 0;
  1019. m_gameConfig.bDuoLai = 1;
  1020. m_gameConfig.wFengDing = ppConfig->wFengDing;
  1021. m_gameConfig.tmp1 = ppConfig->tmp1;
  1022. if (m_gameConfig.wFengDing == 0 || m_gameConfig.wFengDing == 5)
  1023. {
  1024. mMaxTaiNum = 5;
  1025. }
  1026. else if (m_gameConfig.wFengDing == 6 || m_gameConfig.wFengDing == 7)
  1027. {
  1028. mMaxTaiNum = m_gameConfig.wFengDing;
  1029. }
  1030. else
  1031. {
  1032. mMaxTaiNum = 20;
  1033. }
  1034. lstrcpy(m_gameConfig.sPrivateTableID, sPrivateRoomId.c_str());
  1035. //bGameType = m_gameConfig.wSubGameID;
  1036. //bGameZuiDiFen = m_gameConfig.wDiScore*(bGameType == HongZhong ? 10 : 16);
  1037. m_cbTotalCardCount = MAX_REPERTORY_ZJ;
  1038. //协议修改,值变成 4 3 2
  1039. if (m_gameConfig.tmp1 == 0)
  1040. {
  1041. mPlayGameUserCount = 4;
  1042. }
  1043. else
  1044. {
  1045. if (m_gameConfig.tmp1 == 2)
  1046. {
  1047. m_bTwoPlayerFlag = TRUE;
  1048. mPlayGameUserCount = 3;
  1049. m_cbTotalCardCount = MAX_REPERTORY_ZJ_Two;
  1050. m_pITableFrame->SetStartMode(START_MODE_ALL_READY);
  1051. }
  1052. else
  1053. {
  1054. mPlayGameUserCount = m_gameConfig.tmp1;
  1055. }
  1056. }
  1057. m_pITableFrame->SetChairCount(mPlayGameUserCount);
  1058. ASSERT(m_gameConfig.wSubGameID >= 0 && m_gameConfig.wSubGameID < MahJongType::count);
  1059. if (!sPrivateRoomId.empty())
  1060. {
  1061. mGameTableId = _wtoi(sPrivateRoomId.c_str());
  1062. }
  1063. else
  1064. {
  1065. mGameTableId = 1;
  1066. }
  1067. }
  1068. int SignedRemoveRep(BYTE array[], int n)
  1069. {
  1070. int i, left = 0;
  1071. for (i = 0; i < n; i++)//将出现过的位置置负号标志
  1072. {
  1073. if (array[i] > 0) //可以直接做下标
  1074. {
  1075. array[array[i]] = -array[array[i]];
  1076. }
  1077. else
  1078. {
  1079. if (array[-array[i]] > 0) //为正时才是第一次置标志
  1080. array[-array[i]] = -array[-array[i]];
  1081. }
  1082. }
  1083. for (i = 0; i < n; i++)//抽取算法
  1084. {
  1085. if (array[i] < 0) //根据标志顺序保存出现过的值
  1086. array[left++] = i;
  1087. }
  1088. return left;
  1089. }
  1090. //游戏消息处理
  1091. bool CTableFrameSink_dcs::OnGameMessage(WORD wSubCmdID, VOID* pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
  1092. {
  1093. switch (wSubCmdID)
  1094. {
  1095. case SUB_C_OUT_CARD: //出牌消息
  1096. {
  1097. //定义变量
  1098. SparrowMaJiang::PB_CS_C_OutCard OutCard;
  1099. OutCard.ParseFromArray(pDataBuffer, wDataSize);
  1100. //用户效验
  1101. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1102. return OnUserOutCard(pIServerUserItem->GetChairID(), OutCard.cbcarddata());
  1103. // bool bRet= OnUserOutCard(pIServerUserItem->GetChairID(), pOutCard->cbCardData);
  1104. // QueryPerformanceCounter(&nEndTime);
  1105. // double dwTime;
  1106. // dwTime = ((nEndTime.QuadPart - nBeginTime.QuadPart) / nFreq.QuadPart) * 1000;
  1107. // if (dwTime > 100){
  1108. // CString str;
  1109. // str = _T("Zoro 翻财神/包麻将 OnUserOutCard 耗费时间 %d 秒 出牌=%d\r\n牌:", dwTime,pOutCard->cbCardData);
  1110. // for (size_t i = 0; i < MAX_INDEX; i++)
  1111. // {
  1112. // CString tmp;
  1113. // tmp.Format(_T("%d"), m_cbCardIndex[pIServerUserItem->GetChairID()][i]);
  1114. // str += tmp;
  1115. // }
  1116. // OutputDebugString(str);
  1117. //
  1118. // }
  1119. // return bRet;
  1120. }
  1121. case SUB_C_OPERATE_CARD: //操作消息
  1122. {
  1123. SparrowMaJiang::PB_CS_C_OperateCard OperateCard;
  1124. OperateCard.ParseFromArray(pDataBuffer, wDataSize);
  1125. //用户效验
  1126. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1127. CMD_C_OperateCard pOperateCard;
  1128. for (WORD i = 0; i < 4; i++)
  1129. {
  1130. pOperateCard.cbCaiShenCard[i] = OperateCard.cbcaishencard(i);
  1131. }
  1132. pOperateCard.cbOperateCard = OperateCard.cboperatecard();
  1133. pOperateCard.cbOperateCode = OperateCard.cboperatecode();
  1134. return OnUserOperateCard(pIServerUserItem->GetChairID(), pOperateCard.cbOperateCode, pOperateCard.cbOperateCard, pOperateCard.cbCaiShenCard);
  1135. }
  1136. case SUB_C_TRUSTEE: //托管
  1137. {
  1138. SparrowMaJiang::PB_CS_C_Trustee pTrustee;
  1139. pTrustee.ParseFromArray(pDataBuffer, wDataSize);
  1140. m_bTrustee[pIServerUserItem->GetChairID()] = pTrustee.btrustee();
  1141. CMD_S_Trustee Trustee;
  1142. Trustee.bTrustee = pTrustee.btrustee();
  1143. Trustee.wChairID = pIServerUserItem->GetChairID();
  1144. SparrowMaJiang::PB_CS_S_Trustee Trustees;
  1145. Trustees.set_btrustee(Trustee.bTrustee);
  1146. Trustees.set_wchairid(Trustee.wChairID);
  1147. std::string pbdata = Trustees.SerializePartialAsString();
  1148. RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1149. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1150. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1151. return true;
  1152. }
  1153. // case SUB_C_SELECT_BAO:{
  1154. // CMD_C_BAO *pBaoTai = (CMD_C_BAO *)pDataBuffer;
  1155. // SelectBaoTaiNum(pIServerUserItem->GetChairID(), pBaoTai->cbTaiNum);
  1156. // return true;
  1157. // }
  1158. // case SUB_C_SELECT_CAI:{
  1159. // CMD_C_Magic *pMagic = (CMD_C_Magic*)pDataBuffer;
  1160. // SelectBaoMagic(pIServerUserItem->GetChairID(), pMagic->cbMagicFirst, pMagic->cbMagicSenced);
  1161. // return true;
  1162. // }
  1163. case SUB_C_DING_CAI:{
  1164. //OutputDebugString(_T("丁财神开始"));
  1165. SparrowMaJiang::PB_CS_C_MagicDing pDingCaiBuffer;
  1166. pDingCaiBuffer.ParseFromArray(pDataBuffer, wDataSize);
  1167. //用户效验
  1168. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1169. if (pDingCaiBuffer.isdingcai())
  1170. {
  1171. //UserDingMagicCard(pIServerUserItem->GetChairID());
  1172. BYTE TempCardIndex[MAX_INDEX] = { 0 };
  1173. CopyMemory(TempCardIndex, m_cbCardIndex[pIServerUserItem->GetChairID()], MAX_INDEX);
  1174. TempCardIndex[m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;
  1175. std::vector<CanDcsSt> vCards;
  1176. GetMagicCardAndTaiNum(TempCardIndex, pIServerUserItem->GetChairID(), m_cbSendCardData, vCards);
  1177. CMD_S_DING_CAI_RESULT DcResult;
  1178. ZeroMemory(&DcResult, sizeof(CMD_S_DING_CAI_RESULT));
  1179. if (vCards.size() > 0)
  1180. {
  1181. DcResult.cbResult = 1;
  1182. BYTE TempRecordIndex[MAX_INDEX] = { 0 };
  1183. int caiCardsCount = 0;
  1184. BYTE tmpCardMagicLeftAndRight[MAX_COUNT] = { 0 };
  1185. INT tmpCardMagicLeftAndRightCount = 0;
  1186. //////////////////////////////////////////////////////////////////////////
  1187. // 先获取所有可以作为两边的牌
  1188. //////////////////////////////////////////////////////////////////////////
  1189. for (int i = 0; i < vCards.size();i++)
  1190. {
  1191. if (vCards[i].bDuCanHu)
  1192. {
  1193. // CString strOut;
  1194. // strOut.Format(_T("定财神 独财 =%02x 台=%d\r\n"), vCards[i].MagicCard, vCards[i].nTai);
  1195. // OutputDebugString(strOut);
  1196. continue;
  1197. }
  1198. // CString strOut;
  1199. // strOut.Format(_T("定财神 财 =%02x %02x 台=%d\r\n"), vCards[i].MagicCard, vCards[i].MagicCardNext, vCards[i].nTai);
  1200. // OutputDebugString(strOut);
  1201. if (GetCardCanHuWithAll(vCards[i].MagicCard, vCards) && !CardInAll(vCards[i].MagicCard, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  1202. {
  1203. DcResult.caiCards[caiCardsCount] = vCards[i].MagicCard;
  1204. DcResult.caiCards[caiCardsCount] |= DingLeftAndRightGao2;
  1205. caiCardsCount++;
  1206. tmpCardMagicLeftAndRight[tmpCardMagicLeftAndRightCount++] = vCards[i].MagicCard;
  1207. }
  1208. if (vCards[i].MagicCardNext != 0)
  1209. {
  1210. if (GetCardCanHuWithAll(vCards[i].MagicCardNext, vCards) && !CardInAll(vCards[i].MagicCardNext, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  1211. {
  1212. DcResult.caiCards[caiCardsCount] = vCards[i].MagicCardNext;
  1213. DcResult.caiCards[caiCardsCount] |= DingLeftAndRightGao2;
  1214. caiCardsCount++;
  1215. tmpCardMagicLeftAndRight[tmpCardMagicLeftAndRightCount++] = vCards[i].MagicCardNext;
  1216. }
  1217. }
  1218. }
  1219. for (int i = 0; i < vCards.size(); i++)
  1220. {
  1221. if (vCards[i].bDuCanHu)
  1222. {
  1223. //CString strOut;
  1224. //strOut.Format(_T("定财神 独财 =%02x 台=%d\r\n"), vCards[i].MagicCard, vCards[i].nTai);
  1225. //OutputDebugString(strOut);
  1226. DcResult.caiCards[caiCardsCount] = vCards[i].MagicCard;
  1227. DcResult.caiCards[caiCardsCount] |= DingDuGao2;
  1228. caiCardsCount++;
  1229. continue;
  1230. }
  1231. else
  1232. {
  1233. //CString strOut;
  1234. //strOut.Format(_T("定财神 财 =%02x %02x 台=%d\r\n"), vCards[i].MagicCard, vCards[i].MagicCardNext, vCards[i].nTai);
  1235. //OutputDebugString(strOut);
  1236. {
  1237. if (!CardInAll(vCards[i].MagicCard, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  1238. {
  1239. DcResult.caiCards[caiCardsCount] = vCards[i].MagicCard;
  1240. DcResult.caiCards[caiCardsCount] |= DingRightGao2;
  1241. caiCardsCount++;
  1242. }
  1243. if (!CardInAll(vCards[i].MagicCardNext, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  1244. {
  1245. DcResult.caiCards[caiCardsCount] = vCards[i].MagicCardNext;
  1246. DcResult.caiCards[caiCardsCount] |= DingLeftGao2;
  1247. caiCardsCount++;
  1248. }
  1249. // else
  1250. // {
  1251. // DcResult.caiCards[caiCardsCount] |= DingDuGao2;
  1252. // caiCardsCount++;
  1253. //
  1254. // }
  1255. }
  1256. }
  1257. }
  1258. // int caiCardsCount = 0;
  1259. // for (int i = 0; i < MAX_INDEX; i++)
  1260. // {
  1261. // if (TempRecordIndex[i] == 0)
  1262. // {
  1263. // continue;
  1264. // }
  1265. // if (TempRecordIndex[i] >= MAX_COUNT)
  1266. // {
  1267. // DcResult.caiCards[caiCardsCount] = m_GameLogic.SwitchToCardData(i);
  1268. // DcResult.caiCards[caiCardsCount] |= 0x80;
  1269. // caiCardsCount++;
  1270. // }
  1271. // else
  1272. // {
  1273. // DcResult.caiCards[caiCardsCount] = m_GameLogic.SwitchToCardData(i);
  1274. // caiCardsCount++;
  1275. // }
  1276. // }
  1277. // CString strOut;
  1278. // for (size_t i = 0; i < caiCardsCount; i++)
  1279. // {
  1280. // CString strCards;
  1281. // strCards.Format(_T("%02x \t"), DcResult.caiCards[i]);
  1282. // strOut += strCards;
  1283. // }
  1284. // OutputDebugString(strOut);
  1285. }
  1286. else
  1287. {
  1288. //OutputDebugString(_T("定财神无"));
  1289. DcResult.cbResult = 2;
  1290. }
  1291. DcResult.cbIsWCHu = false;
  1292. {
  1293. CGameLogic_dcs TempGameLogic(this);
  1294. TempGameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  1295. BYTE TaiShu = 0;
  1296. if (TempGameLogic.AnalyseCardNew(m_cbCardIndex[pIServerUserItem->GetChairID()], m_WeaveItemArray[pIServerUserItem->GetChairID()], m_cbWeaveItemCount[pIServerUserItem->GetChairID()]))
  1297. {
  1298. TempGameLogic.mSunTaiJiangInColor = TempGameLogic.mJiangInColor;
  1299. TaiShu = TempGameLogic.AnalyseCardTaiNum(m_cbCardIndex[pIServerUserItem->GetChairID()], m_WeaveItemArray[pIServerUserItem->GetChairID()], m_cbWeaveItemCount[pIServerUserItem->GetChairID()]);
  1300. if (m_bQiangGang)
  1301. {
  1302. TaiShu++;
  1303. }
  1304. if (m_bUsersGangStatus[pIServerUserItem->GetChairID()] == TRUE)
  1305. {
  1306. TaiShu++;
  1307. }
  1308. if (TempGameLogic.AnalyseCardTaiNum_IsQuanZi(m_cbCardIndex[pIServerUserItem->GetChairID()], m_WeaveItemArray[pIServerUserItem->GetChairID()], m_cbWeaveItemCount[pIServerUserItem->GetChairID()]))
  1309. {
  1310. TaiShu = 7;
  1311. }
  1312. }
  1313. if (TaiShu >= DingMagicMinTai)
  1314. {
  1315. DcResult.cbIsWCHu = TRUE;
  1316. // OutputDebugString(_T("无财胡"));
  1317. }
  1318. }
  1319. SparrowMaJiang::PB_CS_S_DING_CAI_RESULT pDcResult;
  1320. pDcResult.set_cbiswchu(DcResult.cbIsWCHu);
  1321. pDcResult.set_cbresult(DcResult.cbResult);
  1322. for (BYTE j = 0; j < MAX_INDEX; j++)
  1323. {
  1324. pDcResult.add_caicards(DcResult.caiCards[j]);
  1325. }
  1326. std::string pbdate = pDcResult.SerializePartialAsString();
  1327. RepayRecord(pIServerUserItem->GetChairID(), SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  1328. //发送消息
  1329. m_pITableFrame->SendTableData(pIServerUserItem->GetChairID(), SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  1330. }
  1331. else
  1332. {
  1333. CMD_S_DING_CAI_RESULT DcResult;
  1334. DcResult.cbResult = 0;
  1335. ZeroMemory(DcResult.caiCards, MAX_COUNT);
  1336. //发送消息
  1337. SparrowMaJiang::PB_CS_S_DING_CAI_RESULT pDcResult;
  1338. pDcResult.set_cbiswchu(DcResult.cbIsWCHu);
  1339. pDcResult.set_cbresult(DcResult.cbResult);
  1340. for (BYTE j = 0; j < MAX_INDEX; j++)
  1341. {
  1342. pDcResult.add_caicards(DcResult.caiCards[j]);
  1343. }
  1344. std::string pbdate = pDcResult.SerializePartialAsString();
  1345. RepayRecord(pIServerUserItem->GetChairID(), SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  1346. m_pITableFrame->SendTableData(pIServerUserItem->GetChairID(), SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  1347. if (m_wCurrentUser == INVALID_CHAIR)
  1348. {
  1349. //设置变量
  1350. m_bResponse[pIServerUserItem->GetChairID()] = true;
  1351. m_cbPerformAction[pIServerUserItem->GetChairID()] = WIK_NULL;
  1352. //m_cbOperateCard[wChairID] = cbOperateCard;
  1353. /*CopyMemory(m_cbOperateCaiCard[wChairID], cbCaiShenCard, sizeof(cbCaiShenCard));*/
  1354. //执行动作的优先级判断, WIK_CHI_HU 大于 WIK_PENG 大于 [WIK_RIGHT or WIK_CENTER or WIK_LEFT]
  1355. WORD TempUser = m_wProvideUser;
  1356. WORD wTargetUser = pIServerUserItem->GetChairID();
  1357. int cbTargetAction = WIK_NULL;
  1358. OperatorPriority(TempUser, wTargetUser, cbTargetAction);
  1359. if (m_bResponse[wTargetUser] == false)//操作判断
  1360. {
  1361. m_cbLastDisCardData[pIServerUserItem->GetChairID()][m_cbLastDisCount[pIServerUserItem->GetChairID()]++] = m_cbProvideCard;
  1362. return true;
  1363. }
  1364. if ( cbTargetAction&WIK_Qiang_GANG)//此动作为抢杠胡才会促发
  1365. {
  1366. BYTE cbTargetCaiCard[4] = { 0 };
  1367. CopyMemory(cbTargetCaiCard, m_cbOperateCaiCard[wTargetUser], sizeof(cbTargetCaiCard));
  1368. m_bQiangGang = true;
  1369. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  1370. m_wCurrentUser = wTargetUser;
  1371. //m_wProvideUser = wTargetUser;
  1372. m_cbSendCardData = m_cbProvideCard;
  1373. m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1374. m_cbUserAction[wTargetUser] = WIK_Qiang_GANG;
  1375. OnUserOperateCard(wTargetUser, WIK_Qiang_GANG, m_cbProvideCard, cbTargetCaiCard);
  1376. return true;
  1377. }
  1378. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1379. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1380. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1381. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1382. if (m_bQiangGang)
  1383. {
  1384. DispatchCardData(m_wResumeUser,true);
  1385. m_bQiangGang = false;
  1386. }
  1387. else
  1388. {
  1389. DispatchCardData(m_wResumeUser);
  1390. }
  1391. }
  1392. }
  1393. // OutputDebugString(_T("丁财神结束"));
  1394. return true;
  1395. }
  1396. default:
  1397. return false;
  1398. }
  1399. return false;
  1400. }
  1401. BOOL CTableFrameSink_dcs::GetCardCanHuWithAll(BYTE cbCard, std::vector<CanDcsSt> &vCards)
  1402. {
  1403. BOOL FindCount = 0;
  1404. for (int i = 0; i < vCards.size();i++)
  1405. {
  1406. if (vCards[i].bDuCanHu)
  1407. {
  1408. continue;
  1409. }
  1410. if (vCards[i].MagicCard==cbCard||vCards[i].MagicCardNext==cbCard)
  1411. {
  1412. FindCount++;
  1413. }
  1414. if (FindCount>=2)
  1415. {
  1416. break;
  1417. }
  1418. }
  1419. return FindCount >= 2;
  1420. }
  1421. BOOL CTableFrameSink_dcs::CardInAll(BYTE CbCard, BYTE *pByte, int Count)
  1422. {
  1423. if (pByte==NULL||Count<=0)
  1424. {
  1425. return FALSE;
  1426. }
  1427. for (int i = 0; i < Count;i++)
  1428. {
  1429. if (CbCard==pByte[i])
  1430. {
  1431. return TRUE;
  1432. }
  1433. }
  1434. return FALSE;
  1435. }
  1436. void CTableFrameSink_dcs::CalculationMagicCards(BYTE CurrentUserIndex)
  1437. {
  1438. EnumAllWeave(CurrentUserIndex);
  1439. }
  1440. void CTableFrameSink_dcs::EnumAllWeave(BYTE CurrentUserIndex)
  1441. {
  1442. for (int j = 0; j < m_cbWeaveItemCount[CurrentUserIndex]; j++)
  1443. {
  1444. CString strOut;
  1445. switch (m_WeaveItemArray[CurrentUserIndex][j].cbWeaveKind)
  1446. {
  1447. case WIK_PENG:
  1448. case WIK_BU_GANG:
  1449. case WIK_MING_GANG:
  1450. case WIK_AN_GANG:
  1451. {
  1452. //cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  1453. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard)] = 0;
  1454. break;
  1455. }
  1456. case WIK_LEFT:{
  1457. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard)] = 0;
  1458. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) + 1] = 0;
  1459. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) + 2] = 0;
  1460. // cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  1461. // cbCards[nCards++] = WeaveItem[i].cbCenterCard + 1;
  1462. // cbCards[nCards++] = WeaveItem[i].cbCenterCard + 2;
  1463. break;
  1464. }
  1465. case WIK_CENTER:{
  1466. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) - 1] = 0;
  1467. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard)] = 0;
  1468. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) + 1] = 0;
  1469. // cbCards[nCards++] = WeaveItem[i].cbCenterCard - 1;
  1470. // cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  1471. // cbCards[nCards++] = WeaveItem[i].cbCenterCard + 1;
  1472. break;
  1473. }
  1474. case WIK_RIGHT:{
  1475. // cbCards[nCards++] = WeaveItem[i].cbCenterCard - 1;
  1476. // cbCards[nCards++] = WeaveItem[i].cbCenterCard - 2;
  1477. // cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  1478. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) - 1] = 0;
  1479. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard) - 2] = 0;
  1480. mCanDingCaiCardArray[CurrentUserIndex][m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[CurrentUserIndex][j].cbCenterCard)] = 0;
  1481. break;
  1482. }
  1483. default:
  1484. break;
  1485. }
  1486. }
  1487. }
  1488. //框架消息处理
  1489. bool CTableFrameSink_dcs::OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
  1490. {
  1491. return false;
  1492. }
  1493. //用户断线重连
  1494. bool CTableFrameSink_dcs::OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem)
  1495. {
  1496. auto dwUserID = pIServerUserItem->GetUserID();
  1497. if (wChairID > 4 || wChairID < 0)
  1498. {
  1499. OutputDebugString(_T("OnActionUserConnect wChairID Error"));
  1500. return false;
  1501. }
  1502. auto iter = std::find(m_offlineUsers.begin(), m_offlineUsers.end(), dwUserID);
  1503. if (m_TabbOutCardCout[wChairID] > 0)
  1504. HttpTingCard(wChairID);
  1505. if (wChairID != m_wProvideUser&&m_cbUserAction[wChairID] & WIK_Qiang_GANG){
  1506. //mCmd_NotifyQianggh
  1507. SparrowMaJiang::PB_CS_S_NOTIFY_QIANGGH pQiangGang;
  1508. pQiangGang.set_cbactioncard(mCmd_NotifyQianggh->cbActionCard);
  1509. pQiangGang.set_cbactionmask(mCmd_NotifyQianggh->cbActionMask);
  1510. pQiangGang.set_wresumeuser(mCmd_NotifyQianggh->wResumeUser);
  1511. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1512. {
  1513. pQiangGang.add_caicards(mCmd_NotifyQianggh->caiCards[j]);
  1514. }
  1515. std::string pbdate = pQiangGang.SerializePartialAsString();
  1516. m_pITableFrame->SendTableData(wChairID, SUB_S_NOTIFY_QIANGGH, (void*)pbdate.c_str(), pbdate.length());
  1517. }
  1518. if (iter != end(m_offlineUsers))
  1519. {
  1520. m_offlineUsers.erase(iter); //玩家重新上线
  1521. return true;
  1522. }
  1523. return true;
  1524. }
  1525. //用户坐下
  1526. bool CTableFrameSink_dcs::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
  1527. {
  1528. return true;
  1529. }
  1530. //游戏中途旁观进入
  1531. bool CTableFrameSink_dcs::PerformLookonLogin(IServerUserItem * pIServerUserItem)
  1532. {
  1533. CMD_S_PangGuan StatusPlay;
  1534. memset(&StatusPlay, 0, sizeof(StatusPlay));
  1535. //游戏房主基础配置
  1536. CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  1537. CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore));
  1538. StatusPlay.cbTotalCardCount = m_cbTotalCardCount;
  1539. StatusPlay.cbLeftCardCount = m_cbLeftCardCount;
  1540. StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  1541. StatusPlay.GameStatus = m_pITableFrame->IsDrawStarted();
  1542. if (StatusPlay.GameStatus)
  1543. {
  1544. //游戏变量
  1545. StatusPlay.wBankerUser = m_wBankerUser;
  1546. WORD wSice = WORD(m_lSiceCount & 0xffff);
  1547. StatusPlay.lSiZi[0] = HIBYTE(wSice);
  1548. StatusPlay.lSiZi[1] = LOBYTE(wSice);
  1549. StatusPlay.lSiZi[2] = m_cbMagicFirstData;
  1550. StatusPlay.lSiZi[3] = m_cbMagicSecondData;
  1551. StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();
  1552. CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard));
  1553. CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount));
  1554. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  1555. {
  1556. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  1557. {
  1558. continue;
  1559. }
  1560. //StatusPlay.bWanLaiZi[i] = m_OutLaiZi[i];
  1561. //StatusPlay.bWanLaiZi[i] |= (m_OutHongZhongGang[i] << 4);
  1562. //StatusPlay.bWanLaiZi[i] |= (m_OutFaCaiGang[i] << 8);
  1563. StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]);
  1564. }
  1565. StatusPlay.totalOptTime = 10;
  1566. StatusPlay.leftOptTime = 0;
  1567. ASSERT(m_wProvideUser >= 0 && m_wProvideUser <= 3);
  1568. //当前到谁家
  1569. StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser);
  1570. WORD OldUser = 0;//定义一个最后出牌用户`
  1571. if (m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR)//牌权是摸牌得且没出牌
  1572. {
  1573. //if (m_bGangStatus)
  1574. //{
  1575. // StatusPlay.bPutCardData[m_wProvideUser] = m_OutLastLaiZiData;
  1576. //}
  1577. //else
  1578. //{
  1579. if (m_bTwoPlayerFlag)
  1580. {
  1581. OldUser = (m_wProvideUser - 2 + GAME_PLAYER) % GAME_PLAYER;
  1582. }
  1583. else
  1584. {
  1585. OldUser = (m_wProvideUser - 1 + mPlayGameUserCount) % mPlayGameUserCount;
  1586. }
  1587. BYTE TempIndex = 0;
  1588. BYTE bDiscardCount = (m_cbDiscardCount[OldUser] - 1) >= 0 ? (m_cbDiscardCount[OldUser] - 1) : 0;
  1589. for (BYTE i = bDiscardCount; i < 40; i++)
  1590. {
  1591. if (m_cbDiscardCard[OldUser][i] == 0)
  1592. {
  1593. TempIndex = i - 1;
  1594. break;
  1595. }
  1596. }
  1597. TempIndex = (TempIndex == 255) ? 0 : TempIndex;
  1598. StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex];
  1599. //}
  1600. }
  1601. if (m_wProvideUser == m_wOutCardUser&& m_wCurrentUser == INVALID_CHAIR)//当有人可以碰且没有碰时候
  1602. {
  1603. StatusPlay.bPutCardData[m_wProvideUser] = m_cbProvideCard;
  1604. StatusPlay.cbDiscardCard[m_wProvideUser][StatusPlay.cbDiscardCount[m_wProvideUser]++] = m_cbProvideCard;
  1605. }
  1606. //组合扑克
  1607. CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray));
  1608. CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  1609. }
  1610. SparrowMaJiang::PB_CS_S_PangGuan PangGuan;
  1611. PangGuan.mutable_gameconfig()->set_bduolai(StatusPlay.gameConfig.bDuoLai);
  1612. PangGuan.mutable_gameconfig()->set_isowner(StatusPlay.gameConfig.IsOwner);
  1613. PangGuan.mutable_gameconfig()->set_roomid(StatusPlay.gameConfig.RoomId);
  1614. std::string sPrivateTableID = CW2AEX<1024>(StatusPlay.gameConfig.sPrivateTableID, CP_UTF8).m_psz;
  1615. PangGuan.mutable_gameconfig()->set_sprivatetableid(sPrivateTableID);
  1616. PangGuan.mutable_gameconfig()->set_tmp1(StatusPlay.gameConfig.tmp1);
  1617. PangGuan.mutable_gameconfig()->set_tmp2(StatusPlay.gameConfig.tmp2);
  1618. PangGuan.mutable_gameconfig()->set_wdiscore(StatusPlay.gameConfig.wDiScore);
  1619. PangGuan.mutable_gameconfig()->set_wfanfei(StatusPlay.gameConfig.wFanFei);
  1620. PangGuan.mutable_gameconfig()->set_wfengding(StatusPlay.gameConfig.wFengDing);
  1621. PangGuan.mutable_gameconfig()->set_whadplaycount(StatusPlay.gameConfig.wHadPlayCount);
  1622. PangGuan.mutable_gameconfig()->set_wiplimit(StatusPlay.gameConfig.wIpLimit);
  1623. PangGuan.mutable_gameconfig()->set_wplaycountrule(StatusPlay.gameConfig.wPlayCountRule);
  1624. PangGuan.mutable_gameconfig()->set_wsubgameid(StatusPlay.gameConfig.wSubGameID);
  1625. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1626. {
  1627. PangGuan.add_lusertmpscore(StatusPlay.lUserTmpScore[j]);
  1628. PangGuan.add_bputcarddata(StatusPlay.bPutCardData[j]);
  1629. PangGuan.add_cbcardcount(StatusPlay.cbCardCount[j]);
  1630. PangGuan.add_cbweavecount(StatusPlay.cbWeaveCount[j]);
  1631. PangGuan.add_cbdiscardcount(StatusPlay.cbDiscardCount[j]);
  1632. SparrowMaJiang::pb_cbDiscardCard* DiscardCard = PangGuan.add_cbdiscardcard();
  1633. for (BYTE i = 0; i < 40; i++)
  1634. {
  1635. DiscardCard->add_cbdiscardcard(StatusPlay.cbDiscardCard[j][i]);
  1636. }
  1637. SparrowMaJiang::pb_WeaveItemArray* WeaveItemArray = PangGuan.add_weaveitemarray();
  1638. for (BYTE i = 0; i < 4; i++)
  1639. {
  1640. SparrowMaJiang::pb_WeaveItem* WeaveItem = WeaveItemArray->add_weaveitem();
  1641. WeaveItem->set_cbcentercard(StatusPlay.WeaveItemArray[j][i].cbCenterCard);
  1642. WeaveItem->set_cbpubliccard(StatusPlay.WeaveItemArray[j][i].cbPublicCard);
  1643. WeaveItem->set_cbweavekind(StatusPlay.WeaveItemArray[j][i].cbWeaveKind);
  1644. WeaveItem->set_wprovideuser(StatusPlay.WeaveItemArray[j][i].wProvideUser);
  1645. for (BYTE k = 0; k < 4; k++)
  1646. {
  1647. WeaveItem->add_cbmargicoffset(StatusPlay.WeaveItemArray[j][i].cbMargicOffset[k]);
  1648. }
  1649. }
  1650. }
  1651. PangGuan.set_gamestatus(StatusPlay.GameStatus);
  1652. PangGuan.set_cbtotalcardcount(StatusPlay.cbTotalCardCount);
  1653. PangGuan.set_cbleftcardcount(StatusPlay.cbLeftCardCount);
  1654. PangGuan.set_wbankeruser(StatusPlay.wBankerUser);
  1655. for (BYTE j = 0; j < 4; j++)
  1656. {
  1657. PangGuan.add_lsizi(StatusPlay.lSiZi[j]);
  1658. }
  1659. PangGuan.set_dwownerid(StatusPlay.dwOwnerID);
  1660. PangGuan.set_wcurrentuser(StatusPlay.wCurrentUser);
  1661. PangGuan.set_totalopttime(StatusPlay.totalOptTime);
  1662. PangGuan.set_leftopttime(StatusPlay.leftOptTime);
  1663. std::string pbdata = PangGuan.SerializePartialAsString();
  1664. return m_pITableFrame->SendUserItemData(pIServerUserItem, SUB_S_PANGGUAN, (void*)pbdata.c_str(), pbdata.length());
  1665. }
  1666. //用户起来
  1667. bool CTableFrameSink_dcs::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
  1668. {
  1669. //庄家设置
  1670. if (bLookonUser == false && !QueryUseTemporaryScore())
  1671. {
  1672. m_bTrustee[wChairID] = false;
  1673. CMD_S_Trustee Trustee;
  1674. Trustee.bTrustee = false;
  1675. Trustee.wChairID = wChairID;
  1676. SparrowMaJiang::PB_CS_S_Trustee Trustees;
  1677. Trustees.set_btrustee(Trustee.bTrustee);
  1678. Trustees.set_wchairid(Trustee.wChairID);
  1679. std::string pbdata = Trustees.SerializePartialAsString();
  1680. RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1681. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1682. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1683. }
  1684. return true;
  1685. }
  1686. //用户出牌
  1687. bool CTableFrameSink_dcs::OnUserOutCard(WORD wChairID, BYTE cbCardData)
  1688. {
  1689. m_bQiangGang = false;
  1690. //效验状态
  1691. ASSERT(m_pITableFrame->GetGameStatus() == GS_MJ_PLAY);
  1692. if (m_pITableFrame->GetGameStatus() != GS_MJ_PLAY) return true;
  1693. //错误断言
  1694. ASSERT(wChairID == m_wCurrentUser);
  1695. ASSERT(m_GameLogic.IsValidCard(cbCardData) == true);
  1696. //效验参数
  1697. if (wChairID != m_wCurrentUser) return false;
  1698. if (m_GameLogic.IsValidCard(cbCardData) == false) return false;
  1699. if ((m_GameLogic.GetCardCount(m_cbCardIndex[wChairID]) - 2) % 3 != 0)
  1700. {
  1701. return false;
  1702. }
  1703. //删除扑克
  1704. if (m_GameLogic.RemoveCard(m_cbCardIndex[wChairID], cbCardData) == false)
  1705. {
  1706. ASSERT(FALSE);
  1707. return false;
  1708. }
  1709. ZeroMemory(&m_cbLastDisCardData[wChairID], sizeof(m_cbLastDisCardData[wChairID]));
  1710. m_cbLastDisCount[wChairID] = 0;
  1711. //for (BYTE i = 0; i < GAME_PLAYER; i++)
  1712. //{
  1713. // if (i == wChairID)continue;
  1714. // m_cbLastDisCardData[i][m_cbLastDisCount[i]++] = cbCardData;//打出得牌,放到其他玩家得记忆库里面
  1715. //}
  1716. //m_bSendStatus = true;
  1717. //if (m_bGangStatus)
  1718. //{
  1719. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  1720. // m_bGangStatus = false;
  1721. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  1722. m_bGangOption = 0;
  1723. m_GangPrivedUserID = -1;
  1724. //m_bGangOutStatus = true;
  1725. //}
  1726. m_cbUserAction[wChairID] = WIK_NULL;
  1727. m_cbPerformAction[wChairID] = WIK_NULL;
  1728. //出牌记录
  1729. m_cbOutCardCount++;
  1730. m_wOutCardUser = wChairID; //记录出牌人
  1731. m_cbOutCardData = cbCardData; //记录出牌数据
  1732. m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数
  1733. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  1734. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  1735. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  1736. BYTE FanHui[MAX_INDEX] = { 0 };
  1737. /*m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], FanHui);
  1738. if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], FanHui))
  1739. {*/
  1740. OutTingCard(wChairID, m_GameLogic.SwitchToCardIndex(m_cbOutCardData));
  1741. //}
  1742. //构造数据
  1743. CMD_S_OutCard OutCard;
  1744. OutCard.wOutCardUser = wChairID;
  1745. OutCard.cbOutCardData = cbCardData;
  1746. OutCard.bOptType = 0;
  1747. SparrowMaJiang::PB_CS_S_OutCard Card;
  1748. Card.set_woutcarduser(OutCard.wOutCardUser);
  1749. Card.set_cboutcarddata(OutCard.cbOutCardData);
  1750. Card.set_bopttype(OutCard.bOptType);
  1751. //发送数据
  1752. std::string pbdata = Card.SerializePartialAsString();
  1753. RepayRecord(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1754. //发送消息
  1755. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1756. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1757. m_wProvideUser = wChairID;
  1758. m_cbProvideCard = cbCardData;
  1759. //用户切换
  1760. if (m_bTwoPlayerFlag)
  1761. {
  1762. m_wCurrentUser = (wChairID + 2) % GAME_PLAYER;
  1763. }
  1764. else
  1765. {
  1766. m_wCurrentUser = (wChairID + 1) % mPlayGameUserCount;
  1767. }
  1768. //响应判断
  1769. bool bAroseAction = EstimateUserRespond(wChairID, cbCardData, EstimatKind_OutCard);
  1770. //派发扑克
  1771. if (bAroseAction == false)
  1772. {
  1773. DispatchCardData(m_wCurrentUser);
  1774. }
  1775. return true;
  1776. }
  1777. //用户操作
  1778. bool CTableFrameSink_dcs::OnUserOperateCard(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4])
  1779. {
  1780. //效验状态
  1781. ASSERT(m_pITableFrame->GetGameStatus() == GS_MJ_PLAY);
  1782. if (m_pITableFrame->GetGameStatus() != GS_MJ_PLAY)
  1783. return true;
  1784. //效验用户 注意:机器人有可能发生此断言
  1785. //ASSERT((wChairID==m_wCurrentUser)||(m_wCurrentUser==INVALID_CHAIR));
  1786. if ((wChairID != m_wCurrentUser) && (m_wCurrentUser != INVALID_CHAIR) && (cbOperateCode != WIK_Qiang_GANG))
  1787. return true;
  1788. tagGangCardResult GangCardResult;
  1789. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  1790. //被动动作
  1791. if (m_wCurrentUser == INVALID_CHAIR&&wChairID != m_wProvideUser)//表示有人出牌后,下一个人还未摸牌这段时间内,有人对上一张出牌有吃胡、杠、碰等操作
  1792. {
  1793. //效验状态
  1794. if (m_bResponse[wChairID] == true)
  1795. return true;
  1796. if ((cbOperateCode != WIK_NULL) && ((m_cbUserAction[wChairID] & cbOperateCode) == 0) && (cbOperateCode != WIK_Qiang_GANG&&cbOperateCode != WIK_ZI_MO))
  1797. return true;
  1798. //变量定义
  1799. WORD wTargetUser = wChairID;
  1800. int cbTargetAction = cbOperateCode;
  1801. //设置变量
  1802. m_bResponse[wChairID] = true;
  1803. m_cbPerformAction[wChairID] = cbOperateCode;
  1804. m_cbOperateCard[wChairID] = cbOperateCard;
  1805. CopyMemory(m_cbOperateCaiCard[wChairID], cbCaiShenCard, sizeof(cbCaiShenCard));
  1806. //执行动作的优先级判断, WIK_CHI_HU 大于 WIK_PENG 大于 [WIK_RIGHT or WIK_CENTER or WIK_LEFT]
  1807. WORD TmpwProvideUser = m_wProvideUser;
  1808. OperatorPriority(TmpwProvideUser, wTargetUser, cbTargetAction);
  1809. if (m_bResponse[wTargetUser] == false)//操作判断
  1810. {
  1811. if (cbOperateCode == WIK_NULL)
  1812. m_cbLastDisCardData[wChairID][m_cbLastDisCount[wChairID]++] = m_cbProvideCard;
  1813. return true;
  1814. }
  1815. //放弃操作
  1816. if (m_bQiangGang&&cbOperateCard == 0)//此处if 主要用于解决,用户抢杠胡那一刻,断线重连。客户端不知道用户抢的那张牌。所以必须后台强制处理一下。
  1817. {
  1818. m_cbOperateCard[wTargetUser] = m_cbProvideCard;
  1819. }
  1820. else
  1821. {
  1822. m_bQiangGang = false;
  1823. }
  1824. if (cbOperateCode == WIK_NULL &&cbTargetAction == WIK_NULL)
  1825. {
  1826. //用户状态
  1827. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1828. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1829. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1830. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1831. //当该用户点过时 加入该张牌
  1832. //if(wTargetUser==wChairID)
  1833. //{
  1834. m_cbLastDisCardData[wTargetUser][m_cbLastDisCount[wTargetUser]++] = m_cbProvideCard;
  1835. //}
  1836. if (m_wCurrentUser == INVALID_CHAIR)
  1837. {
  1838. DispatchCardData(m_wResumeUser);
  1839. }
  1840. return true;
  1841. }
  1842. //变量定义
  1843. BYTE cbTargetCard = m_cbOperateCard[wTargetUser];
  1844. BYTE cbTargetCaiCard[4] = { 0 };
  1845. CopyMemory(cbTargetCaiCard, m_cbOperateCaiCard[wTargetUser], sizeof(cbTargetCaiCard));
  1846. if (cbTargetCard != m_cbProvideCard)//校验很重要
  1847. {
  1848. m_bResponse[wTargetUser] = false;
  1849. ASSERT(false);
  1850. return false;
  1851. }
  1852. //出牌变量
  1853. m_cbOutCardData = 0;
  1854. //m_bSendStatus = true;
  1855. m_wOutCardUser = INVALID_CHAIR;
  1856. //m_bEnjoinChiHu[wTargetUser] = true;
  1857. //用户状态
  1858. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1859. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1860. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1861. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1862. //组合扑克
  1863. if (cbTargetAction&(WIK_LEFT | WIK_CENTER | WIK_RIGHT | WIK_PENG | WIK_MING_GANG))
  1864. {
  1865. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  1866. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  1867. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  1868. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  1869. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  1870. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  1871. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  1872. /*if (cbTargetAction& WIK_PENG)
  1873. {
  1874. //当任意一个玩家碰了之后,清理最后一张牌记录 //下一个牌 所有人 都可以碰 所以清零
  1875. ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData));
  1876. ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount));
  1877. }*/
  1878. }
  1879. if (cbTargetAction &WIK_ZI_MO || cbTargetAction&WIK_Qiang_GANG)//此动作为抢杠胡才会促发
  1880. {
  1881. m_bQiangGang = true;
  1882. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  1883. m_wCurrentUser = wTargetUser;
  1884. //m_wProvideUser = wTargetUser;
  1885. m_cbSendCardData = m_cbProvideCard;
  1886. m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1887. m_cbUserAction[wTargetUser] = WIK_Qiang_GANG;
  1888. OnUserOperateCard(wTargetUser, WIK_Qiang_GANG, m_cbProvideCard, cbCaiShenCard);
  1889. return true;
  1890. }
  1891. DeleteCaiShenCard(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard);
  1892. //杠牌处理
  1893. if (cbTargetAction & (WIK_MING_GANG | WIK_DAN_MING_GANG | WIK_SHUANG_MING_GANG | WIK_SAN_MING_GANG))
  1894. {
  1895. int cbActionMask = WIK_NULL;
  1896. WORD cbActionCard[6] = { 0 };
  1897. HttpOperateResult(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard, cbActionMask, cbActionCard);
  1898. //设置用户
  1899. m_wCurrentUser = wTargetUser;
  1900. m_bGangOption = cbTargetAction;
  1901. m_GangPrivedUserID = m_wProvideUser;
  1902. DispatchCardData(wTargetUser, true);
  1903. return true;
  1904. }
  1905. else
  1906. {
  1907. WORD cbActionCard[6] = { 0 };
  1908. int cbActionMask = NULL;
  1909. TingCard(wTargetUser);
  1910. HttpOperateResult(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard, cbActionMask, cbActionCard);
  1911. //设置用户
  1912. m_wCurrentUser = wTargetUser;
  1913. if (m_TabbOutCardCout[wTargetUser] > 0)//有听牌就发一个听牌协议
  1914. {
  1915. HttpTingCard(wTargetUser);
  1916. }
  1917. return true;
  1918. }
  1919. ASSERT(false);
  1920. return false;
  1921. }
  1922. //主动动作
  1923. if (m_wCurrentUser == wChairID) //如果是摸牌用户的操作,比如自摸或者自杠
  1924. {
  1925. if (IsCanTianhu()&&cbOperateCode==WIK_ZI_MO)
  1926. {
  1927. cbOperateCode = WIK_TIAN_ZI_MO;
  1928. }
  1929. if (cbOperateCode == WIK_NULL)
  1930. {
  1931. //用户状态
  1932. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1933. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1934. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1935. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1936. //发送扑克
  1937. return true;
  1938. }
  1939. //效验操作
  1940. if ((cbOperateCode == WIK_NULL))
  1941. return true;
  1942. //设置变量
  1943. //m_bSendStatus = true;
  1944. //m_bEnjoinChiHu[m_wCurrentUser]=true;
  1945. m_cbUserAction[m_wCurrentUser] = WIK_NULL;
  1946. m_cbPerformAction[m_wCurrentUser] = WIK_NULL;
  1947. bool bPublic = false;
  1948. //执行动作
  1949. if (cbOperateCode & (WIK_TIAN_ZI_MO | WIK_ZI_MO | WIK_Qiang_GANG))
  1950. {
  1951. BYTE TempCardData = m_cbProvideCard;
  1952. if (m_cbProvideCard != m_cbSendCardData || m_cbProvideCard != cbOperateCard)
  1953. {
  1954. ASSERT(false);
  1955. return false;
  1956. }
  1957. int TempAction = 0;
  1958. CChiHuRight chr;
  1959. BYTE TaiShu = 0;
  1960. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;
  1961. if (cbCaiShenCard == NULL || cbCaiShenCard[1] == 0 && cbCaiShenCard[0] == 0)
  1962. {
  1963. m_GameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  1964. }
  1965. else
  1966. {
  1967. if (cbCaiShenCard[1] == 0)
  1968. {
  1969. m_GameLogic.SetMagicIndex(m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0]), MAX_INDEX);
  1970. }
  1971. else
  1972. {
  1973. m_GameLogic.SetMagicIndex(m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0]), m_GameLogic.SwitchToCardIndex(cbCaiShenCard[1]));
  1974. }
  1975. }
  1976. TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID],
  1977. m_cbWeaveItemCount[wChairID], m_cbSendCardData, chr, TaiShu, m_bUsersGangStatus[wChairID], m_bQiangGang);
  1978. if (IsCanTianhu()&&TaiShu>0)
  1979. {
  1980. TempAction = WIK_ZI_MO;
  1981. }
  1982. m_GameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  1983. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1984. if (TempAction == WIK_NULL)
  1985. {
  1986. OutputDebugString(_T("玩家点了胡牌,但是实际上没有胡"));
  1987. CString str;
  1988. str.Format(_T("此时财神是 %d %d "), cbCaiShenCard[0], cbCaiShenCard[1]);
  1989. OutputDebugString(str);
  1990. ASSERT(false);
  1991. return false;
  1992. }
  1993. m_HuPai[wChairID]++;
  1994. CMD_S_OperateResult OperateResult;
  1995. OperateResult.wOperateUser = wChairID;
  1996. OperateResult.cbOperateCard = cbOperateCard;
  1997. OperateResult.cbOperateCode = cbOperateCode;
  1998. OperateResult.wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wChairID : m_wProvideUser;
  1999. if (cbCaiShenCard != NULL)
  2000. {
  2001. CopyMemory(OperateResult.cbCaiShenCard, cbCaiShenCard, 4);
  2002. }
  2003. WORD paitype = bHuPaiType(chr);
  2004. if (m_bUsersGangStatus[wChairID] == true)
  2005. {
  2006. paitype |= ZJ_TAI_GangKai;
  2007. //TaiShu++;
  2008. }
  2009. if (m_bQiangGang == true)
  2010. {
  2011. paitype |= ZJ_TAI_QiangGang;
  2012. OperateResult.cbOperateCode = WIK_CHI_HU;
  2013. }
  2014. if (WIK_TIAN_ZI_MO == cbOperateCode)//天胡台数直接到最大
  2015. {
  2016. paitype |= ZJ_TAI_TianHu;
  2017. TaiShu = mMaxTaiNum;
  2018. }
  2019. OperateResult.cbActionMask = TaiShu | (paitype << 16);//异或 然后右移
  2020. ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard));
  2021. SparrowMaJiang::PB_CS_S_OperateResult Result;
  2022. Result.set_woperateuser(OperateResult.wOperateUser);
  2023. Result.set_cboperatecard(OperateResult.cbOperateCard);
  2024. Result.set_cboperatecode(OperateResult.cbOperateCode);
  2025. Result.set_wprovideuser(OperateResult.wProvideUser);
  2026. for (BYTE j = 0; j < 4; j++)
  2027. {
  2028. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2029. }
  2030. Result.set_cbactionmask(OperateResult.cbActionMask);
  2031. for (BYTE j = 0; j < 6; j++)
  2032. {
  2033. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  2034. }
  2035. //发送数据
  2036. std::string pbdata = Result.SerializePartialAsString();
  2037. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2038. //发送消息
  2039. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2040. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2041. //积分变动
  2042. CMD_S_GangScore gs;
  2043. ZeroMemory(&gs, sizeof(gs));
  2044. gs.wChairId = wChairID;
  2045. gs.cbOperateCode = WIK_ZI_MO;
  2046. if (m_bQiangGang == true){
  2047. gs.cbOperateCode = WIK_CHI_HU;
  2048. }
  2049. else
  2050. {
  2051. gs.cbOperateCode = WIK_ZI_MO;
  2052. }
  2053. int TempInfoScore = 0;
  2054. WORD LaoZhuang = m_wBankerUser & 0x00ff;
  2055. if (LianXuHuPai[LaoZhuang] >= 2)
  2056. {
  2057. TaiShu++;
  2058. //TaiShu = TaiShu > (mMaxTaiNum - 1) ? mMaxTaiNum : ++TaiShu;//老庄台数加1
  2059. }
  2060. /* if (TaiShu>FengDingTaiNum)
  2061. {
  2062. TaiShu = FengDingTaiNum;
  2063. }*/
  2064. // [9/11/2017 Zoro] 经与苗苗确认,取消新加需求。所有杠开 都算自摸。
  2065. /* if (mMjType==1&&m_bGangStatus==true)
  2066. {
  2067. if (m_GangPrivedUserID!=wChairID&&m_GangPrivedUserID!=-1&&wChairID==mbaoMjUserID)
  2068. {
  2069. CaculationScore(wChairID, TaiShu, Win_FangPao, m_GangPrivedUserID, chr, gs);
  2070. }
  2071. else
  2072. {
  2073. CaculationScore(wChairID, TaiShu, Win_ZiMo, m_wProvideUser, chr, gs);
  2074. }
  2075. }
  2076. else
  2077. {*/
  2078. //}
  2079. if (cbOperateCode&WIK_Qiang_GANG)
  2080. {
  2081. CaculationScore(wChairID, TaiShu, win_qianggang, m_wProvideUser, chr, gs);
  2082. }
  2083. else
  2084. {
  2085. CaculationScore(wChairID, TaiShu, Win_ZiMo, m_wProvideUser, chr, gs);
  2086. }
  2087. LianXuHuPai[wChairID]++;
  2088. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  2089. GangScore.set_cboperatecode(gs.cbOperateCode);
  2090. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2091. {
  2092. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  2093. GangScore.add_lgangscore(gs.lGangScore[j]);
  2094. }
  2095. GangScore.set_wchairid(gs.wChairId);
  2096. std::string pbscore = GangScore.SerializePartialAsString();
  2097. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2098. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2099. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  2100. {
  2101. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2102. {
  2103. continue;
  2104. }
  2105. gs.cbWanJiaScore[i] = m_lGameScore[i];
  2106. }
  2107. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2108. {
  2109. GangScore.set_cbwanjiascore(j, gs.cbWanJiaScore[j]);
  2110. }
  2111. std::string pbscores = GangScore.SerializePartialAsString();
  2112. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscores.c_str(), pbscores.length());
  2113. OnEventGameConclude(wChairID, NULL, GER_NORMAL);
  2114. return true;
  2115. }
  2116. if (cbOperateCode & (WIK_DAN_BU_GANG | WIK_BU_GANG))
  2117. {
  2118. DeleteCard(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard);
  2119. int cbActionMask = WIK_NULL;
  2120. WORD cbActionCard[6] = { 0 };
  2121. HttpOperateResult(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard);
  2122. //响应判断
  2123. m_wProvideUser = wChairID;
  2124. m_bQiangGang = true;
  2125. m_bUsersGangStatus[wChairID] = true;
  2126. bool bAroseAction = false;
  2127. if (cbOperateCard<0x31)
  2128. {
  2129. bAroseAction = EstimateUserRespond(wChairID, cbOperateCard, EstimatKind_GangCard);//补杠,别人可以抢杠胡
  2130. }
  2131. //--201808-10
  2132. // 此处包含bug,如果抢杠的用户选择了过。此时该杠上开花的用户则无法胡杠上开话,会少一台。此bug需要修复 [11/28/2017 Zoro]
  2133. //派发扑克
  2134. if (bAroseAction == false)
  2135. {
  2136. m_bQiangGang = false;
  2137. m_bGangOption = cbOperateCode;
  2138. m_GangPrivedUserID = m_wCurrentUser;
  2139. DispatchCardData(m_wCurrentUser, true);
  2140. }
  2141. else
  2142. {
  2143. // m_bGangStatus = false;
  2144. m_bQiangGang = true;
  2145. }
  2146. return true;
  2147. }
  2148. DeleteCard(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard);
  2149. int cbActionMask = WIK_NULL;
  2150. WORD cbActionCard[6] = { 0 };
  2151. HttpOperateResult(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard);
  2152. DispatchCardData(wChairID, true);
  2153. return true;
  2154. }
  2155. return true;
  2156. }
  2157. //发送操作
  2158. bool CTableFrameSink_dcs::SendOperateNotify()
  2159. {
  2160. //发送提示
  2161. for (WORD i = 0; i < mPlayGameUserCount; i++)
  2162. {
  2163. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2164. {
  2165. continue;
  2166. }
  2167. if (m_cbUserAction[i] != WIK_NULL)
  2168. {
  2169. //构造数据
  2170. CMD_S_OperateNotify OperateNotify;
  2171. OperateNotify.wResumeUser = m_wResumeUser;
  2172. OperateNotify.cbActionCard = m_cbProvideCard;
  2173. OperateNotify.cbActionMask = m_cbUserAction[i];
  2174. SparrowMaJiang::PB_CS_S_OperateNotify Notify;
  2175. Notify.set_wresumeuser(OperateNotify.wResumeUser);
  2176. Notify.set_cbactioncard(OperateNotify.cbActionCard);
  2177. Notify.set_cbactionmask(OperateNotify.cbActionMask);
  2178. std::string pbdata = Notify.SerializePartialAsString();
  2179. //发送数据
  2180. m_pITableFrame->SendTableData(i, SUB_S_OPERATE_NOTIFY, (void*)pbdata.c_str(), pbdata.length());
  2181. ////-沙 前端需要展示提示数据
  2182. OperateNotify.wResumeUser = i;
  2183. Notify.set_wresumeuser(OperateNotify.wResumeUser);
  2184. std::string pbdatas = Notify.SerializePartialAsString();
  2185. RepayRecord(i, SUB_S_OPERATE_NOTIFY, (void*)pbdatas.c_str(), pbdata.length());
  2186. }
  2187. }
  2188. //m_pITableFrame->SendLookonData(i, SUB_S_OPERATE_NOTIFY, &OperateNotify, sizeof(OperateNotify));
  2189. return true;
  2190. }
  2191. //派发扑克,wCurrentUser表示给哪个用户,bTail表示是末尾拿牌还是不是,true表示末尾,同时标示杠牌抓牌
  2192. bool CTableFrameSink_dcs::DispatchCardData(WORD wCurrentUser, bool bTail)
  2193. {
  2194. //状态效验
  2195. ASSERT(wCurrentUser != INVALID_CHAIR);
  2196. if (wCurrentUser == INVALID_CHAIR)
  2197. return false;
  2198. //丢弃扑克
  2199. if ((m_wOutCardUser != INVALID_CHAIR) && (m_cbOutCardData != 0))
  2200. {
  2201. m_cbDiscardCount[m_wOutCardUser]++;
  2202. m_cbDiscardCard[m_wOutCardUser][m_cbDiscardCount[m_wOutCardUser] - 1] = m_cbOutCardData;
  2203. }
  2204. //荒庄结束
  2205. if (m_cbLeftCardCount == 0)
  2206. {
  2207. //m_cbChiHuCard = 0;
  2208. m_wProvideUser = INVALID_CHAIR;
  2209. bIsHuang = true;
  2210. OnEventGameConclude(m_wProvideUser, NULL, GER_NORMAL);
  2211. return true;
  2212. }
  2213. mBCanShowLeft = TRUE;
  2214. //设置变量
  2215. m_cbOutCardData = 0;
  2216. m_wCurrentUser = wCurrentUser; //记录拿牌人的索引。
  2217. m_wOutCardUser = INVALID_CHAIR; //置空上次出牌用户的索引
  2218. BYTE ActionCard[3] = { 0 }; //操作牌值
  2219. BYTE AnActionCount = 0;
  2220. //发送扑克
  2221. m_cbSendCardCount++;
  2222. --m_cbLeftCardCount;//剩余牌减少
  2223. m_cbSendCardData = m_cbRepertoryCard[--m_cbShiJiLeftCardCount];//实际剩余牌减少
  2224. CChiHuRight chr;
  2225. BYTE TaiShu = 0;
  2226. // m_bGangStatus = bTail;
  2227. m_bUsersGangStatus[wCurrentUser] = bTail;
  2228. m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wCurrentUser], m_WeaveItemArray[wCurrentUser],
  2229. m_cbWeaveItemCount[wCurrentUser], m_cbSendCardData, chr, TaiShu, bTail);
  2230. //////////////////////////////////////////////////////////////////////////
  2231. //定财神 判断是否可以定财神
  2232. BYTE TempCardIndex[MAX_INDEX] = { 0 };
  2233. CopyMemory(TempCardIndex, m_cbCardIndex[wCurrentUser], MAX_INDEX);
  2234. std::vector<CanDcsSt> vCards;
  2235. if (GetMagicCardAndTaiNum(TempCardIndex, wCurrentUser, m_cbSendCardData, vCards,TRUE))
  2236. {
  2237. m_cbUserAction[wCurrentUser] |= WIK_CanDingMagic;
  2238. }
  2239. //////////////////////////////////////////////////////////////////////////
  2240. //加牌
  2241. m_cbCardIndex[wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  2242. //设置变量
  2243. m_wProvideUser = wCurrentUser;
  2244. m_cbProvideCard = m_cbSendCardData;
  2245. //杠牌判断
  2246. tagGangCardResult GangCardResult;
  2247. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  2248. if (m_cbLeftCardCount > 0)
  2249. {
  2250. bool bCanAnGang = true;//此true表示自己抓牌,false表示表人打得去检验杠,
  2251. m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[wCurrentUser],
  2252. m_WeaveItemArray[wCurrentUser], m_cbWeaveItemCount[wCurrentUser], GangCardResult);
  2253. }
  2254. //听牌计算
  2255. // m_TabbOutCardCout[wCurrentUser] = 0; //可以打出的牌就听牌的个数
  2256. // ZeroMemory(m_TabbOutCardData[wCurrentUser], sizeof(m_TabbOutCardData[wCurrentUser])); //具体打哪几张牌
  2257. // ZeroMemory(m_TabbTingCardCount[wCurrentUser], sizeof(m_TabbTingCardCount[wCurrentUser])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  2258. // ZeroMemory(m_TabbTingCardData[wCurrentUser], sizeof(m_TabbTingCardData[wCurrentUser])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  2259. if (!(m_cbUserAction[wCurrentUser] & WIK_ZI_MO))
  2260. TingCard(m_wCurrentUser);
  2261. //构造数据
  2262. CMD_S_SendCard SendCard;
  2263. ZeroMemory(&SendCard, sizeof(SendCard));
  2264. SendCard.wCurrentUser = wCurrentUser;
  2265. SendCard.bTail = bTail;
  2266. SendCard.bLeftCardCount = m_cbLeftCardCount;
  2267. SendCard.cbActionMask = m_cbUserAction[wCurrentUser];
  2268. SendCard.cbCardData = m_cbSendCardData;
  2269. SparrowMaJiang::PB_CS_S_SendCard Card;
  2270. Card.set_wcurrentuser(SendCard.wCurrentUser);
  2271. Card.set_btail(SendCard.bTail);
  2272. Card.set_bleftcardcount(SendCard.bLeftCardCount);
  2273. Card.set_cbactionmask(SendCard.cbActionMask);
  2274. Card.set_cbcarddata(SendCard.cbCardData);
  2275. std::string pbdatas = Card.SerializePartialAsString();
  2276. RepayRecord(INVALID_CHAIR, SUB_S_SEND_CARD, (void*)pbdatas.c_str(), pbdatas.length());
  2277. //发送数据
  2278. for (int i = 0; i < mPlayGameUserCount; i++)
  2279. {
  2280. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2281. {
  2282. continue;
  2283. }
  2284. if (i == m_wCurrentUser)
  2285. {
  2286. //发送给摸牌玩家的数据,附带麻将牌面数据
  2287. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)//先暗杠后补杠牌数据
  2288. SendCard.cbActionCard[j] = GangCardResult.cbCardData[j];
  2289. SendCard.cbCardData = m_cbSendCardData;
  2290. SendCard.cbActionMask = m_cbUserAction[wCurrentUser];
  2291. //m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, &SendCard, sizeof(SendCard));
  2292. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)
  2293. {
  2294. Card.add_cbactioncard(SendCard.cbActionCard[j]);
  2295. }
  2296. Card.set_cbactionmask(SendCard.cbActionMask);
  2297. Card.set_cbcarddata(SendCard.cbCardData);
  2298. std::string pbdata = Card.SerializePartialAsString();
  2299. m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2300. }
  2301. else
  2302. {//发送给其他玩家的数据,没有麻将牌面数据(防止客户端作弊)
  2303. ZeroMemory(SendCard.cbActionCard, sizeof(SendCard.cbActionCard));
  2304. SendCard.cbCardData = 0x00;
  2305. SendCard.cbActionMask = 0x0000;
  2306. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)
  2307. {
  2308. Card.add_cbactioncard(SendCard.cbActionCard[j]);
  2309. }
  2310. Card.set_cbactionmask(SendCard.cbActionMask);
  2311. Card.set_cbcarddata(SendCard.cbCardData);
  2312. std::string pbdata = Card.SerializePartialAsString();
  2313. m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2314. }
  2315. }
  2316. SendCard.cbActionMask = 0;
  2317. SendCard.cbCardData = 0;
  2318. Card.set_cbactionmask(SendCard.cbActionMask);
  2319. Card.set_cbcarddata(SendCard.cbCardData);
  2320. std::string pbdata = Card.SerializePartialAsString();
  2321. //给旁观者的抓牌动作
  2322. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2323. if (m_TabbOutCardCout[m_wCurrentUser] > 0)//有听牌就发一个听牌协议
  2324. {
  2325. HttpTingCard(m_wCurrentUser);
  2326. }
  2327. return true;
  2328. }
  2329. //响应判断
  2330. bool CTableFrameSink_dcs::EstimateUserRespond(WORD wCenterUser, BYTE cbCenterCard, enEstimatKind EstimatKind)
  2331. {
  2332. //财神牌不判断
  2333. if (m_GameLogic.IsMagicCard(cbCenterCard))return false;
  2334. //变量定义
  2335. bool bAroseAction[GAME_PLAYER] = { false };
  2336. bool mbAroseAction = false;
  2337. //吃牌判断,出牌玩家下家位置
  2338. WORD wEatUser = (wCenterUser + 1) % mPlayGameUserCount;
  2339. if (m_bTwoPlayerFlag&&wEatUser == TowMjNullseat)
  2340. {
  2341. wEatUser++;
  2342. }
  2343. //用户状态
  2344. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  2345. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  2346. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  2347. bool bHaveQiangGang = false;
  2348. //动作判断
  2349. for (WORD nUserIndex = 0; nUserIndex < mPlayGameUserCount; nUserIndex++)
  2350. {
  2351. if (m_bTwoPlayerFlag&&nUserIndex == TowMjNullseat)
  2352. {
  2353. continue;
  2354. }
  2355. //用户过滤
  2356. if (wCenterUser == nUserIndex) continue;
  2357. //出牌类型
  2358. if (EstimatKind == EstimatKind_OutCard)
  2359. {
  2360. CChiHuRight Chr;
  2361. BYTE TaiShu = 0;
  2362. int wAction = 0;
  2363. /* wAction = m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[nUserIndex], m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex], cbCenterCard, Chr, TaiShu);
  2364. if (wAction != WIK_NULL)
  2365. {
  2366. m_cbUserAction[nUserIndex] = WIK_CHI_HU;
  2367. if (m_cbOutCardCount == 1 &&(m_wBankerUser&0xff)!=nUserIndex&&mMjType==0)
  2368. {
  2369. m_cbUserAction[nUserIndex] = WIK_DI_CHIHU;
  2370. }
  2371. } */
  2372. //确定只有下家才能吃牌
  2373. if (wEatUser == nUserIndex)
  2374. {
  2375. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimateEatCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2376. }
  2377. //碰牌判断
  2378. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimatePengCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2379. /*if (m_cbUserAction[nUserIndex]& WIK_PENG ||
  2380. m_cbUserAction[nUserIndex] & WIK_DAN_PENG||
  2381. m_cbUserAction[nUserIndex] & WIK_PENG
  2382. )
  2383. {
  2384. if (m_cbLastDisCardData[nUserIndex][m_cbLastDisCount[nUserIndex]]> 0)
  2385. {
  2386. m_cbLastDisCardData[nUserIndex][m_cbLastDisCount[nUserIndex]--]--;
  2387. }
  2388. }*/
  2389. //杠牌判断
  2390. if (m_cbLeftCardCount > 0)
  2391. {
  2392. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimateGangCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2393. }
  2394. }
  2395. if (EstimatKind == EstimatKind_GangCard)
  2396. {
  2397. CChiHuRight Chr;
  2398. BYTE TaiShu = 0;
  2399. //int wAction = 0;
  2400. int GangStatus = m_bUsersGangStatus[wCenterUser];
  2401. BYTE TempCardIndex[MAX_INDEX] = { 0 };
  2402. CopyMemory(TempCardIndex, m_cbCardIndex[nUserIndex], MAX_INDEX);
  2403. //wAction = m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[nUserIndex], m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex], cbCenterCard, Chr, TaiShu, false, GangStatus);
  2404. //////////////////////////////////////////////////////////////////////////
  2405. //优先算 无财神胡
  2406. //////////////////////////////////////////////////////////////////////////
  2407. CGameLogic_dcs TempGameLogic(this);
  2408. BOOL bCanWuMacHu = FALSE;
  2409. TempGameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  2410. TempCardIndex[TempGameLogic.SwitchToCardIndex(cbCenterCard)]++;
  2411. if (TempGameLogic.AnalyseCardNew(TempCardIndex, m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex]))
  2412. {
  2413. TempGameLogic.mSunTaiJiangInColor = TempGameLogic.mJiangInColor;
  2414. int nTai = TempGameLogic.AnalyseCardTaiNum(TempCardIndex, m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex]);
  2415. if (nTai>=3)
  2416. {
  2417. bCanWuMacHu = TRUE;
  2418. }
  2419. }
  2420. TempCardIndex[TempGameLogic.SwitchToCardIndex(cbCenterCard)]--;
  2421. //////////////////////////////////////////////////////////////////////////
  2422. // TempCardIndex[m_GameLogic.SwitchToCardIndex(cbCenterCard)]++;
  2423. std::vector<CanDcsSt> vCards;
  2424. GetMagicCardAndTaiNum(TempCardIndex, nUserIndex, cbCenterCard, vCards);
  2425. if (vCards.size() > 0)
  2426. {
  2427. BYTE TempRecordIndex[MAX_INDEX] = { 0 };
  2428. int caiCardsCount = 0;
  2429. BYTE tmpCardMagicLeftAndRight[MAX_COUNT] = { 0 };
  2430. INT tmpCardMagicLeftAndRightCount = 0;
  2431. BYTE Cards[2] = { 0 };
  2432. if (vCards[0].bDuCanHu)
  2433. {
  2434. Cards[0] = vCards[0].MagicCard|DingDuGao2;
  2435. }
  2436. else
  2437. {
  2438. if (GetCardCanHuWithAll(vCards[0].MagicCard, vCards) && !CardInAll(vCards[0].MagicCard, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  2439. {
  2440. Cards[0] = vCards[0].MagicCard | DingLeftAndRightGao2;
  2441. tmpCardMagicLeftAndRight[tmpCardMagicLeftAndRightCount++] = vCards[0].MagicCard;
  2442. }
  2443. if (vCards[0].MagicCardNext != 0)
  2444. {
  2445. if (GetCardCanHuWithAll(vCards[0].MagicCardNext, vCards) && !CardInAll(vCards[0].MagicCardNext, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  2446. {
  2447. Cards[1] = vCards[0].MagicCardNext | DingLeftAndRightGao2;
  2448. tmpCardMagicLeftAndRight[tmpCardMagicLeftAndRightCount++] = vCards[0].MagicCardNext;
  2449. }
  2450. }
  2451. if (!CardInAll(vCards[0].MagicCard, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  2452. {
  2453. Cards[0] = vCards[0].MagicCard | DingRightGao2;
  2454. }
  2455. if (!CardInAll(vCards[0].MagicCardNext, tmpCardMagicLeftAndRight, tmpCardMagicLeftAndRightCount))
  2456. {
  2457. Cards[1] = vCards[0].MagicCardNext | DingLeftGao2;
  2458. }
  2459. }
  2460. CMD_S_NOTIFY_QIANGGH SNotify;
  2461. if (bCanWuMacHu==FALSE)
  2462. {
  2463. SNotify.caiCards[0] = Cards[0];
  2464. SNotify.caiCards[1] = Cards[1];
  2465. }
  2466. else
  2467. {
  2468. SNotify.caiCards[0] = 0;
  2469. SNotify.caiCards[1] = 0;
  2470. }
  2471. SNotify.cbActionCard = cbCenterCard;
  2472. SNotify.cbActionMask = WIK_Qiang_GANG;
  2473. SNotify.wResumeUser = wCenterUser;
  2474. CopyMemory(&mCmd_NotifyQianggh[nUserIndex], &SNotify, sizeof(CMD_S_NOTIFY_QIANGGH));
  2475. SparrowMaJiang::PB_CS_S_NOTIFY_QIANGGH pQiangGang;
  2476. pQiangGang.set_cbactioncard(SNotify.cbActionCard);
  2477. pQiangGang.set_cbactionmask(SNotify.cbActionMask);
  2478. pQiangGang.set_wresumeuser(SNotify.wResumeUser);
  2479. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2480. {
  2481. pQiangGang.add_caicards(SNotify.caiCards[j]);
  2482. }
  2483. std::string pbdate = pQiangGang.SerializePartialAsString();
  2484. m_pITableFrame->SendTableData(nUserIndex, SUB_S_NOTIFY_QIANGGH, (void*)pbdate.c_str(), pbdate.length());
  2485. bHaveQiangGang = true;
  2486. m_cbUserAction[nUserIndex] = WIK_Qiang_GANG;
  2487. }
  2488. // if (wAction&WIK_ZI_MO)
  2489. // {
  2490. // m_cbUserAction[nUserIndex] |= WIK_ZI_MO;
  2491. // }
  2492. }
  2493. //结果判断
  2494. if (m_cbUserAction[nUserIndex] != WIK_NULL)
  2495. {
  2496. bAroseAction[nUserIndex] = true;
  2497. if (m_cbUserAction[nUserIndex] & (WIK_PENG | WIK_CHI_HU | WIK_PENG_PENG))
  2498. {
  2499. BYTE bTemp = 0;
  2500. //记忆牌有多少张
  2501. for (BYTE j = 0; j < m_cbLastDisCount[nUserIndex]; j++)
  2502. {
  2503. //如果在一圈中 记忆1个一样的牌 则不能操作
  2504. if (m_cbLastDisCardData[nUserIndex][j] == cbCenterCard)
  2505. {
  2506. m_cbUserAction[nUserIndex] = m_cbUserAction[nUserIndex] & (~(WIK_PENG | WIK_CHI_HU | WIK_PENG_PENG));
  2507. if (m_cbUserAction[nUserIndex] == WIK_NULL)
  2508. bAroseAction[nUserIndex] = false;
  2509. }
  2510. }
  2511. }
  2512. }
  2513. }
  2514. for (int nUserIndex = 0; nUserIndex < mPlayGameUserCount; nUserIndex++)
  2515. {
  2516. if (m_bTwoPlayerFlag&&nUserIndex == TowMjNullseat)
  2517. {
  2518. continue;
  2519. }
  2520. if (bAroseAction[nUserIndex] == true)
  2521. {
  2522. mbAroseAction = true;
  2523. break;
  2524. }
  2525. }
  2526. //结果处理
  2527. if (mbAroseAction == true && bHaveQiangGang == FALSE)
  2528. {
  2529. //设置变量
  2530. m_wProvideUser = wCenterUser;
  2531. m_cbProvideCard = cbCenterCard;
  2532. m_wResumeUser = m_wCurrentUser;
  2533. m_wCurrentUser = INVALID_CHAIR;
  2534. //发送提示
  2535. SendOperateNotify();
  2536. return true;
  2537. }
  2538. if (bHaveQiangGang)
  2539. {
  2540. m_wProvideUser = wCenterUser;
  2541. m_cbProvideCard = cbCenterCard;
  2542. m_wResumeUser = m_wCurrentUser;
  2543. m_wCurrentUser = INVALID_CHAIR;
  2544. return true;
  2545. }
  2546. return false;
  2547. }
  2548. //胡的这张牌 牌堆里面还有几张
  2549. //计算方式 服务器上剩余里面的牌,+其他三位位玩家手牌= 该胡牌个数
  2550. BYTE CTableFrameSink_dcs::RemainNum(WORD wChairId, const BYTE m_cbCard, BYTE cbOutCardIndex)
  2551. {
  2552. BYTE m_cbNum = 0;
  2553. BYTE mCard[MAX_INDEX] = { 0 }; //把所有当前用户可以看到的牌 都扔到这个数组中
  2554. BYTE TempIndex = m_GameLogic.SwitchToCardIndex(m_cbCard);
  2555. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  2556. {
  2557. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2558. {
  2559. continue;
  2560. }
  2561. for (BYTE j = 0; j < m_cbDiscardCount[i]; j++)//丢弃数
  2562. {
  2563. mCard[m_GameLogic.SwitchToCardIndex(m_cbDiscardCard[i][j])]++;
  2564. }
  2565. for (BYTE k = 0; k < m_cbWeaveItemCount[i]; k++)//摆出来的牌
  2566. {
  2567. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_PENG)
  2568. {
  2569. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 3;
  2570. }
  2571. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_LEFT)
  2572. {
  2573. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2574. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 1)]++;
  2575. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 2)]++;
  2576. }
  2577. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_RIGHT)
  2578. {
  2579. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2580. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 1)]++;
  2581. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 2)]++;
  2582. }
  2583. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_CENTER)
  2584. {
  2585. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2586. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 1)]++;
  2587. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 1)]++;
  2588. }
  2589. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_MING_GANG || (i == wChairId&&m_WeaveItemArray[i][k].cbWeaveKind == WIK_AN_GANG))
  2590. {
  2591. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 4;
  2592. }
  2593. if (m_WeaveItemArray[i][k].cbWeaveKind& (WIK_SHUANG_CAICHI | WIK_SHUANG_PENG | WIK_DAN_CHI))
  2594. {
  2595. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2596. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2597. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2598. }
  2599. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_PENG)
  2600. {
  2601. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 2;
  2602. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2603. }
  2604. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_AN_GANG))
  2605. {
  2606. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 3;
  2607. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2608. }
  2609. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_SHUANG_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_SHUANG_AN_GANG))
  2610. {
  2611. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 2;
  2612. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2613. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2614. }
  2615. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_SAN_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_SAN_AN_GANG))
  2616. {
  2617. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 1;
  2618. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2619. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2620. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[2])]++;
  2621. }
  2622. if (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_QUANG_AN_GANG)
  2623. {
  2624. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2625. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2626. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[2])]++;
  2627. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[3])]++;
  2628. }
  2629. if (m_WeaveItemArray[i][k].cbWeaveKind & (WIK_BU_GANG | WIK_DAN_BU_GANG))
  2630. {
  2631. for (int m = 0; m < 4; m++)
  2632. {
  2633. if (m_WeaveItemArray[i][k].cbMargicOffset[m] != 0)
  2634. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[m])]++;
  2635. else
  2636. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] ++;
  2637. }
  2638. }
  2639. }
  2640. }
  2641. //8个财神变7个 在加回来一个
  2642. //非包麻将 需要计算翻财神的那张牌
  2643. BYTE cbMagicFirstIndex = m_GameLogic.SwitchToCardIndex(m_cbMagicFirstData);
  2644. if (mCard[cbMagicFirstIndex] < 4)
  2645. {
  2646. mCard[cbMagicFirstIndex]++;
  2647. }
  2648. //非包麻将 不需要把财神那张牌加入落地牌
  2649. //增加自己假设去掉的牌 这样才真正的标示 牌桌加手牌
  2650. mCard[cbOutCardIndex]++;
  2651. for (BYTE i = 0; i < MAX_INDEX; i++)
  2652. {
  2653. mCard[i] += m_cbCardIndex[wChairId][i];
  2654. }
  2655. m_cbNum = 4 - mCard[TempIndex];
  2656. ASSERT(m_cbNum >= 0 && m_cbNum <= 4);
  2657. if (m_cbNum < 0)m_cbNum = 0;
  2658. return m_cbNum;
  2659. }
  2660. //对手牌遍历,并把该牌减去,然后分析这13张拍能胡什么
  2661. bool CTableFrameSink_dcs::TingCard(WORD wChairID)
  2662. {
  2663. m_PaiQuan[wChairID] = 0;
  2664. m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数
  2665. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  2666. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  2667. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  2668. BYTE WilEnumCard[MAX_INDEX] = { 0 };
  2669. m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], WilEnumCard);
  2670. for (BYTE i = 0; i < MAX_INDEX; i++)
  2671. {
  2672. if (m_cbCardIndex[wChairID][i] == 0)continue;
  2673. if (--m_cbCardIndex[wChairID][i] < 0){ ASSERT(false); return false; }
  2674. //if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID],FanHui))
  2675. //{
  2676. m_TabbOutCardData[wChairID][m_TabbOutCardCout[wChairID]] = m_GameLogic.SwitchToCardData(i);
  2677. BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1
  2678. BYTE m_cbTingParCount = 0; //听牌数据
  2679. if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, WilEnumCard, wChairID))
  2680. {
  2681. for (BYTE j = 0; j < MAX_INDEX; j++)
  2682. {
  2683. if (m_cbTingPai[j] > 0)
  2684. {
  2685. if (m_cbTingParCount == 19)
  2686. {
  2687. m_cbTingParCount++;
  2688. break;
  2689. }
  2690. m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j);
  2691. //计算所胡的这张牌 还剩余几张
  2692. BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1], i);
  2693. m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, m_cbTingPai[j], m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1]);
  2694. }
  2695. }
  2696. if (m_cbTingParCount == 20)
  2697. {
  2698. m_TabbTingCardCount[wChairID][m_TabbOutCardCout[wChairID]] = 255;
  2699. ZeroMemory(m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]], m_cbTingParCount);
  2700. }
  2701. else
  2702. m_TabbTingCardCount[wChairID][m_TabbOutCardCout[wChairID]] = m_cbTingParCount;
  2703. }
  2704. if (m_cbTingParCount > 0)
  2705. m_TabbOutCardCout[wChairID]++;
  2706. else{ m_TabbOutCardData[wChairID][m_TabbOutCardCout[wChairID]] = 0; }
  2707. //}
  2708. m_cbCardIndex[wChairID][i]++;
  2709. }
  2710. return true;
  2711. }
  2712. bool CTableFrameSink_dcs::OutTingCard(WORD wChairID, BYTE cardIndex)
  2713. {
  2714. m_PaiQuan[wChairID] = 1;
  2715. m_TabbOutCardCout[wChairID] = 1; //可以打出的牌就听牌的个数,当打出牌已经完成,默认255不存在
  2716. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  2717. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  2718. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  2719. BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1
  2720. BYTE m_cbTingParCount = 0;//听牌数据
  2721. BYTE FanHui[MAX_INDEX] = { 0 };
  2722. m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], FanHui);
  2723. if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, FanHui, wChairID))
  2724. {
  2725. for (BYTE j = 0; j < MAX_INDEX; j++)
  2726. {
  2727. if (m_cbTingPai[j] > 0)
  2728. {
  2729. if (m_cbTingParCount == 19)
  2730. {
  2731. m_cbTingParCount++;
  2732. break;
  2733. }
  2734. m_TabbTingCardData[wChairID][0][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j);
  2735. //用户ID
  2736. BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1], cardIndex);
  2737. m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, m_cbTingPai[j], m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1]);
  2738. }
  2739. }
  2740. if (m_cbTingParCount == 20)
  2741. {
  2742. m_TabbTingCardCount[wChairID][0] = 255;
  2743. ZeroMemory(m_TabbTingCardData[wChairID][0], m_cbTingParCount);
  2744. }
  2745. else
  2746. {
  2747. m_TabbTingCardCount[wChairID][0] = m_cbTingParCount;
  2748. }
  2749. return true;
  2750. }
  2751. return false;
  2752. }
  2753. void CTableFrameSink_dcs::HttpTingCard(WORD wChairID)
  2754. {
  2755. CMD_S_TingCard strTingCard;
  2756. ZeroMemory(&strTingCard, sizeof(strTingCard));
  2757. strTingCard.bPaiQuan = m_PaiQuan[wChairID];
  2758. strTingCard.bOutCardCout = m_TabbOutCardCout[wChairID];
  2759. CopyMemory(strTingCard.bOutCardData, m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID]));
  2760. CopyMemory(strTingCard.bTingCardCount, m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID]));
  2761. CopyMemory(strTingCard.bTingCardData, m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID]));
  2762. SparrowMaJiang::PB_CS_S_TingCard Card;
  2763. Card.set_bpaiquan(strTingCard.bPaiQuan);
  2764. Card.set_boutcardcout(strTingCard.bOutCardCout);
  2765. for (BYTE j = 0; j < strTingCard.bOutCardCout; j++)
  2766. {
  2767. Card.add_boutcarddata(strTingCard.bOutCardData[j]);
  2768. }
  2769. for (BYTE j = 0; j < strTingCard.bOutCardCout; j++)
  2770. {
  2771. Card.add_btingcardcount(strTingCard.bTingCardCount[j]);
  2772. }
  2773. for (BYTE i = 0; i < strTingCard.bOutCardCout; i++)
  2774. {
  2775. SparrowMaJiang::pb_bTingCardData* CardData = Card.add_btingcarddata();
  2776. for (BYTE j = 0; j < strTingCard.bTingCardCount[i]; j++)
  2777. {
  2778. CardData->add_btingcarddatas(strTingCard.bTingCardData[i][j]);
  2779. }
  2780. }
  2781. std::string pbdata = Card.SerializePartialAsString();
  2782. m_pITableFrame->SendTableData(wChairID, SUB_S_TING_CARD, (void*)pbdata.c_str(), pbdata.length());
  2783. }
  2784. void CTableFrameSink_dcs::HttpOperateResult(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard, int cbActionMask, WORD cbActionCard[6])
  2785. {
  2786. if (cbOperateCode & WIK_GANG_GANG)
  2787. {//构造结果
  2788. CMD_S_OperateResult OperateResult;
  2789. memset(&OperateResult, 0, sizeof(OperateResult));
  2790. OperateResult.wOperateUser = wChairID;
  2791. OperateResult.wProvideUser = wChairID;
  2792. OperateResult.cbOperateCode = cbOperateCode;
  2793. OperateResult.cbOperateCard = cbOperateCard;
  2794. CopyMemory(OperateResult.cbCaiShenCard, cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2795. OperateResult.cbActionMask = cbActionMask;
  2796. CopyMemory(OperateResult.cbActionCard, cbActionCard, sizeof(OperateResult.cbActionCard));
  2797. SparrowMaJiang::PB_CS_S_OperateResult Result;
  2798. Result.set_woperateuser(OperateResult.wOperateUser);
  2799. Result.set_cboperatecard(OperateResult.cbOperateCard);
  2800. Result.set_cboperatecode(OperateResult.cbOperateCode);
  2801. Result.set_wprovideuser(OperateResult.wProvideUser);
  2802. for (BYTE j = 0; j < 4; j++)
  2803. {
  2804. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2805. }
  2806. Result.set_cbactionmask(OperateResult.cbActionMask);
  2807. for (BYTE j = 0; j < 6; j++)
  2808. {
  2809. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  2810. }
  2811. //发送数据
  2812. std::string pbdata = Result.SerializePartialAsString();
  2813. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2814. //发送消息
  2815. m_pITableFrame->SendTableData(wChairID, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2816. ZeroMemory(OperateResult.cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2817. for (BYTE j = 0; j < 4; j++)
  2818. {
  2819. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2820. }
  2821. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  2822. {
  2823. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2824. {
  2825. continue;
  2826. }
  2827. if (i == wChairID)continue;
  2828. //发送消息
  2829. m_pITableFrame->SendTableData(i, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2830. }
  2831. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2832. }
  2833. else
  2834. {
  2835. CMD_S_OperateResult OperateResult;
  2836. memset(&OperateResult, 0, sizeof(OperateResult));
  2837. OperateResult.wOperateUser = wChairID;
  2838. OperateResult.wProvideUser = m_wProvideUser;
  2839. if (cbOperateCode &(WIK_DAN_BU_GANG | WIK_BU_GANG))
  2840. OperateResult.wProvideUser = wChairID;
  2841. OperateResult.cbOperateCode = cbOperateCode;
  2842. OperateResult.cbOperateCard = cbOperateCard;
  2843. CopyMemory(OperateResult.cbCaiShenCard, cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2844. OperateResult.cbActionMask = cbActionMask;
  2845. CopyMemory(OperateResult.cbActionCard, cbActionCard, sizeof(OperateResult.cbActionCard));
  2846. SparrowMaJiang::PB_CS_S_OperateResult Result;
  2847. Result.set_woperateuser(OperateResult.wOperateUser);
  2848. Result.set_cboperatecard(OperateResult.cbOperateCard);
  2849. Result.set_cboperatecode(OperateResult.cbOperateCode);
  2850. Result.set_wprovideuser(OperateResult.wProvideUser);
  2851. for (BYTE j = 0; j < 4; j++)
  2852. {
  2853. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2854. }
  2855. Result.set_cbactionmask(OperateResult.cbActionMask);
  2856. for (BYTE j = 0; j < 6; j++)
  2857. {
  2858. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  2859. }
  2860. //发送数据
  2861. std::string pbdata = Result.SerializePartialAsString();
  2862. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2863. //发送消息
  2864. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2865. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2866. }
  2867. }
  2868. BYTE CTableFrameSink_dcs::GetNextMagicCardData(BYTE cbMagicCardFirstData)
  2869. {
  2870. BYTE TmpCardData = 0;
  2871. BYTE HuaSe = m_GameLogic.GetCardColor(cbMagicCardFirstData);
  2872. switch (HuaSe)
  2873. {
  2874. case 0:
  2875. case 1:
  2876. case 2:
  2877. {
  2878. if ((cbMagicCardFirstData & MASK_VALUE) == 0x09)
  2879. {
  2880. TmpCardData = (cbMagicCardFirstData & MASK_COLOR) | 0x01;
  2881. }
  2882. else
  2883. {
  2884. TmpCardData = cbMagicCardFirstData + 1;
  2885. }
  2886. break;
  2887. }
  2888. case 3:
  2889. {
  2890. if ((cbMagicCardFirstData & MASK_VALUE) == 0x04)
  2891. {
  2892. TmpCardData = (cbMagicCardFirstData & MASK_COLOR) | 0x01;
  2893. }
  2894. else if ((cbMagicCardFirstData & MASK_VALUE) == 0x07)
  2895. {
  2896. TmpCardData = cbMagicCardFirstData - 2;
  2897. }
  2898. else
  2899. {
  2900. TmpCardData = cbMagicCardFirstData + 1;
  2901. }
  2902. break;
  2903. }
  2904. default:
  2905. {
  2906. ASSERT(false);
  2907. break;
  2908. }
  2909. }
  2910. return TmpCardData;
  2911. }
  2912. BYTE CTableFrameSink_dcs::GetLastMagicCardData(BYTE cbMagicCardFirstIndex)
  2913. {
  2914. BYTE TmpCardData = 0;
  2915. BYTE HuaSe = m_GameLogic.GetCardColor(cbMagicCardFirstIndex);
  2916. switch (HuaSe)
  2917. {
  2918. case 0:
  2919. case 1:
  2920. case 2:
  2921. {
  2922. if ((cbMagicCardFirstIndex & MASK_VALUE) == 0x01)
  2923. {
  2924. TmpCardData = (cbMagicCardFirstIndex & MASK_COLOR) | 0x09;
  2925. }
  2926. else
  2927. {
  2928. TmpCardData = cbMagicCardFirstIndex - 1;
  2929. }
  2930. break;
  2931. }
  2932. case 3:
  2933. {
  2934. if ((cbMagicCardFirstIndex & MASK_VALUE) == 0x01)
  2935. {
  2936. TmpCardData = (cbMagicCardFirstIndex & MASK_COLOR) | 0x04;
  2937. }
  2938. else if ((cbMagicCardFirstIndex & MASK_VALUE) == 0x05)
  2939. {
  2940. TmpCardData = cbMagicCardFirstIndex + 2;
  2941. }
  2942. else
  2943. {
  2944. TmpCardData = cbMagicCardFirstIndex - 1;
  2945. }
  2946. break;
  2947. }
  2948. default:
  2949. {
  2950. ASSERT(false);
  2951. break;
  2952. }
  2953. }
  2954. return TmpCardData;
  2955. }
  2956. void CTableFrameSink_dcs::FanMagicCaculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score)
  2957. {
  2958. int tmpScorTai = 1;
  2959. if (nTai >= 3)
  2960. {
  2961. tmpScorTai = nTai - 2;
  2962. }
  2963. switch (WinWay)
  2964. {
  2965. case win_qianggang:{
  2966. WinQiangGang_Score(WinChairID, tmpScorTai, WinWay, provideUserID, chr, cmd_Score);
  2967. break;
  2968. }
  2969. case Win_ZiMo:{
  2970. WinFanMagic_ZiMo_Score(WinChairID, tmpScorTai, WinWay, provideUserID, cmd_Score);
  2971. break;
  2972. }
  2973. case win_DiHu:{
  2974. WinFanMagic_DiHu_Score(WinChairID, tmpScorTai, WinWay, provideUserID, cmd_Score);
  2975. break;
  2976. }
  2977. default:
  2978. break;
  2979. }
  2980. }
  2981. /*
  2982. int TempInfoScore = 0;
  2983. int nFengDingNum = m_gameConfig.wDiScore*pow(2, mMaxTaiNum);
  2984. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  2985. {
  2986. if (i == WinChairID)continue;
  2987. LianXuHuPai[i] = 0;
  2988. if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  2989. {
  2990. cmd_Score.lGangScore[i] -= nFengDingNum;
  2991. }
  2992. else {
  2993. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore *pow(2, nTai);
  2994. }
  2995. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2996. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2997. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2998. TempInfoScore -= cmd_Score.lGangScore[i];
  2999. }
  3000. cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  3001. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3002. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3003. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  3004. */
  3005. void CTableFrameSink_dcs::WinQiangGang_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score)
  3006. {
  3007. //计算4家积分变动 输家 同时包赔3家的
  3008. int TempInfoScore = 0;
  3009. int nFengDingNum = m_gameConfig.wDiScore*pow(2, mMaxTaiNum-2); //32
  3010. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  3011. {
  3012. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  3013. {
  3014. continue;
  3015. }
  3016. if (i == WinChairID)continue;
  3017. LianXuHuPai[i] = 0;
  3018. if (i == m_wProvideUser)
  3019. {
  3020. int nOneUserScore = 0;
  3021. if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  3022. {
  3023. nOneUserScore -= nFengDingNum;
  3024. }
  3025. else {
  3026. nOneUserScore -= m_gameConfig.wDiScore *pow(2, nTai);
  3027. }
  3028. cmd_Score.lGangScore[i] += nOneUserScore;
  3029. TempInfoScore -= nOneUserScore;
  3030. }
  3031. else
  3032. {
  3033. int nOneUserScore = 0;
  3034. if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  3035. {
  3036. nOneUserScore -= nFengDingNum;
  3037. }
  3038. else {
  3039. nOneUserScore -= (m_gameConfig.wDiScore*pow(2, nTai));
  3040. }
  3041. cmd_Score.lGangScore[provideUserID] += nOneUserScore;
  3042. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  3043. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  3044. TempInfoScore -= nOneUserScore;
  3045. }
  3046. }
  3047. m_lGameScore[m_wProvideUser] += cmd_Score.lGangScore[m_wProvideUser];
  3048. m_lGameTatolScore[m_wProvideUser] += cmd_Score.lGangScore[m_wProvideUser];
  3049. cmd_Score.cbWanJiaScore[m_wProvideUser] = m_lGameTatolScore[m_wProvideUser];
  3050. cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  3051. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3052. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3053. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  3054. }
  3055. //
  3056. //void CTableFrameSink_dcs::WinFanMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score)
  3057. //{
  3058. // int TempInfoScore = 0;
  3059. // int nFengDingNum = m_gameConfig.wDiScore*pow(2, mMaxTaiNum);
  3060. // for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  3061. // {
  3062. // if (i == WinChairID)continue;
  3063. // LianXuHuPai[i] = 0;
  3064. // if (i == m_wProvideUser)
  3065. // {
  3066. // if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  3067. // {
  3068. // cmd_Score.lGangScore[i] -= nFengDingNum;
  3069. // }
  3070. // else {
  3071. // cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore *pow(2, nTai);
  3072. // }
  3073. //
  3074. //
  3075. // m_lGameScore[i] += cmd_Score.lGangScore[i];
  3076. // m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  3077. // cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  3078. // }
  3079. // else
  3080. // {
  3081. // if (m_gameConfig.wDiScore *pow(2, nTai) / 2 >= nFengDingNum)
  3082. // {
  3083. // cmd_Score.lGangScore[i] -= nFengDingNum;
  3084. // }
  3085. // else {
  3086. // cmd_Score.lGangScore[i] -= (m_gameConfig.wDiScore*pow(2, nTai) / 2);
  3087. // }
  3088. // m_lGameScore[i] += cmd_Score.lGangScore[i];
  3089. // m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  3090. // cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  3091. // }
  3092. // TempInfoScore -= cmd_Score.lGangScore[i];
  3093. // }
  3094. // cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  3095. // m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3096. // m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3097. // cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  3098. //}
  3099. //
  3100. //void CTableFrameSink_dcs::WinFangMagic_FangPao_QingYiSe_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight Userchr, CMD_S_GangScore& cmd_Score)
  3101. //{
  3102. // int ProvideUserHaveTwoTai=false;
  3103. // for (int i = 0; i < MAX_INDEX;i++)
  3104. // {
  3105. // CChiHuRight chr;
  3106. // BYTE nTaiShu=0;
  3107. // int TempAction;
  3108. // TempAction = m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[provideUserID], m_WeaveItemArray[provideUserID],
  3109. // m_cbWeaveItemCount[provideUserID], m_GameLogic.SwitchToCardData(i), chr, nTaiShu);
  3110. // if (TempAction!=WIK_NULL&&nTaiShu>2)
  3111. // {
  3112. // ProvideUserHaveTwoTai = true;
  3113. // break;
  3114. // }
  3115. // if (TempAction!=WIK_NULL&&nTaiShu==2)
  3116. // {
  3117. // if (TempAction&ZJ_TAI_WuMagic)
  3118. // {
  3119. // continue;
  3120. // }
  3121. // else
  3122. // {
  3123. // ProvideUserHaveTwoTai = true;
  3124. // break;
  3125. // }
  3126. // }
  3127. // }
  3128. //
  3129. // if (ProvideUserHaveTwoTai)
  3130. // {
  3131. // WinFanMagic_FangPao_Score(WinChairID, nTai, WinWay, provideUserID, Userchr, cmd_Score);
  3132. // }
  3133. // else
  3134. // {
  3135. // //计算4家积分变动 输家 同时包赔3家的
  3136. // int TempInfoScore = 0;
  3137. // int nFengDingNum = m_gameConfig.wDiScore*pow(2, mMaxTaiNum); //32
  3138. // for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  3139. // {
  3140. // if (i == WinChairID)continue;
  3141. // LianXuHuPai[i] = 0;
  3142. // if (i == m_wProvideUser)
  3143. // {
  3144. // int nOneUserScore = 0;
  3145. // if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  3146. // {
  3147. // nOneUserScore -= nFengDingNum;
  3148. // }
  3149. // else {
  3150. // nOneUserScore -= m_gameConfig.wDiScore *pow(2, nTai);
  3151. // }
  3152. // cmd_Score.lGangScore[i] += nOneUserScore;
  3153. // TempInfoScore -= nOneUserScore;
  3154. // }
  3155. // else
  3156. // {
  3157. // int nOneUserScore = 0;
  3158. // if (m_gameConfig.wDiScore *pow(2, nTai) / 2 >= nFengDingNum)
  3159. // {
  3160. // nOneUserScore -= nFengDingNum;
  3161. // }
  3162. // else {
  3163. // nOneUserScore -= (m_gameConfig.wDiScore*pow(2, nTai) / 2);
  3164. //
  3165. // }
  3166. // cmd_Score.lGangScore[provideUserID] += nOneUserScore;
  3167. //
  3168. //
  3169. // m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  3170. // cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  3171. // TempInfoScore -= nOneUserScore;
  3172. // }
  3173. //
  3174. // }
  3175. //
  3176. // m_lGameScore[m_wProvideUser] += cmd_Score.lGangScore[m_wProvideUser];
  3177. // m_lGameTatolScore[m_wProvideUser] += cmd_Score.lGangScore[m_wProvideUser];
  3178. // cmd_Score.cbWanJiaScore[m_wProvideUser] = m_lGameTatolScore[m_wProvideUser];
  3179. //
  3180. // cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  3181. // m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3182. // m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3183. // cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  3184. // }
  3185. //
  3186. //}
  3187. void CTableFrameSink_dcs::WinFanMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score)
  3188. {
  3189. int TempInfoScore = 0;
  3190. int nFengDingNum = m_gameConfig.wDiScore*pow(2, mMaxTaiNum-2);
  3191. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  3192. {
  3193. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  3194. {
  3195. continue;
  3196. }
  3197. if (i == WinChairID)continue;
  3198. LianXuHuPai[i] = 0;
  3199. if (m_gameConfig.wDiScore *pow(2, nTai) >= nFengDingNum)
  3200. {
  3201. cmd_Score.lGangScore[i] -= nFengDingNum;
  3202. }
  3203. else {
  3204. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore *pow(2, nTai);
  3205. }
  3206. m_lGameScore[i] += cmd_Score.lGangScore[i];
  3207. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  3208. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  3209. TempInfoScore -= cmd_Score.lGangScore[i];
  3210. }
  3211. cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  3212. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3213. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  3214. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  3215. }
  3216. void CTableFrameSink_dcs::WinFanMagic_DiHu_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score)
  3217. {
  3218. WinFanMagic_ZiMo_Score(WinChairID, nTai, WinWay, provideUserID, cmd_Score);
  3219. }
  3220. void CTableFrameSink_dcs::CaculationScore(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight UserChr, CMD_S_GangScore& cmd_Score)
  3221. {
  3222. FanMagicCaculation(WinChairID, nTai, WinWay, provideUserID, UserChr, cmd_Score);
  3223. }
  3224. void CTableFrameSink_dcs::WritePaiCardData(TCHAR* TableId, int count)
  3225. {
  3226. if (!mBWriteTableData)
  3227. {
  3228. return;
  3229. }
  3230. SYSTEMTIME stTime;
  3231. GetLocalTime(&stTime);
  3232. CString sTimerDir;
  3233. sTimerDir.Format(_T("%d月%d日-%d时"), stTime.wMonth, stTime.wDay, stTime.wHour);
  3234. CString strFileName;
  3235. if (mTableDatastrPath.IsEmpty())
  3236. {
  3237. strFileName.Format(_T("TableData\\%s\\Table_%s_%d.dat"), TableId, sTimerDir.GetBuffer(), count);
  3238. }
  3239. else
  3240. {
  3241. strFileName.Format(_T("%s\\TableData\\%s\\Table_%s_%d.dat"), mTableDatastrPath.GetBuffer(), sTimerDir.GetBuffer(), TableId, count);
  3242. }
  3243. CString strCreate;
  3244. strCreate = mTableDatastrPath;
  3245. PathAppend(strCreate.GetBufferSetLength(MAX_PATH), _T("\\TableData"));
  3246. strCreate.ReleaseBuffer();
  3247. if (!PathFileExists(strCreate.GetBuffer()))
  3248. {
  3249. CreateDirectory(strCreate.GetBuffer(), NULL);
  3250. }
  3251. PathAppend(strCreate.GetBufferSetLength(MAX_PATH), sTimerDir.GetBuffer());
  3252. strCreate.ReleaseBuffer();
  3253. if (!PathFileExists(strCreate.GetBuffer()))
  3254. {
  3255. CreateDirectory(strCreate.GetBuffer(), NULL);
  3256. }
  3257. HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_NEW, NULL, NULL);
  3258. if (hFile != INVALID_HANDLE_VALUE)
  3259. {
  3260. DWORD dwWrite;
  3261. WriteFile(hFile, m_cbRepertoryCard, m_cbTotalCardCount, &dwWrite, NULL);
  3262. CloseHandle(hFile);
  3263. }
  3264. }
  3265. void CTableFrameSink_dcs::ReadGameData()
  3266. {
  3267. CString strFileName;
  3268. strFileName = _T("Table.dat");
  3269. if (!PathFileExists(_T("Table.dat")))
  3270. {
  3271. return;
  3272. }
  3273. HANDLE hFile = CreateFile(strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL);
  3274. if (hFile != INVALID_HANDLE_VALUE)
  3275. {
  3276. DWORD dwRead;
  3277. DWORD dwFileSize;
  3278. DWORD fileSize = GetFileSize(hFile, &dwFileSize);
  3279. if (fileSize != m_cbTotalCardCount)
  3280. {
  3281. CloseHandle(hFile);
  3282. return;
  3283. }
  3284. SetFilePointer(hFile, 0, 0, FILE_BEGIN);
  3285. //BYTE tmpCard[MAX_REPERTORY_ZJ] = { 0 };
  3286. ReadFile(hFile, m_cbRepertoryCard, m_cbTotalCardCount, &dwRead, NULL);
  3287. CloseHandle(hFile);
  3288. /* for (BYTE i = 0; i < MAX_REPERTORY_ZJ; i++)
  3289. {
  3290. ASSERT(i < MAX_REPERTORY_ZJ);
  3291. m_cbRepertoryCard[i] = tmpCard[MAX_REPERTORY_ZJ - i - 1];
  3292. }
  3293. */
  3294. }
  3295. }
  3296. //打印玩家所有积分
  3297. void CTableFrameSink_dcs::PrintUsersScore(LPCTSTR lpstrInfo)
  3298. {
  3299. //OutputDebugString(lpstrInfo);
  3300. CString strInfo;
  3301. for (int i = 0; i < mPlayGameUserCount; i++)
  3302. {
  3303. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  3304. {
  3305. continue;
  3306. }
  3307. CString strTmp;
  3308. strTmp.Format(_T("UserID =%d 本次变更积分 %d 本局剩余拥有积分%d"),
  3309. i, m_lGameScore[i], m_lGameTatolScore[i]);
  3310. //OutputDebugString(strTmp);
  3311. }
  3312. }
  3313. bool CTableFrameSink_dcs::UserDingMagicCard(WORD wChairID)
  3314. {
  3315. //获取玩家手牌
  3316. //获取玩家已经吃碰的牌
  3317. //将吃碰的牌 在手牌中删除。
  3318. //将手牌作为财神 进行判断 是否可以胡牌
  3319. //m_cbCardIndex[wTargetUser], m_WeaveItemArray[wTargetUser],
  3320. // m_cbWeaveItemCount[wTargetUser],
  3321. BYTE tmpRecordDcsCars[MAX_COUNT] = { 0 };
  3322. BYTE tmpRecordDscCardsOld[MAX_COUNT] = { 0 };
  3323. int nRecordCount = 0;
  3324. BYTE TempUserCards[MAX_INDEX] = { 0 };
  3325. CopyMemory(TempUserCards, m_cbCardIndex[wChairID], MAX_INDEX);
  3326. BYTE WeaveCards[MAX_COUNT] = { 0 };
  3327. int nCount = 0;
  3328. GetOneWeaveItemCards(m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], WeaveCards, nCount);
  3329. for (int i = 0; i < nCount; i++)
  3330. {
  3331. int nIndex = m_GameLogic.SwitchToCardIndex(WeaveCards[i]);
  3332. TempUserCards[nIndex] = 0;
  3333. }
  3334. //减去手牌中定财神 与 Weave冲突的牌。
  3335. //计算2次 第一次 计算独财神 第二次 计算连续财神
  3336. for (int i = 0; i < MAX_INDEX; i++)//第一次循环 把所有能够读财神的记录了。
  3337. {
  3338. if (TempUserCards[i] == 0)
  3339. {
  3340. continue;
  3341. }
  3342. TempUserCards[i] = 0;
  3343. CGameLogic_dcs TempGameLogic(this);
  3344. BYTE cbCard = TempGameLogic.SwitchToCardData(i);
  3345. if (CardInCardArray(cbCard, WeaveCards, nCount))
  3346. {
  3347. continue;
  3348. }
  3349. TempGameLogic.SetMagicIndex(TempGameLogic.SwitchToCardIndex(cbCard), MAX_INDEX);
  3350. BYTE TaiShu = 0;
  3351. // BYTE TempAction = TempGameLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID],
  3352. // m_cbWeaveItemCount[wChairID], NULL, chr, TaiShu);
  3353. if (TempGameLogic.AnalyseCardNew(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3354. {
  3355. TempGameLogic.mSunTaiJiangInColor = TempGameLogic.mJiangInColor;
  3356. TaiShu = TempGameLogic.AnalyseCardTaiNum(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]);
  3357. }
  3358. if (TaiShu >= DingMagicMinTai)
  3359. {
  3360. tmpRecordDcsCars[nRecordCount] = cbCard;
  3361. tmpRecordDscCardsOld[nRecordCount] = cbCard;
  3362. tmpRecordDcsCars[nRecordCount] |= 0x80;
  3363. nRecordCount++;
  3364. }
  3365. }
  3366. //把手牌中已经能够独财胡的 左右2张牌都干掉。
  3367. for (size_t i = 0; i < nRecordCount; i++)
  3368. {
  3369. BYTE cbCard = GetNextMagicCardData(tmpRecordDscCardsOld[i]);
  3370. if (TempUserCards[m_GameLogic.SwitchToCardIndex(cbCard)]>0)
  3371. {
  3372. TempUserCards[m_GameLogic.SwitchToCardIndex(cbCard)] = 0;
  3373. tmpRecordDcsCars[nRecordCount] = cbCard;
  3374. tmpRecordDscCardsOld[nRecordCount] = cbCard;
  3375. nRecordCount++;
  3376. }
  3377. cbCard = GetLastMagicCardData(tmpRecordDscCardsOld[i]);
  3378. if (TempUserCards[m_GameLogic.SwitchToCardIndex(cbCard)] > 0)
  3379. {
  3380. TempUserCards[m_GameLogic.SwitchToCardIndex(cbCard)] = 0;
  3381. tmpRecordDcsCars[nRecordCount] = cbCard;
  3382. tmpRecordDscCardsOld[nRecordCount] = cbCard;
  3383. nRecordCount++;
  3384. }
  3385. }
  3386. //在手牌中 寻找连续的2张牌 进行胡牌判断
  3387. std::vector<CaiCards> TmpCards;
  3388. GetLianXuCards(TempUserCards, TmpCards);
  3389. for (int i = 0; i < TmpCards.size(); i++)
  3390. {
  3391. CGameLogic_dcs TempGameLogic(this);
  3392. TempGameLogic.SetMagicIndex(TempGameLogic.SwitchToCardIndex(TmpCards[i].firstCardIndex), TmpCards[i].secCardIndex);
  3393. CChiHuRight chr;
  3394. BYTE TaiShu = 0;
  3395. BYTE TempAction = TempGameLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID],
  3396. m_cbWeaveItemCount[wChairID], m_cbSendCardData, chr, TaiShu);
  3397. if (TempAction == WIK_ZI_MO&&TaiShu >= DingMagicMinTai)
  3398. {
  3399. tmpRecordDcsCars[nRecordCount++] = m_GameLogic.SwitchToCardData(TmpCards[i].firstCardIndex);
  3400. tmpRecordDcsCars[nRecordCount++] = m_GameLogic.SwitchToCardData(TmpCards[i].secCardIndex);
  3401. }
  3402. }
  3403. //////////////////////////////////////////////////////////////////////////
  3404. //判定无财神
  3405. //////////////////////////////////////////////////////////////////////////
  3406. CMD_S_DING_CAI_RESULT DcResult;
  3407. DcResult.cbIsWCHu = false;
  3408. {
  3409. CGameLogic_dcs TempGameLogic(this);
  3410. TempGameLogic.SetMagicIndex(MAX_INDEX, MAX_INDEX);
  3411. BYTE TaiShu = 0;
  3412. if (TempGameLogic.AnalyseCardNew(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3413. {
  3414. TempGameLogic.mSunTaiJiangInColor = TempGameLogic.mJiangInColor;
  3415. TaiShu = TempGameLogic.AnalyseCardTaiNum(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]);
  3416. }
  3417. if (TaiShu >= DingMagicMinTai)
  3418. {
  3419. DcResult.cbIsWCHu = TRUE;
  3420. OutputDebugString(_T("无财胡"));
  3421. }
  3422. }
  3423. if (nRecordCount >= 1)
  3424. {
  3425. DcResult.cbResult = 1;
  3426. }
  3427. else
  3428. {
  3429. DcResult.cbResult = 0;
  3430. }
  3431. for (int i = 0; i < nRecordCount; i++)
  3432. {
  3433. CString str;
  3434. if ((tmpRecordDcsCars[i] & 0x80) != 0)
  3435. {
  3436. str.Format(_T("独财神 %02x"), tmpRecordDcsCars[i] ^ 0x80);
  3437. OutputDebugString(str);
  3438. }
  3439. else{
  3440. str.Format(_T("财神 %02x"), tmpRecordDcsCars[i]);
  3441. OutputDebugString(str);
  3442. }
  3443. }
  3444. CopyMemory(DcResult.caiCards, tmpRecordDcsCars, nRecordCount);
  3445. SparrowMaJiang::PB_CS_S_DING_CAI_RESULT pDcResult;
  3446. pDcResult.set_cbiswchu(DcResult.cbIsWCHu);
  3447. pDcResult.set_cbresult(DcResult.cbResult);
  3448. for (BYTE j = 0; j < MAX_INDEX; j++)
  3449. {
  3450. pDcResult.add_caicards(DcResult.caiCards[j]);
  3451. }
  3452. std::string pbdate = pDcResult.SerializePartialAsString();
  3453. RepayRecord(wChairID, SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  3454. //发送消息
  3455. m_pITableFrame->SendTableData(wChairID, SUB_S_DING_CAI_RESULT, (void*)pbdate.c_str(), pbdate.length());
  3456. return TRUE;
  3457. }
  3458. bool CTableFrameSink_dcs::GetOneWeaveItemCards(const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BYTE * cbCards, INT & CardsCount)
  3459. {
  3460. int nCards = 0;
  3461. for (int i = 0; i < cbWeaveCount; i++)
  3462. {
  3463. switch (WeaveItem[i].cbWeaveKind)
  3464. {
  3465. case WIK_PENG:
  3466. case WIK_BU_GANG:
  3467. case WIK_MING_GANG:
  3468. case WIK_AN_GANG:
  3469. {
  3470. cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  3471. break;
  3472. }
  3473. case WIK_LEFT:{
  3474. cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  3475. cbCards[nCards++] = WeaveItem[i].cbCenterCard + 1;
  3476. cbCards[nCards++] = WeaveItem[i].cbCenterCard + 2;
  3477. break;
  3478. }
  3479. case WIK_CENTER:{
  3480. cbCards[nCards++] = WeaveItem[i].cbCenterCard - 1;
  3481. cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  3482. cbCards[nCards++] = WeaveItem[i].cbCenterCard + 1;
  3483. break;
  3484. }
  3485. case WIK_RIGHT:{
  3486. cbCards[nCards++] = WeaveItem[i].cbCenterCard - 1;
  3487. cbCards[nCards++] = WeaveItem[i].cbCenterCard - 2;
  3488. cbCards[nCards++] = WeaveItem[i].cbCenterCard;
  3489. break;
  3490. }
  3491. default:
  3492. break;
  3493. }
  3494. }
  3495. CardsCount = nCards;
  3496. return TRUE;
  3497. }
  3498. bool CTableFrameSink_dcs::CardInCardArray(BYTE cbCard, BYTE* cbCards, int nCount)
  3499. {
  3500. for (int i = 0; i < nCount; i++)
  3501. {
  3502. if (cbCards[i] == cbCard)
  3503. {
  3504. return true;
  3505. }
  3506. }
  3507. return false;
  3508. }
  3509. bool CTableFrameSink_dcs::GetLianXuCards(BYTE* CardsIndex, std::vector<CaiCards> &vCards)
  3510. {
  3511. for (int i = 0; i < MAX_INDEX; i++)
  3512. {
  3513. if (CardsIndex[i] == 0)
  3514. {
  3515. continue;
  3516. }
  3517. int nNextIndex = m_GameLogic.SwitchToCardIndex(GetNextMagicCardData(i));
  3518. if (CardsIndex[nNextIndex] > 0)
  3519. {
  3520. CaiCards tmp;
  3521. tmp.firstCardIndex = i;
  3522. tmp.firstCardIndex = nNextIndex;
  3523. vCards.push_back(tmp);
  3524. }
  3525. }
  3526. return true;
  3527. }
  3528. #include<algorithm>
  3529. bool comp(const CanDcsSt &a, const CanDcsSt &b){
  3530. return a.nTai > b.nTai;
  3531. }
  3532. //获取14张手牌(包括落地牌),能够当作财神的牌,以及此牌当财神时胡的 台数
  3533. bool CTableFrameSink_dcs::GetMagicCardAndTaiNum(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, std::vector<CanDcsSt> &vCards, BOOL FindOneExit )
  3534. {
  3535. //ZeroMemory(mCanDingCaiCardArray[wChairID], MAX_INDEX);
  3536. memset(mCanDingCaiCardArray[wChairID], 4, MAX_INDEX);
  3537. if (m_bQiangGang==true)
  3538. {
  3539. mCanDingCaiCardArray[wChairID][m_GameLogic.SwitchToCardIndex(cbCenterCard)] = 0;
  3540. }
  3541. CalculationMagicCards(wChairID);
  3542. //第一步 根据落地派 获取能够当财神的牌的组合
  3543. BYTE CanMakeMagic[MAX_COUNT] = { 0 };
  3544. std::vector<CanMadeMagic> vCanMadeMagics;
  3545. cardsIndex[m_GameLogic.SwitchToCardIndex(cbCenterCard)]++;
  3546. GetCanMadeMagicCards(cardsIndex, vCanMadeMagics,wChairID);
  3547. cardsIndex[m_GameLogic.SwitchToCardIndex(cbCenterCard)]--;
  3548. std::vector<CanMadeMagic>::iterator it = vCanMadeMagics.begin();
  3549. for (; it != vCanMadeMagics.end(); it++)
  3550. {
  3551. int nTai = GetTaiNumFromCards(cardsIndex, wChairID, cbCenterCard, it->firstIndex, it->SecIndex, m_bQiangGang);
  3552. if (nTai>0&&IsCanTianhu()&&FindOneExit==FALSE)
  3553. {
  3554. nTai = mMaxTaiNum;
  3555. }
  3556. if (nTai >= DingMagicMinTai)
  3557. {
  3558. CanDcsSt st;
  3559. st.nTai = nTai;
  3560. if (it->SecIndex == MAX_INDEX)
  3561. {
  3562. st.bDuCanHu = true;
  3563. st.MagicCard = m_GameLogic.SwitchToCardData(it->firstIndex);
  3564. st.MagicCardNext = 0;
  3565. }
  3566. else
  3567. {
  3568. st.bDuCanHu = false;
  3569. st.MagicCard = m_GameLogic.SwitchToCardData(it->firstIndex);
  3570. st.MagicCardNext = m_GameLogic.SwitchToCardData(it->SecIndex);
  3571. }
  3572. if (m_bQiangGang)
  3573. {
  3574. if (st.MagicCard == cbCenterCard || st.MagicCardNext == cbCenterCard)
  3575. {
  3576. continue;
  3577. }
  3578. }
  3579. vCards.push_back(st);
  3580. if (FindOneExit)
  3581. {
  3582. break;
  3583. }
  3584. }
  3585. }
  3586. std::sort(vCards.begin(), vCards.end(), comp);
  3587. return vCards.size() > 0;
  3588. }
  3589. bool CTableFrameSink_dcs::GetCanMadeMagicCards(BYTE* cardsIndex, std::vector<CanMadeMagic> &vCards, BYTE currentUserIndex)
  3590. {
  3591. //手牌 和mCanDingCaiCard 对比。值=4的 则可以当作财神
  3592. for (int i = 0; i < MAX_INDEX;i++)
  3593. {
  3594. if (cardsIndex[i]==0)
  3595. {
  3596. //不是手牌的先排除
  3597. continue;
  3598. }
  3599. if (mCanDingCaiCardArray[currentUserIndex][i] == 4)
  3600. {
  3601. CanMadeMagic macgic;
  3602. macgic.firstIndex = i;
  3603. macgic.SecIndex = MAX_INDEX;
  3604. vCards.push_back(macgic);
  3605. int NextIndex = m_GameLogic.SwitchToCardIndex(GetNextMagicCardData(m_GameLogic.SwitchToCardData(i)));
  3606. if (mCanDingCaiCardArray[currentUserIndex][NextIndex] == 4 && cardsIndex[NextIndex]>0)
  3607. {
  3608. CanMadeMagic macgic;
  3609. macgic.firstIndex = i;
  3610. macgic.SecIndex = m_GameLogic.SwitchToCardIndex(GetNextMagicCardData(m_GameLogic.SwitchToCardData(i)));
  3611. vCards.push_back(macgic);
  3612. }
  3613. }
  3614. }
  3615. //
  3616. //
  3617. // BYTE TempUserCards[MAX_INDEX] = { 0 };
  3618. // CopyMemory(TempUserCards, cardsIndex, MAX_INDEX);
  3619. // BYTE WeaveCards[MAX_COUNT] = { 0 };
  3620. // int nCount = 0;
  3621. // GetOneWeaveItemCards(WeaveItem, cbWeaveCount, WeaveCards, nCount);
  3622. //
  3623. // for (int i = 0; i < nCount; i++)
  3624. // {
  3625. // int nIndex = m_GameLogic.SwitchToCardIndex(WeaveCards[i]);
  3626. // TempUserCards[nIndex] = 0;
  3627. // }
  3628. // for (int i = 0; i < MAX_INDEX; i++)
  3629. // {
  3630. // if (TempUserCards[i] == 0)
  3631. // {
  3632. // continue;
  3633. // }
  3634. // CanMadeMagic macgic;
  3635. // macgic.firstIndex = i;
  3636. // macgic.SecIndex = MAX_INDEX;
  3637. // vCards.push_back(macgic);
  3638. //
  3639. // if (TempUserCards[m_GameLogic.SwitchToCardIndex(GetNextMagicCardData(m_GameLogic.SwitchToCardData(i)))]>0)
  3640. // {
  3641. // CanMadeMagic macgic;
  3642. // macgic.firstIndex = i;
  3643. // macgic.SecIndex = m_GameLogic.SwitchToCardIndex(GetNextMagicCardData(m_GameLogic.SwitchToCardData(i)));
  3644. // vCards.push_back(macgic);
  3645. // }
  3646. //
  3647. // }
  3648. return true;
  3649. }
  3650. byte CTableFrameSink_dcs::GetTaiNumFromCards(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, BYTE firstIndex, BYTE secIndex, bool bQiangGang/*=false*/)
  3651. {
  3652. CGameLogic_dcs dscLogic(this);
  3653. dscLogic.SetMagicIndex(firstIndex, secIndex);
  3654. CChiHuRight chr;
  3655. BYTE TaiShu = 0;
  3656. BYTE szCardIndex[MAX_INDEX] = { 0 };
  3657. CopyMemory(szCardIndex, cardsIndex, MAX_INDEX);
  3658. szCardIndex[dscLogic.SwitchToCardIndex(cbCenterCard)]++;
  3659. if (dscLogic.AnalyseCardNew(szCardIndex, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3660. {
  3661. dscLogic.mSunTaiJiangInColor = dscLogic.mJiangInColor;
  3662. int nMagicCount = dscLogic.GetMaigcCardCount(szCardIndex);
  3663. if (bQiangGang&&nMagicCount!=0)
  3664. {
  3665. BYTE szCardIndexDeleteMagic[MAX_INDEX] = { 0 };
  3666. CopyMemory(szCardIndexDeleteMagic, cardsIndex, MAX_INDEX);
  3667. CChiHuRight chihuright;
  3668. if (WIK_ZI_MO == dscLogic.AnalyseChiHuCard_DeleteMagic(szCardIndexDeleteMagic, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], cbCenterCard, chihuright, TaiShu, FALSE, TRUE))
  3669. {
  3670. return TaiShu;
  3671. }
  3672. return 0;
  3673. }
  3674. dscLogic.m_cbHuCard = cbCenterCard;
  3675. int TmpJiangInColor = dscLogic.mJiangInColor;
  3676. dscLogic.mSunTaiJiangInColor = dscLogic.mJiangInColor;
  3677. int nTai = dscLogic.AnalyseCardTaiNum(szCardIndex, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], bQiangGang==TRUE?FALSE:TRUE);
  3678. if (bQiangGang)
  3679. {
  3680. nTai++;
  3681. }
  3682. if (m_bUsersGangStatus[wChairID]==TRUE)
  3683. {
  3684. nTai++;
  3685. }
  3686. if (nTai>=3)
  3687. {
  3688. if (dscLogic.AnalyseCardTaiNum_IsDuMagic(szCardIndex, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3689. {
  3690. nTai++;
  3691. }
  3692. if (dscLogic.AnalyseCardTaiNum_IsQuanZi(szCardIndex, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3693. {
  3694. nTai = 7;
  3695. }
  3696. }
  3697. // if (dscLogic.AnalyseCardTaiNum_IsWuMagic(szCardIndex, m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID]))
  3698. // {
  3699. // nTai = 7;
  3700. // }
  3701. return nTai;
  3702. }
  3703. // BYTE TempAction = dscLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID],
  3704. // m_cbWeaveItemCount[wChairID], m_cbSendCardData, chr, TaiShu,false,bQiangGang);
  3705. // if (TempAction == WIK_ZI_MO)
  3706. // {
  3707. // return TaiShu;
  3708. // }
  3709. return 0;
  3710. }
  3711. BOOL CTableFrameSink_dcs::IsCanTianhu()
  3712. {
  3713. if (m_cbOutCardCount>0)
  3714. {
  3715. return FALSE;
  3716. }
  3717. if (m_bTwoPlayerFlag)
  3718. {
  3719. if (m_cbSendCardCount != ((13 * mPlayGameUserCount-1) + 1))
  3720. {
  3721. return FALSE;
  3722. }
  3723. }
  3724. else
  3725. {
  3726. if (m_cbSendCardCount != ((13 * mPlayGameUserCount) + 1))
  3727. {
  3728. return FALSE;
  3729. }
  3730. }
  3731. return TRUE;
  3732. // 打出牌数目为0 并且 m_cbSendCardCount 发牌数据等于玩家数+1
  3733. }
  3734. //被动操作删除手牌
  3735. bool CTableFrameSink_dcs::DeleteCaiShenCard(WORD wTargetUser, BYTE cbTargetCaiCard[4], int cbTargetAction, BYTE cbTargetCard)
  3736. {
  3737. switch (cbTargetAction)
  3738. {
  3739. case WIK_LEFT: //上牌操作,左吃
  3740. {
  3741. //删除扑克
  3742. BYTE cbRemoveCard[3];
  3743. BYTE cbMagicCard[4] = { 0 };
  3744. m_GameLogic.GetWeaveCard(WIK_LEFT, cbTargetCard, cbMagicCard, cbRemoveCard);
  3745. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3746. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3747. return true;
  3748. }
  3749. case WIK_RIGHT: //上牌操作,右吃
  3750. {
  3751. //删除扑克
  3752. BYTE cbRemoveCard[3];
  3753. BYTE cbMagicCard[4] = { 0 };
  3754. m_GameLogic.GetWeaveCard(WIK_RIGHT, cbTargetCard, cbMagicCard, cbRemoveCard);
  3755. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3756. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3757. return true;
  3758. }
  3759. case WIK_CENTER: //上牌操作,中吃
  3760. {
  3761. //删除扑克
  3762. BYTE cbRemoveCard[3];
  3763. BYTE cbMagicCard[4] = { 0 };
  3764. m_GameLogic.GetWeaveCard(WIK_CENTER, cbTargetCard, cbMagicCard, cbRemoveCard);
  3765. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3766. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3767. return true;
  3768. }
  3769. case WIK_PENG: //碰牌操作
  3770. {
  3771. //删除扑克
  3772. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] < 2)
  3773. {
  3774. ASSERT(false);
  3775. return false;
  3776. }
  3777. BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard };
  3778. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3779. return true;
  3780. }
  3781. case WIK_MING_GANG: //明杠牌操作
  3782. case WIK_BU_GANG:
  3783. {
  3784. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] != 3)
  3785. {
  3786. ASSERT(false);
  3787. return false;
  3788. }
  3789. BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard, cbTargetCard };
  3790. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, CountArray(cbRemoveCard)));
  3791. if (mPlayGameUserCount == 4)
  3792. {
  3793. mBCanShowLeft = FALSE;
  3794. mTempLeftCount = m_cbLeftCardCount;
  3795. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3796. {
  3797. m_cbLeftCardCount -= 6;
  3798. }
  3799. else//少于三墩就只有一张可以抓的牌咯
  3800. {
  3801. mTempLeftCount = m_cbLeftCardCount;
  3802. }
  3803. }
  3804. if (mPlayGameUserCount != 4)
  3805. {
  3806. mBCanShowLeft = FALSE;
  3807. if (m_cbLeftCardCount > 4)//扣除2墩可摸的牌
  3808. {
  3809. m_cbLeftCardCount -= 4;
  3810. }
  3811. else//少于二墩就只有一张可以抓的牌咯
  3812. {
  3813. m_cbLeftCardCount = 1;
  3814. }
  3815. }
  3816. m_cbGangCount++;//打了几个杠
  3817. return true;
  3818. }
  3819. default:
  3820. {
  3821. ASSERT(false);
  3822. return false;
  3823. }
  3824. }
  3825. }
  3826. //自主操作删除手牌
  3827. bool CTableFrameSink_dcs::DeleteCard(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard)
  3828. {
  3829. switch (cbOperateCode)
  3830. {
  3831. case WIK_AN_GANG: //暗杠牌操作
  3832. {
  3833. //扑克效验
  3834. ASSERT((cbOperateCode == WIK_AN_GANG) || (m_GameLogic.IsValidCard(cbOperateCard) == true));
  3835. if ((cbOperateCode != WIK_AN_GANG) && (m_GameLogic.IsValidCard(cbOperateCard) == false))
  3836. return false;
  3837. //变量定义
  3838. BYTE cbWeaveIndex = 0xFF;
  3839. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3840. //杠牌处理
  3841. if (m_cbCardIndex[wChairID][cbCardIndex] == 4)
  3842. {
  3843. //扑克效验
  3844. ASSERT(m_cbCardIndex[wChairID][cbCardIndex] == 4);
  3845. if (m_cbCardIndex[wChairID][cbCardIndex] != 4)
  3846. {
  3847. ASSERT(false);
  3848. return false;
  3849. }
  3850. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3851. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3852. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3853. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3854. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3855. }
  3856. else
  3857. {
  3858. ASSERT(FALSE);
  3859. return false;
  3860. }
  3861. //删除扑克
  3862. m_cbCardIndex[wChairID][cbCardIndex] = 0;
  3863. //////////////////////////////////////////////////////////////////////////
  3864. if (mPlayGameUserCount == 4)
  3865. {
  3866. mBCanShowLeft = FALSE;
  3867. mTempLeftCount = m_cbLeftCardCount;
  3868. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3869. {
  3870. m_cbLeftCardCount -= 6;
  3871. }
  3872. else//少于三墩就只有一张可以抓的牌咯
  3873. {
  3874. m_cbLeftCardCount = 1;
  3875. }
  3876. }
  3877. if (mPlayGameUserCount != 4)
  3878. {
  3879. mBCanShowLeft = FALSE;
  3880. if (m_cbLeftCardCount > 4)//扣除2墩可摸的牌
  3881. {
  3882. m_cbLeftCardCount -= 4;
  3883. }
  3884. else//少于二墩就只有一张可以抓的牌咯
  3885. {
  3886. m_cbLeftCardCount = 1;
  3887. }
  3888. }
  3889. //////////////////////////////////////////////////////////////////////////
  3890. m_cbGangCount++;//打了几个杠
  3891. return true;
  3892. }
  3893. case WIK_BU_GANG:
  3894. {
  3895. //扑克效验
  3896. ASSERT((cbOperateCode == WIK_NULL) || (cbOperateCode == WIK_BU_GANG) || (m_GameLogic.IsValidCard(cbOperateCard) == true));
  3897. if ((cbOperateCode != WIK_BU_GANG) && (m_GameLogic.IsValidCard(cbOperateCard) == false))
  3898. return false;
  3899. BYTE cbWeaveIndex = 0xFF;
  3900. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3901. //杠牌处理
  3902. if (m_cbCardIndex[wChairID][cbCardIndex] >= 1)//表示续杠类型
  3903. {
  3904. //寻找组合
  3905. for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++)
  3906. {
  3907. INT cbWeaveKind = m_WeaveItemArray[wChairID][i].cbWeaveKind;
  3908. BYTE cbCenterCard = m_WeaveItemArray[wChairID][i].cbCenterCard;
  3909. if ((cbCenterCard == cbOperateCard) && (cbWeaveKind &(WIK_DAN_PENG | WIK_PENG | WIK_SHUANG_PENG)))
  3910. {
  3911. cbWeaveIndex = i;
  3912. break;
  3913. }
  3914. }
  3915. //效验动作
  3916. ASSERT(cbWeaveIndex != 0xFF);
  3917. if (cbWeaveIndex == 0xFF) return false;
  3918. //组合扑克
  3919. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = TRUE;
  3920. //m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3921. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3922. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3923. }
  3924. else
  3925. {
  3926. ASSERT(false);
  3927. return false;
  3928. }
  3929. //删除扑克
  3930. m_cbCardIndex[wChairID][cbCardIndex] -= 1;
  3931. if (mPlayGameUserCount == 4)
  3932. {
  3933. mBCanShowLeft = FALSE;
  3934. mTempLeftCount = m_cbLeftCardCount;
  3935. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3936. {
  3937. m_cbLeftCardCount -= 6;
  3938. }
  3939. else//少于三墩就只有一张可以抓的牌咯
  3940. {
  3941. m_cbLeftCardCount = 1;
  3942. }
  3943. }
  3944. if (mPlayGameUserCount != 4)
  3945. {
  3946. mBCanShowLeft = FALSE;
  3947. if (m_cbLeftCardCount > 4)//扣除2墩可摸的牌
  3948. {
  3949. m_cbLeftCardCount -= 4;
  3950. }
  3951. else//少于二墩就只有一张可以抓的牌咯
  3952. {
  3953. m_cbLeftCardCount = 1;
  3954. }
  3955. }
  3956. //////////////////////////////////////////////////////////////////////////
  3957. m_cbGangCount++;//打了几个杠
  3958. return true;
  3959. }
  3960. default:
  3961. {
  3962. ASSERT(false);
  3963. return false;
  3964. };
  3965. }
  3966. }
  3967. //优先级判断
  3968. /*
  3969. 提供牌的用户
  3970. 当前操作的用户
  3971. 当前用户的操作
  3972. */
  3973. bool CTableFrameSink_dcs::OperatorPriority(WORD TmpwProvideUser, WORD &wOptUser, int &cbTargetAction)
  3974. {
  3975. for (WORD UserPlayIndex = 0; UserPlayIndex < mPlayGameUserCount; UserPlayIndex++)//除了打牌人,操作人与其他两位对操作优先级
  3976. {
  3977. if (m_bTwoPlayerFlag&&UserPlayIndex == TowMjNullseat)
  3978. {
  3979. continue;
  3980. }
  3981. TmpwProvideUser = (TmpwProvideUser + 1) % mPlayGameUserCount;//temp=temp->next
  3982. if (TmpwProvideUser == wOptUser)continue;
  3983. //获取动作
  3984. int cbUserAction = (m_bResponse[TmpwProvideUser] == false) ? m_cbUserAction[TmpwProvideUser] : m_cbPerformAction[TmpwProvideUser];
  3985. //优先级别
  3986. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  3987. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  3988. //动作判断
  3989. if (cbUserActionRank > cbTargetActionRank)
  3990. {
  3991. wOptUser = TmpwProvideUser;
  3992. cbTargetAction = cbUserAction;
  3993. continue;
  3994. }
  3995. if (cbUserActionRank == cbTargetActionRank && cbTargetActionRank != WIK_NULL)
  3996. {
  3997. if (UserPlayIndex == 2)//肯定和其他人都比了,最后一次两个人的操作一样,且表示操作人不在末端操作人
  3998. {
  3999. return true;
  4000. }
  4001. else if (UserPlayIndex == 1)//对比一次,对比了两次说明操作人不是下家的下家;操作人只能是第一家或者最后一家,如果是第一家操作:,如果是最后一家
  4002. {
  4003. WORD TempTempUser = (TmpwProvideUser + 1) % mPlayGameUserCount;
  4004. if (wOptUser == TempTempUser)//确定操作人是最后一个,这是第二次对比
  4005. {
  4006. wOptUser = TmpwProvideUser;
  4007. cbTargetAction = cbUserAction;
  4008. return true;
  4009. }
  4010. else//第一次对比,确定操作人是出牌人下家,这个时候再把他和后面一个人的牌权对比
  4011. {
  4012. int cbUserAction = (m_bResponse[TempTempUser] == false) ? m_cbUserAction[TempTempUser] : m_cbPerformAction[TempTempUser];
  4013. //优先级别
  4014. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  4015. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  4016. if (cbUserActionRank > cbTargetActionRank)
  4017. {
  4018. wOptUser = TempTempUser;
  4019. cbTargetAction = cbUserAction;
  4020. return true;
  4021. }
  4022. break;
  4023. }
  4024. }
  4025. else//冲上来就比了一次,说操作人不是打牌人下家
  4026. {
  4027. wOptUser = TmpwProvideUser;
  4028. cbTargetAction = cbUserAction;
  4029. WORD TempTempUser = (TmpwProvideUser + 1) % mPlayGameUserCount;
  4030. if (wOptUser == TempTempUser)TempTempUser = (TempTempUser + 1) % mPlayGameUserCount;//如果在中间就换一个人
  4031. int cbUserAction = (m_bResponse[TempTempUser] == false) ? m_cbUserAction[TempTempUser] : m_cbPerformAction[TempTempUser];
  4032. //优先级别
  4033. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  4034. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  4035. if (cbUserActionRank > cbTargetActionRank)
  4036. {
  4037. wOptUser = TempTempUser;
  4038. cbTargetAction = cbUserAction;
  4039. return true;
  4040. }
  4041. return true;
  4042. }
  4043. }
  4044. }
  4045. return true;
  4046. }
  4047. int CTableFrameSink_dcs::bHuPaiType(CChiHuRight &CChiHuRight)
  4048. {
  4049. int hutype = 0;
  4050. if (!(CChiHuRight&ZJ_TAI_QingYiSe).IsEmpty())
  4051. {
  4052. hutype |= ZJ_TAI_QingYiSe;
  4053. }
  4054. if (!(CChiHuRight&ZJ_TAI_DongFeng).IsEmpty())
  4055. {
  4056. hutype |= ZJ_TAI_DongFeng;
  4057. }
  4058. if (!(CChiHuRight&ZJ_TAI_WuMagic).IsEmpty())
  4059. {
  4060. hutype |= ZJ_TAI_WuMagic;
  4061. }
  4062. if (!(CChiHuRight&ZJ_TAI_QuanShun).IsEmpty())
  4063. {
  4064. hutype |= ZJ_TAI_QuanShun;
  4065. }
  4066. if (!(CChiHuRight&ZJ_TAI_PengPeng).IsEmpty())
  4067. {
  4068. hutype |= ZJ_TAI_PengPeng;
  4069. }
  4070. if (!(CChiHuRight&ZJ_TAI_HunYiSe).IsEmpty())
  4071. {
  4072. hutype |= ZJ_TAI_HunYiSe;
  4073. }
  4074. // if (!(CChiHuRight&ZJ_TAI_Gang).IsEmpty())
  4075. // {
  4076. // hutype |= ZJ_TAI_Gang;
  4077. // }
  4078. if (!(CChiHuRight&ZJ_TAI_ZFB).IsEmpty())
  4079. {
  4080. hutype |= ZJ_TAI_ZFB;
  4081. }
  4082. if (!(CChiHuRight&ZJ_TAI_QuanZi).IsEmpty())
  4083. {
  4084. hutype |= ZJ_TAI_QuanZi;
  4085. }
  4086. if (!(CChiHuRight&ZJ_TAI_ZHAHU).IsEmpty())
  4087. {
  4088. hutype = ZJ_TAI_ZHAHU;
  4089. }
  4090. if (!(CChiHuRight&ZJ_TAI_Gang).IsEmpty())//单财胡
  4091. {
  4092. OutputDebugString(_T("增加 单财胡 +1"));
  4093. hutype |= ZJ_TAI_Gang;
  4094. }
  4095. return hutype;
  4096. }