诸暨麻将添加redis
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

1012 lignes
27 KiB

  1. #include "Stdafx.h"
  2. #include "AndroidUserItemSink.h"
  3. #include "AndroidAI.h"
  4. //////////////////////////////////////////////////////////////////////////
  5. //辅助时间
  6. #ifdef _DEBUG
  7. #define TIME_LESS 1 //最少时间
  8. #define TIME_START_GAME 1 //开始时间
  9. #define TIME_OPERATE_CARD 1 //操作牌时间
  10. #else
  11. #define TIME_LESS 2 //最少时间
  12. #define TIME_START_GAME 10 //开始时间
  13. #define TIME_OPERATE_CARD 8 //操作牌时间
  14. #endif
  15. //游戏时间
  16. //游戏时间
  17. #define IDI_OUT_CARD (0) //出牌时间
  18. #define IDI_START_GAME (1) //开始时间
  19. #define IDI_OPERATE_CARD (2) //
  20. //////////////////////////////////////////////////////////////////////////
  21. //构造函数
  22. CAndroidUserItemSink::CAndroidUserItemSink()
  23. {
  24. //游戏变量
  25. m_wBankerUser=INVALID_CHAIR;
  26. m_wCurrentUser=INVALID_CHAIR;
  27. m_cbActionMask = 0;
  28. m_cbActionCard = 0;
  29. //组合扑克
  30. ZeroMemory(m_cbWeaveCount,sizeof(m_cbWeaveCount));
  31. ZeroMemory(m_WeaveItemArray,sizeof(m_WeaveItemArray));
  32. //扑克变量
  33. m_cbLeftCardCount=0;
  34. ZeroMemory(m_cbCardIndex,sizeof(m_cbCardIndex));
  35. return;
  36. }
  37. //析构函数
  38. CAndroidUserItemSink::~CAndroidUserItemSink()
  39. {
  40. }
  41. //接口查询
  42. VOID * CAndroidUserItemSink::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
  43. {
  44. QUERYINTERFACE(IAndroidUserItemSink,Guid,dwQueryVer);
  45. QUERYINTERFACE_IUNKNOWNEX(IAndroidUserItemSink,Guid,dwQueryVer);
  46. return NULL;
  47. }
  48. //初始接口
  49. bool CAndroidUserItemSink::Initialization(IUnknownEx * pIUnknownEx)
  50. {
  51. //查询接口
  52. m_pIAndroidUserItem=QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx,IAndroidUserItem);
  53. if (m_pIAndroidUserItem==NULL) return false;
  54. return true;
  55. }
  56. //重置接口
  57. bool CAndroidUserItemSink::RepositionSink()
  58. {
  59. //游戏变量
  60. m_wBankerUser=INVALID_CHAIR;
  61. m_wCurrentUser=INVALID_CHAIR;
  62. m_cbActionMask = 0;
  63. m_cbActionCard = 0;
  64. //组合扑克
  65. ZeroMemory(m_cbWeaveCount,sizeof(m_cbWeaveCount));
  66. ZeroMemory(m_WeaveItemArray,sizeof(m_WeaveItemArray));
  67. //扑克变量
  68. m_cbLeftCardCount=0;
  69. ZeroMemory(m_cbCardIndex,sizeof(m_cbCardIndex));
  70. return true;
  71. }
  72. //时间消息
  73. bool CAndroidUserItemSink::OnEventTimer(UINT nTimerID)
  74. {
  75. switch (nTimerID)
  76. {
  77. case IDI_START_GAME: //开始游戏
  78. {
  79. m_pIAndroidUserItem->KillGameTimer(IDI_START_GAME);
  80. //开始判断
  81. if( m_pIAndroidUserItem->GetGameStatus()==GS_MJ_FREE )
  82. m_pIAndroidUserItem->SendUserReady(NULL,0);
  83. return true;
  84. }
  85. case IDI_OPERATE_CARD: //操作定时器
  86. {
  87. tagOutCardResult OutCardResult;
  88. WORD wMeChairId = m_pIAndroidUserItem->GetChairID();
  89. #ifdef _DEBUG
  90. BYTE byCardCount = m_GameLogic.GetCardCount( m_cbCardIndex[wMeChairId] );
  91. if( wMeChairId == m_wCurrentUser )
  92. ASSERT( (byCardCount+1)%3 == 0 );
  93. else ASSERT( byCardCount%3 == 1 );
  94. #endif
  95. try
  96. {
  97. //搜索出牌
  98. if( SearchOutCard(OutCardResult) )
  99. {
  100. if( OutCardResult.cbOperateCode != WIK_NULL )
  101. {
  102. //效验
  103. ASSERT( OutCardResult.cbOperateCode&m_cbActionMask );
  104. if( !(OutCardResult.cbOperateCode&m_cbActionMask) ) throw 0;
  105. //响应操作
  106. OnOperateCard(OutCardResult.cbOperateCode,OutCardResult.cbOperateCard);
  107. }
  108. else
  109. {
  110. //效验
  111. ASSERT( m_cbCardIndex[m_pIAndroidUserItem->GetChairID()][m_GameLogic.SwitchToCardIndex(OutCardResult.cbOperateCard)] > 0 );
  112. if( m_cbCardIndex[m_pIAndroidUserItem->GetChairID()][m_GameLogic.SwitchToCardIndex(OutCardResult.cbOperateCard)] == 0 ) throw 0;
  113. //出牌
  114. OnOutCard(OutCardResult.cbOperateCard);
  115. }
  116. }else
  117. {
  118. //效验
  119. ASSERT( wMeChairId != m_wCurrentUser );
  120. if( wMeChairId == m_wCurrentUser ) throw 0;
  121. //响应操作
  122. OnOperateCard(WIK_NULL,0);
  123. }
  124. }catch(...)
  125. {
  126. ASSERT(FALSE);
  127. //异常处理
  128. if( wMeChairId == m_wCurrentUser )
  129. {
  130. for( BYTE i = 0; i < MAX_INDEX; i++ )
  131. {
  132. if( m_cbCardIndex[wMeChairId][i] > 0 )
  133. {
  134. OnOutCard( m_GameLogic.SwitchToCardData(i) );
  135. return true;
  136. }
  137. }
  138. }
  139. else OnOperateCard( WIK_NULL,0 );
  140. }
  141. return true;
  142. }
  143. }
  144. return false;
  145. }
  146. //游戏消息
  147. bool CAndroidUserItemSink::OnEventGameMessage(WORD wSubCmdID, void * pData, WORD wDataSize)
  148. {
  149. switch (wSubCmdID)
  150. {
  151. case SUB_S_GAME_START: //游戏开始
  152. {
  153. return OnSubGameStart(pData,wDataSize);
  154. }
  155. case SUB_S_OUT_CARD: //用户出牌
  156. {
  157. return OnSubOutCard(pData,wDataSize);
  158. }
  159. case SUB_S_SEND_CARD: //发牌消息
  160. {
  161. return OnSubSendCard(pData,wDataSize);
  162. }
  163. case SUB_S_OPERATE_NOTIFY: //操作提示
  164. {
  165. return OnSubOperateNotify(pData,wDataSize);
  166. }
  167. case SUB_S_OPERATE_RESULT: //操作结果
  168. {
  169. return OnSubOperateResult(pData,wDataSize);
  170. }
  171. case SUB_S_GAME_END: //游戏结束
  172. {
  173. return OnSubGameEnd(pData,wDataSize);
  174. }
  175. case SUB_S_TRUSTEE: //用户托管
  176. {
  177. return true;
  178. }
  179. case SUB_S_CHI_HU:
  180. {
  181. return true;
  182. }
  183. case SUB_S_GANG_SCORE:
  184. {
  185. return true;
  186. }
  187. }
  188. //错误断言
  189. ASSERT(FALSE);
  190. return true;
  191. }
  192. //游戏消息
  193. bool CAndroidUserItemSink::OnEventFrameMessage(WORD wSubCmdID, void * pData, WORD wDataSize)
  194. {
  195. return true;
  196. }
  197. //场景消息
  198. bool CAndroidUserItemSink::OnEventSceneMessage(BYTE cbGameStatus, bool bLookonOther, void * pData, WORD wDataSize)
  199. {
  200. switch (cbGameStatus)
  201. {
  202. case GS_MJ_FREE: //空闲状态
  203. {
  204. //效验数据
  205. ASSERT(wDataSize==sizeof(CMD_S_StatusFree));
  206. if (wDataSize!=sizeof(CMD_S_StatusFree)) return false;
  207. //变量定义
  208. CMD_S_StatusFree * pStatusFree=(CMD_S_StatusFree *)pData;
  209. IServerUserItem * pIServerUserItem=m_pIAndroidUserItem->GetMeUserItem();
  210. //玩家设置
  211. if (pIServerUserItem->GetUserStatus()!=US_READY)
  212. {
  213. UINT nElapse=rand()%TIME_START_GAME+TIME_LESS;
  214. m_pIAndroidUserItem->SetGameTimer(IDI_START_GAME,nElapse);
  215. }
  216. return true;
  217. }
  218. case GS_MJ_PLAY: //游戏状态
  219. {
  220. ASSERT( FALSE );
  221. return true;
  222. }
  223. default:
  224. {
  225. ASSERT(FALSE);
  226. return false;
  227. }
  228. }
  229. return true;
  230. }
  231. //用户进入
  232. void CAndroidUserItemSink::OnEventUserEnter(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
  233. {
  234. return;
  235. }
  236. //用户离开
  237. void CAndroidUserItemSink::OnEventUserLeave(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
  238. {
  239. return;
  240. }
  241. //用户积分
  242. void CAndroidUserItemSink::OnEventUserScore(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
  243. {
  244. return;
  245. }
  246. //用户状态
  247. void CAndroidUserItemSink::OnEventUserStatus(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
  248. {
  249. return;
  250. }
  251. //用户段位
  252. void CAndroidUserItemSink::OnEventUserSegment(IAndroidUserItem * pIAndroidUserItem, bool bLookonUser)
  253. {
  254. return;
  255. }
  256. //庄家信息
  257. bool CAndroidUserItemSink::OnSubGameStart(const void * pData, WORD wDataSize)
  258. {
  259. //效验数据
  260. ASSERT(wDataSize==sizeof(CMD_S_GameStart));
  261. if (wDataSize!=sizeof(CMD_S_GameStart)) return false;
  262. //变量定义
  263. CMD_S_GameStart * pGameStart=(CMD_S_GameStart *)pData;
  264. //设置状态
  265. m_pIAndroidUserItem->SetGameStatus(GS_MJ_PLAY);
  266. //设置变量
  267. m_wBankerUser=pGameStart->wBankerUser;
  268. m_wCurrentUser=pGameStart->wCurrentUser;
  269. m_cbLeftCardCount=MAX_REPERTORY-GAME_PLAYER*(MAX_COUNT-1)-1;
  270. m_cbActionMask = pGameStart->cbUserAction;
  271. m_cbActionCard = 0;
  272. //出牌信息
  273. m_cbOutCardData=0;
  274. m_wOutCardUser=INVALID_CHAIR;
  275. ZeroMemory(m_cbDiscardCard,sizeof(m_cbDiscardCard));
  276. ZeroMemory(m_cbDiscardCount,sizeof(m_cbDiscardCount));
  277. //组合扑克
  278. ZeroMemory(m_cbWeaveCount,sizeof(m_cbWeaveCount));
  279. ZeroMemory(m_WeaveItemArray,sizeof(m_WeaveItemArray));
  280. //设置扑克
  281. WORD wMeChairId = m_pIAndroidUserItem->GetChairID();
  282. BYTE cbCardCount = (wMeChairId==m_wBankerUser)?MAX_COUNT:(MAX_COUNT-1);
  283. m_GameLogic.SwitchToCardIndex(pGameStart->cbCardData,cbCardCount,m_cbCardIndex[wMeChairId]);
  284. BYTE bIndex = 1;
  285. for( WORD i = 0; i < GAME_PLAYER; i++ )
  286. {
  287. if( i == wMeChairId ) continue;
  288. cbCardCount=(i==m_wBankerUser)?MAX_COUNT:(MAX_COUNT-1);
  289. m_GameLogic.SwitchToCardIndex(&pGameStart->cbCardData[MAX_COUNT*bIndex++],cbCardCount,m_cbCardIndex[i]);
  290. }
  291. //动作处理
  292. if ((pGameStart->cbUserAction!=WIK_NULL) || m_wCurrentUser==wMeChairId )
  293. {
  294. UINT nElapse = rand()%TIME_OPERATE_CARD+TIME_LESS+5;
  295. m_pIAndroidUserItem->SetGameTimer(IDI_OPERATE_CARD,nElapse);
  296. }
  297. return true;
  298. }
  299. //游戏结束
  300. bool CAndroidUserItemSink::OnSubGameEnd(const void * pData, WORD wDataSize)
  301. {
  302. //效验数据
  303. ASSERT(wDataSize==sizeof(CMD_S_GameEnd));
  304. if (wDataSize!=sizeof(CMD_S_GameEnd)) return false;
  305. //删除定时器
  306. m_pIAndroidUserItem->KillGameTimer(IDI_OPERATE_CARD);
  307. //设置状态
  308. m_pIAndroidUserItem->SetGameStatus(GS_MJ_FREE);
  309. //设置
  310. UINT nElapse = rand()%TIME_START_GAME+TIME_LESS;
  311. m_pIAndroidUserItem->SetGameTimer(IDI_START_GAME,nElapse);
  312. return true;
  313. }
  314. //操作通知
  315. bool CAndroidUserItemSink::OnSubOperateNotify( const void *pBuffer,WORD wDataSize )
  316. {
  317. //效验数据
  318. ASSERT(wDataSize==sizeof(CMD_S_OperateNotify));
  319. if (wDataSize!=sizeof(CMD_S_OperateNotify)) return false;
  320. //变量定义
  321. CMD_S_OperateNotify * pOperateNotify=(CMD_S_OperateNotify *)pBuffer;
  322. //用户界面
  323. if ((pOperateNotify->cbActionMask!=WIK_NULL))
  324. {
  325. //获取变量
  326. WORD wMeChairID=m_pIAndroidUserItem->GetChairID();
  327. m_cbActionMask = pOperateNotify->cbActionMask;
  328. m_cbActionCard = pOperateNotify->cbActionCard;
  329. //设置时间
  330. UINT nElapse = rand()%TIME_OPERATE_CARD+TIME_LESS;
  331. m_pIAndroidUserItem->SetGameTimer(IDI_OPERATE_CARD,nElapse);
  332. }
  333. return true;
  334. }
  335. //操作结果通知
  336. bool CAndroidUserItemSink::OnSubOperateResult( const void *pBuffer,WORD wDataSize )
  337. {
  338. //效验消息
  339. ASSERT(wDataSize==sizeof(CMD_S_OperateResult));
  340. if (wDataSize!=sizeof(CMD_S_OperateResult)) return false;
  341. //消息处理
  342. CMD_S_OperateResult * pOperateResult=(CMD_S_OperateResult *)pBuffer;
  343. m_pIAndroidUserItem->KillGameTimer( IDI_OPERATE_CARD );
  344. //变量定义
  345. BYTE cbPublicCard=TRUE;
  346. WORD wOperateUser=pOperateResult->wOperateUser;
  347. BYTE cbOperateCard = pOperateResult->cbOperateCard;
  348. //出牌变量
  349. if (pOperateResult->cbOperateCode!=WIK_NULL)
  350. {
  351. m_cbOutCardData=0;
  352. m_wOutCardUser=INVALID_CHAIR;
  353. }
  354. //设置变量
  355. m_cbActionMask = WIK_NULL;
  356. m_cbActionCard = 0;
  357. //设置组合
  358. if ((pOperateResult->cbOperateCode&WIK_GANG)!=0)
  359. {
  360. //设置变量
  361. m_wCurrentUser=INVALID_CHAIR;
  362. //组合扑克
  363. BYTE cbWeaveIndex=0xFF;
  364. for (BYTE i=0;i<m_cbWeaveCount[wOperateUser];i++)
  365. {
  366. BYTE cbWeaveKind=m_WeaveItemArray[wOperateUser][i].cbWeaveKind;
  367. BYTE cbCenterCard=m_WeaveItemArray[wOperateUser][i].cbCenterCard;
  368. if ((cbCenterCard==cbOperateCard)&&(cbWeaveKind==WIK_PENG))
  369. {
  370. cbWeaveIndex=i;
  371. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbPublicCard=TRUE;
  372. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbWeaveKind=pOperateResult->cbOperateCode;
  373. m_WeaveItemArray[wOperateUser][cbWeaveIndex].wProvideUser=pOperateResult->wProvideUser;
  374. break;
  375. }
  376. }
  377. //组合扑克
  378. if (cbWeaveIndex==0xFF)
  379. {
  380. //暗杠判断
  381. cbPublicCard=(pOperateResult->wProvideUser==wOperateUser)?FALSE:TRUE;
  382. //设置扑克
  383. cbWeaveIndex=m_cbWeaveCount[wOperateUser]++;
  384. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbPublicCard=cbPublicCard;
  385. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbCenterCard=cbOperateCard;
  386. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbWeaveKind=pOperateResult->cbOperateCode;
  387. m_WeaveItemArray[wOperateUser][cbWeaveIndex].wProvideUser=pOperateResult->wProvideUser;
  388. }
  389. //扑克设置
  390. m_cbCardIndex[wOperateUser][m_GameLogic.SwitchToCardIndex(cbOperateCard)]=0;
  391. }
  392. else if (pOperateResult->cbOperateCode!=WIK_NULL&&pOperateResult->cbOperateCode!=WIK_CHI_HU)
  393. {
  394. //设置变量
  395. m_wCurrentUser=pOperateResult->wOperateUser;
  396. //设置组合
  397. BYTE cbWeaveIndex=m_cbWeaveCount[wOperateUser]++;
  398. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbPublicCard=TRUE;
  399. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbCenterCard=cbOperateCard;
  400. m_WeaveItemArray[wOperateUser][cbWeaveIndex].cbWeaveKind=pOperateResult->cbOperateCode;
  401. m_WeaveItemArray[wOperateUser][cbWeaveIndex].wProvideUser=pOperateResult->wProvideUser;
  402. //组合界面
  403. BYTE cbWeaveCard[4]={0,0,0,0},cbWeaveKind=pOperateResult->cbOperateCode;
  404. BYTE cbWeaveCardCount=m_GameLogic.GetWeaveCard(cbWeaveKind,cbOperateCard,cbWeaveCard);
  405. //删除扑克
  406. m_GameLogic.RemoveCard(cbWeaveCard,cbWeaveCardCount,&cbOperateCard,1);
  407. m_GameLogic.RemoveCard(m_cbCardIndex[wOperateUser],cbWeaveCard,cbWeaveCardCount-1);
  408. }
  409. //设置时间
  410. if (m_wCurrentUser==m_pIAndroidUserItem->GetChairID())
  411. {
  412. //计算时间
  413. UINT nElapse=rand()%TIME_OPERATE_CARD+TIME_LESS;
  414. //设置时间
  415. m_pIAndroidUserItem->SetGameTimer(IDI_OPERATE_CARD,nElapse);
  416. }
  417. return true;
  418. }
  419. //用户出牌
  420. bool CAndroidUserItemSink::OnSubOutCard( const void *pBuffer,WORD wDataSize )
  421. {
  422. //效验消息
  423. ASSERT(wDataSize==sizeof(CMD_S_OutCard));
  424. if (wDataSize!=sizeof(CMD_S_OutCard)) return false;
  425. //消息处理
  426. CMD_S_OutCard * pOutCard=(CMD_S_OutCard *)pBuffer;
  427. //变量定义
  428. WORD wMeChairID=m_pIAndroidUserItem->GetChairID();
  429. //设置变量
  430. m_wCurrentUser=INVALID_CHAIR;
  431. m_wOutCardUser=pOutCard->wOutCardUser;
  432. ASSERT( pOutCard->cbOutCardData != 0 );
  433. m_cbOutCardData=pOutCard->cbOutCardData;
  434. //删除扑克
  435. if( wMeChairID != pOutCard->wOutCardUser )
  436. m_GameLogic.RemoveCard(m_cbCardIndex[pOutCard->wOutCardUser],pOutCard->cbOutCardData);
  437. return true;
  438. }
  439. //用户发牌
  440. bool CAndroidUserItemSink::OnSubSendCard( const void *pBuffer,WORD wDataSize )
  441. {
  442. //效验数据
  443. ASSERT(wDataSize==sizeof(CMD_S_SendCard));
  444. if (wDataSize!=sizeof(CMD_S_SendCard)) return false;
  445. //变量定义
  446. CMD_S_SendCard * pSendCard=(CMD_S_SendCard *)pBuffer;
  447. //设置变量
  448. WORD wMeChairID=m_pIAndroidUserItem->GetChairID();
  449. m_wCurrentUser=pSendCard->wCurrentUser;
  450. //丢弃扑克
  451. if ((m_wOutCardUser!=INVALID_CHAIR)&&(m_cbOutCardData!=0))
  452. {
  453. //丢弃扑克
  454. m_cbDiscardCard[m_wOutCardUser][m_cbDiscardCount[m_wOutCardUser]++] = m_cbOutCardData;
  455. //设置变量
  456. m_cbOutCardData=0;
  457. m_wOutCardUser=INVALID_CHAIR;
  458. }
  459. //发牌处理
  460. if (pSendCard->cbCardData!=0)
  461. {
  462. m_cbCardIndex[pSendCard->wCurrentUser][m_GameLogic.SwitchToCardIndex(pSendCard->cbCardData)]++;
  463. //扣除扑克
  464. m_cbLeftCardCount--;
  465. }
  466. //设置时间
  467. if( wMeChairID == m_wCurrentUser )
  468. {
  469. m_cbActionMask = pSendCard->cbActionMask;
  470. m_cbActionCard = pSendCard->cbCardData;
  471. //计算时间
  472. UINT nElapse=rand()%TIME_OPERATE_CARD+TIME_LESS;
  473. m_pIAndroidUserItem->SetGameTimer(IDI_OPERATE_CARD,nElapse);
  474. }
  475. return true;
  476. }
  477. //出牌
  478. void CAndroidUserItemSink::OnOutCard( BYTE cbOutCard )
  479. {
  480. //删除定时器
  481. m_pIAndroidUserItem->KillGameTimer(IDI_OPERATE_CARD);
  482. //设置变量
  483. m_wCurrentUser=INVALID_CHAIR;
  484. m_cbActionMask = WIK_NULL;
  485. m_cbActionCard = 0;
  486. //删除牌
  487. m_GameLogic.RemoveCard(m_cbCardIndex[m_pIAndroidUserItem->GetChairID()],cbOutCard);
  488. //发送数据
  489. CMD_C_OutCard OutCard;
  490. OutCard.cbCardData=cbOutCard;
  491. if( !m_pIAndroidUserItem->SendSocketData(SUB_C_OUT_CARD,&OutCard,sizeof(OutCard)) )
  492. {
  493. ASSERT( FALSE );
  494. return ;
  495. }
  496. return ;
  497. }
  498. //操作牌
  499. void CAndroidUserItemSink::OnOperateCard( BYTE cbOperateCode,BYTE cbOperateCard )
  500. {
  501. //删除时间
  502. m_pIAndroidUserItem->KillGameTimer(IDI_OPERATE_CARD);
  503. //设置变量
  504. m_cbActionMask = WIK_NULL;
  505. m_cbActionCard = 0;
  506. //发送命令
  507. CMD_C_OperateCard OperateCard;
  508. OperateCard.cbOperateCode=cbOperateCode;
  509. OperateCard.cbOperateCard = cbOperateCard;
  510. if( !m_pIAndroidUserItem->SendSocketData(SUB_C_OPERATE_CARD,&OperateCard,sizeof(OperateCard)) )
  511. {
  512. ASSERT( FALSE );
  513. return ;
  514. }
  515. return ;
  516. }
  517. //搜索听牌
  518. bool CAndroidUserItemSink::SearchTingCard( tagTingCardResult &TingCardResult )
  519. {
  520. //变量定义
  521. ZeroMemory(&TingCardResult,sizeof(TingCardResult));
  522. BYTE bAbandonCardCount=0;
  523. //构造扑克
  524. WORD wMeChairId = m_pIAndroidUserItem->GetChairID();
  525. BYTE cbCardIndexTemp[MAX_INDEX];
  526. CopyMemory(cbCardIndexTemp,m_cbCardIndex[wMeChairId],sizeof(cbCardIndexTemp));
  527. BYTE cbCardCount = m_GameLogic.GetCardCount(cbCardIndexTemp);
  528. if( (cbCardCount-2)%3 == 0 )
  529. {
  530. //听牌分析
  531. for (BYTE i=0;i<MAX_INDEX-ZI_PAI_COUNT;i++)
  532. {
  533. //空牌过滤
  534. if (cbCardIndexTemp[i]==0) continue;
  535. //听牌处理
  536. cbCardIndexTemp[i]--;
  537. //听牌判断
  538. bool bHuCard = false;
  539. bAbandonCardCount = TingCardResult.bAbandonCount;
  540. CChiHuRight chr;
  541. for (BYTE j=0;j<MAX_INDEX-ZI_PAI_COUNT;j++)
  542. {
  543. //胡牌分析
  544. BYTE cbCurrentCard=m_GameLogic.SwitchToCardData(j);
  545. BYTE cbHuCardKind=m_GameLogic.AnalyseChiHuCard(cbCardIndexTemp,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId],cbCurrentCard,chr);
  546. //结果判断
  547. if (cbHuCardKind!=WIK_NULL)
  548. {
  549. bHuCard = true;
  550. TingCardResult.bTingCard[bAbandonCardCount][TingCardResult.bTingCardCount[bAbandonCardCount]++] = cbCurrentCard;
  551. }
  552. }
  553. if( bHuCard == true )
  554. {
  555. TingCardResult.bAbandonCard[TingCardResult.bAbandonCount++] = m_GameLogic.SwitchToCardData(i);
  556. }
  557. //还原处理
  558. cbCardIndexTemp[i]++;
  559. }
  560. }
  561. else
  562. {
  563. //听牌判断
  564. bAbandonCardCount = TingCardResult.bAbandonCount;
  565. CChiHuRight chr;
  566. for (BYTE j=0;j<MAX_INDEX-ZI_PAI_COUNT;j++)
  567. {
  568. //胡牌分析
  569. BYTE cbCurrentCard=m_GameLogic.SwitchToCardData(j);
  570. BYTE cbHuCardKind=m_GameLogic.AnalyseChiHuCard(cbCardIndexTemp,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId],cbCurrentCard,chr);
  571. //结果判断
  572. if (cbHuCardKind!=WIK_NULL)
  573. {
  574. TingCardResult.bTingCard[bAbandonCardCount][TingCardResult.bTingCardCount[bAbandonCardCount]++] = cbCurrentCard;
  575. }
  576. }
  577. }
  578. //计算剩余牌
  579. BYTE n = 0;
  580. while( TingCardResult.bTingCardCount[n] > 0 )
  581. {
  582. TingCardResult.bRemainCount[n] = TingCardResult.bTingCardCount[n]*4;
  583. for( BYTE i = 0; i < TingCardResult.bTingCardCount[n]; i++ )
  584. {
  585. BYTE bCardData = TingCardResult.bTingCard[n][i];
  586. //减自己牌
  587. if( cbCardIndexTemp[m_GameLogic.SwitchToCardIndex(bCardData)] > 0 )
  588. {
  589. TingCardResult.bRemainCount[n] -= cbCardIndexTemp[m_GameLogic.SwitchToCardIndex(bCardData)];
  590. ASSERT( TingCardResult.bRemainCount[n]>=0 );
  591. }
  592. for( BYTE j = 0; j < GAME_PLAYER; j++ )
  593. {
  594. //减组合牌
  595. BYTE k = 0;
  596. for( ; k < m_cbWeaveCount[j]; k++ )
  597. {
  598. if( m_WeaveItemArray[j][k].cbCenterCard == bCardData )
  599. {
  600. TingCardResult.bRemainCount[n] -= m_WeaveItemArray[j][k].cbWeaveKind==WIK_GANG?4:3;
  601. ASSERT( TingCardResult.bRemainCount[n]>=0 );
  602. }
  603. }
  604. //减丢弃牌
  605. for( k = 0; k < m_cbDiscardCount[j]; k++ )
  606. {
  607. if( bCardData == m_cbDiscardCard[j][k] )
  608. {
  609. TingCardResult.bRemainCount[n]--;
  610. ASSERT( TingCardResult.bRemainCount[n]>=0 );
  611. }
  612. }
  613. }
  614. }
  615. n++;
  616. }
  617. return true;
  618. }
  619. //搜索出牌
  620. bool CAndroidUserItemSink::SearchOutCard( tagOutCardResult &OutCardResult )
  621. {
  622. //初始化
  623. ZeroMemory(&OutCardResult,sizeof(OutCardResult));
  624. WORD wMeChairId = m_pIAndroidUserItem->GetChairID();
  625. ASSERT( wMeChairId != INVALID_CHAIR );
  626. if( wMeChairId == INVALID_CHAIR ) return false;
  627. //判断胡
  628. if( (m_cbActionMask&WIK_CHI_HU) != WIK_NULL )
  629. {
  630. OutCardResult.cbOperateCode = WIK_CHI_HU;
  631. OutCardResult.cbOperateCard = m_cbActionCard;
  632. return true;
  633. }
  634. //转换索引
  635. BYTE byCard[MAX_COUNT],byCardCount = 0;
  636. for( BYTE i = 0; i < MAX_INDEX; i++ )
  637. {
  638. for( BYTE j = 0; j < m_cbCardIndex[wMeChairId][i]; j++ )
  639. {
  640. byCard[byCardCount++] = i;
  641. }
  642. }
  643. //判断听
  644. if( WIK_LISTEN == m_GameLogic.AnalyseTingCard(m_cbCardIndex[wMeChairId],m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]) )
  645. {
  646. tagTingCardResult TingCardResult;
  647. if( SearchTingCard(TingCardResult) )
  648. {
  649. BYTE bMostIndex = 0;
  650. int nMostCount = -1;
  651. BYTE i = 0;
  652. while(true)
  653. {
  654. if( TingCardResult.bTingCardCount[i] == 0 ) break;
  655. if( TingCardResult.bRemainCount[i] > nMostCount )
  656. {
  657. bMostIndex = i;
  658. nMostCount = TingCardResult.bRemainCount[i];
  659. }
  660. i++;
  661. }
  662. //有牌可听
  663. if( nMostCount > 0 )
  664. {
  665. //放弃操作
  666. if( wMeChairId != m_wCurrentUser ) return false;
  667. OutCardResult.cbOperateCode = WIK_NULL;
  668. OutCardResult.cbOperateCard = TingCardResult.bAbandonCard[bMostIndex];
  669. return true;
  670. }
  671. //听死牌
  672. else if( wMeChairId == m_wCurrentUser )
  673. {
  674. //机器AI
  675. CAndroidAI AndroidAi;
  676. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  677. AndroidAi.Think();
  678. //从组合中拆牌
  679. BYTE byBadlyCard = 0xff;
  680. if( byCardCount <= 2 )
  681. byBadlyCard = AndroidAi.GetBadlyCard();
  682. else
  683. byBadlyCard = AndroidAi.GetBadlyIn2Card();
  684. if( 0xff != byBadlyCard )
  685. {
  686. OutCardResult.cbOperateCode = WIK_NULL;
  687. OutCardResult.cbOperateCard = m_GameLogic.SwitchToCardData(byBadlyCard);
  688. return true;
  689. }
  690. else
  691. {
  692. //从最佳三只组合中拆牌
  693. byBadlyCard = AndroidAi.GetBadlyIn3Card();
  694. if( 0xff != byBadlyCard )
  695. {
  696. OutCardResult.cbOperateCode = WIK_NULL;
  697. OutCardResult.cbOperateCard = m_GameLogic.SwitchToCardData(byBadlyCard);
  698. return true;
  699. }
  700. }
  701. }
  702. }
  703. }
  704. BYTE cbActionCard = m_cbActionCard;
  705. //计算各种操作得分
  706. BYTE cbOperateCode[] = { WIK_GANG,WIK_PENG,WIK_LEFT,WIK_CENTER,WIK_RIGHT,WIK_NULL };
  707. int nOperateScore[] = { 0,0,0,0,0,0 };
  708. //计算原始分
  709. CAndroidAI AndroidAi;
  710. AndroidAi.SetEnjoinOutCard( NULL,0 );
  711. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  712. AndroidAi.Think();
  713. int nOrgScore = AndroidAi.GetMaxScore();
  714. //判断杠
  715. if( m_cbActionMask & WIK_GANG )
  716. {
  717. if( m_wCurrentUser == wMeChairId )
  718. {
  719. tagGangCardResult GangCardResult;
  720. m_GameLogic.AnalyseGangCard(m_cbCardIndex[wMeChairId],m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId],GangCardResult);
  721. //寻找最高分杠牌
  722. BYTE cbGangCard = 0;
  723. int nMaxGangScore = -1;
  724. for( BYTE i = 0; i < GangCardResult.cbCardCount; i++ )
  725. {
  726. ASSERT( m_cbCardIndex[wMeChairId][m_GameLogic.SwitchToCardIndex(GangCardResult.cbCardData[i])] > 0 );
  727. if( m_cbCardIndex[wMeChairId][m_GameLogic.SwitchToCardIndex(GangCardResult.cbCardData[i])] == 0 ) throw 0;
  728. //计算杠后得分
  729. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  730. AndroidAi.SetAction(WIK_GANG,m_GameLogic.SwitchToCardIndex(GangCardResult.cbCardData[i]));
  731. AndroidAi.Think();
  732. int nScore = AndroidAi.GetMaxScore();
  733. if( nScore > nMaxGangScore )
  734. {
  735. nMaxGangScore = nScore;
  736. cbGangCard = GangCardResult.cbCardData[i];
  737. }
  738. }
  739. ASSERT(nMaxGangScore!=-1&&cbGangCard!=0);
  740. cbActionCard = cbGangCard;
  741. nOperateScore[0] = nMaxGangScore-nOrgScore;
  742. }
  743. else
  744. {
  745. ASSERT( m_cbCardIndex[wMeChairId][m_GameLogic.SwitchToCardIndex(cbActionCard)] > 0 );
  746. if( m_cbCardIndex[wMeChairId][m_GameLogic.SwitchToCardIndex(cbActionCard)] == 0 ) throw 0;
  747. //计算杠后得分
  748. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  749. AndroidAi.SetAction(WIK_GANG,m_GameLogic.SwitchToCardIndex(cbActionCard));
  750. AndroidAi.Think();
  751. nOperateScore[0] = AndroidAi.GetMaxScore()-nOrgScore;
  752. }
  753. }
  754. //判断碰
  755. if( m_cbActionMask & WIK_PENG )
  756. {
  757. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  758. AndroidAi.SetAction(WIK_PENG,m_GameLogic.SwitchToCardIndex(cbActionCard));
  759. AndroidAi.Think();
  760. BYTE byBadlyIndex = AndroidAi.GetBadlyCard();
  761. if( byBadlyIndex == 0xff )
  762. {
  763. byBadlyIndex = AndroidAi.GetBadlyIn2Card();
  764. if( byBadlyIndex == 0xff )
  765. byBadlyIndex = AndroidAi.GetBadlyIn3Card();
  766. }
  767. if( byBadlyIndex != 0xff )
  768. {
  769. AndroidAi.RemoveCardData( byBadlyIndex );
  770. AndroidAi.Think();
  771. nOperateScore[1] = AndroidAi.GetMaxScore()-nOrgScore;
  772. }
  773. }
  774. //左吃
  775. if( m_cbActionMask & WIK_LEFT )
  776. {
  777. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  778. AndroidAi.SetAction(WIK_LEFT,m_GameLogic.SwitchToCardIndex(cbActionCard));
  779. AndroidAi.Think();
  780. BYTE byBadlyIndex = AndroidAi.GetBadlyCard();
  781. if( byBadlyIndex == 0xff )
  782. {
  783. byBadlyIndex = AndroidAi.GetBadlyIn2Card();
  784. if( byBadlyIndex == 0xff )
  785. byBadlyIndex = AndroidAi.GetBadlyIn3Card();
  786. }
  787. if( byBadlyIndex != 0xff )
  788. {
  789. AndroidAi.RemoveCardData( byBadlyIndex );
  790. AndroidAi.Think();
  791. nOperateScore[2] = AndroidAi.GetMaxScore()-nOrgScore;
  792. }
  793. }
  794. //中吃
  795. if( m_cbActionMask & WIK_CENTER )
  796. {
  797. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  798. AndroidAi.SetAction(WIK_CENTER,m_GameLogic.SwitchToCardIndex(cbActionCard));
  799. AndroidAi.Think();
  800. BYTE byBadlyIndex = AndroidAi.GetBadlyCard();
  801. if( byBadlyIndex == 0xff )
  802. {
  803. byBadlyIndex = AndroidAi.GetBadlyIn2Card();
  804. if( byBadlyIndex == 0xff )
  805. byBadlyIndex = AndroidAi.GetBadlyIn3Card();
  806. }
  807. if( byBadlyIndex != 0xff )
  808. {
  809. AndroidAi.RemoveCardData( byBadlyIndex );
  810. AndroidAi.Think();
  811. nOperateScore[3] = AndroidAi.GetMaxScore()-nOrgScore;
  812. }
  813. }
  814. //右吃
  815. if( m_cbActionMask & WIK_RIGHT )
  816. {
  817. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  818. AndroidAi.SetAction(WIK_RIGHT,m_GameLogic.SwitchToCardIndex(cbActionCard));
  819. AndroidAi.Think();
  820. BYTE byBadlyIndex = AndroidAi.GetBadlyCard();
  821. if( byBadlyIndex == 0xff )
  822. {
  823. byBadlyIndex = AndroidAi.GetBadlyIn2Card();
  824. if( byBadlyIndex == 0xff )
  825. byBadlyIndex = AndroidAi.GetBadlyIn3Card();
  826. }
  827. if( byBadlyIndex != 0xff )
  828. {
  829. AndroidAi.RemoveCardData( byBadlyIndex );
  830. AndroidAi.Think();
  831. nOperateScore[4] = AndroidAi.GetMaxScore()-nOrgScore;
  832. }
  833. }
  834. //搜索废牌
  835. BYTE cbOutCardData = cbActionCard;
  836. if( m_wCurrentUser == wMeChairId )
  837. {
  838. AndroidAi.SetCardData(byCard,byCardCount,m_WeaveItemArray[wMeChairId],m_cbWeaveCount[wMeChairId]);
  839. AndroidAi.Think();
  840. BYTE byBadlyIndex = AndroidAi.GetBadlyCard();
  841. if( byBadlyIndex == 0xff )
  842. {
  843. byBadlyIndex = AndroidAi.GetBadlyIn2Card();
  844. if( byBadlyIndex == 0xff )
  845. {
  846. byBadlyIndex = AndroidAi.GetBadlyIn3Card();
  847. ASSERT( byBadlyIndex != 0xff );
  848. if( byBadlyIndex == 0xff ) throw 0;
  849. }
  850. }
  851. AndroidAi.RemoveCardData( byBadlyIndex );
  852. AndroidAi.Think();
  853. nOperateScore[5] = AndroidAi.GetMaxScore()-nOrgScore;
  854. cbOutCardData = m_GameLogic.SwitchToCardData(byBadlyIndex);
  855. }
  856. //获取最高分操作
  857. BYTE cbIndex = 0;
  858. for( BYTE i = 1; i < CountArray(nOperateScore); i++ )
  859. {
  860. if( nOperateScore[cbIndex] < nOperateScore[i] )
  861. cbIndex = i;
  862. }
  863. if( (cbOperateCode[cbIndex]&m_cbActionMask) &&
  864. ( cbOperateCode[cbIndex]==WIK_GANG || nOperateScore[cbIndex] > 0 ) )
  865. {
  866. OutCardResult.cbOperateCode = cbOperateCode[cbIndex];
  867. OutCardResult.cbOperateCard = cbActionCard;
  868. return true;
  869. }
  870. else
  871. {
  872. if( m_wCurrentUser == wMeChairId )
  873. {
  874. OutCardResult.cbOperateCard = cbOutCardData;
  875. return true;
  876. }
  877. else return false;
  878. }
  879. ASSERT( FALSE );
  880. throw 0;
  881. }
  882. //////////////////////////////////////////////////////////////////////////