诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3725 line
92 KiB

  1. #include "StdAfx.h"
  2. #include "GameLogic.h"
  3. #include "math.h"
  4. #include "TableFrameSink_tdh.h"
  5. #include "fstream"
  6. //////////////////////////////////////////////////////////////////////////
  7. //静态变量
  8. //bool CChiHuRight::m_bInit = false;
  9. //DWORD CChiHuRight::m_dwRightMask[MAX_RIGHT_COUNT];
  10. //
  11. ////构造函数
  12. //CChiHuRight::CChiHuRight()
  13. //{
  14. // ZeroMemory( m_dwRight,sizeof(m_dwRight) );
  15. //
  16. // if( !m_bInit )
  17. // {
  18. // m_bInit = true;
  19. // for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
  20. // {
  21. // if( 0 == i )
  22. // m_dwRightMask[i] = 0;
  23. // else
  24. // m_dwRightMask[i] = (DWORD(pow(2.0,i-1)))<<28;
  25. // }
  26. // }
  27. //}
  28. //
  29. ////赋值符重载
  30. //CChiHuRight & CChiHuRight::operator = ( DWORD dwRight )
  31. //{
  32. // DWORD dwOtherRight = 0;
  33. // //验证权位
  34. // if( !IsValidRight( dwRight ) )
  35. // {
  36. // //验证取反权位
  37. // ASSERT( IsValidRight( ~dwRight ) );
  38. // if( !IsValidRight( ~dwRight ) ) return *this;
  39. // dwRight = ~dwRight;
  40. // dwOtherRight = MASK_CHI_HU_RIGHT;
  41. // }
  42. //
  43. // for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
  44. // {
  45. // if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
  46. // m_dwRight[i] = dwRight&MASK_CHI_HU_RIGHT;
  47. // else m_dwRight[i] = dwOtherRight;
  48. // }
  49. //
  50. // return *this;
  51. //}
  52. //
  53. ////与等于
  54. //CChiHuRight & CChiHuRight::operator &= ( DWORD dwRight )
  55. //{
  56. // bool bNavigate = false;
  57. // //验证权位
  58. // if( !IsValidRight( dwRight ) )
  59. // {
  60. // //验证取反权位
  61. // ASSERT( IsValidRight( ~dwRight ) );
  62. // if( !IsValidRight( ~dwRight ) ) return *this;
  63. // //调整权位
  64. // DWORD dwHeadRight = (~dwRight)&0xF0000000;
  65. // DWORD dwTailRight = dwRight&MASK_CHI_HU_RIGHT;
  66. // dwRight = dwHeadRight|dwTailRight;
  67. // bNavigate = true;
  68. // }
  69. //
  70. // for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
  71. // {
  72. // if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
  73. // {
  74. // m_dwRight[i] &= (dwRight&MASK_CHI_HU_RIGHT);
  75. // }
  76. // else if( !bNavigate )
  77. // m_dwRight[i] = 0;
  78. // }
  79. //
  80. // return *this;
  81. //}
  82. //
  83. ////或等于
  84. //CChiHuRight & CChiHuRight::operator |= ( DWORD dwRight )
  85. //{
  86. // //验证权位
  87. // if( !IsValidRight( dwRight ) ) return *this;
  88. //
  89. // for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
  90. // {
  91. // if( (dwRight&m_dwRightMask[i]) || (i==0&&dwRight<0x10000000) )
  92. // m_dwRight[i] |= (dwRight&MASK_CHI_HU_RIGHT);
  93. // }
  94. //
  95. // return *this;
  96. //}
  97. ////异或等于
  98. //CChiHuRight & CChiHuRight::operator -= (DWORD dwRight)
  99. //{
  100. // //验证权位
  101. // if (!IsValidRight(dwRight)) return *this;
  102. //
  103. // for (BYTE i = 0; i < CountArray(m_dwRightMask); i++)
  104. // {
  105. // if ((dwRight&m_dwRightMask[i]) || (i == 0 && dwRight < 0x10000000))
  106. // if (m_dwRight[i]&dwRight)
  107. // {
  108. // m_dwRight[i] ^= dwRight;
  109. // }
  110. //
  111. // }
  112. //
  113. // return *this;
  114. //}
  115. //
  116. ////与
  117. //CChiHuRight CChiHuRight::operator & ( DWORD dwRight )
  118. //{
  119. // CChiHuRight chr = *this;
  120. // return (chr &= dwRight);
  121. //}
  122. //
  123. ////与
  124. //CChiHuRight CChiHuRight::operator & ( DWORD dwRight ) const
  125. //{
  126. // CChiHuRight chr = *this;
  127. // return (chr &= dwRight);
  128. //}
  129. //
  130. ////或
  131. //CChiHuRight CChiHuRight::operator | ( DWORD dwRight )
  132. //{
  133. // CChiHuRight chr = *this;
  134. // return chr |= dwRight;
  135. //}
  136. //
  137. ////或
  138. //CChiHuRight CChiHuRight::operator | ( DWORD dwRight ) const
  139. //{
  140. // CChiHuRight chr = *this;
  141. // return chr |= dwRight;
  142. //}
  143. //
  144. ////是否权位为空
  145. //bool CChiHuRight::IsEmpty()
  146. //{
  147. // for( BYTE i = 0; i < CountArray(m_dwRight); i++ )
  148. // if( m_dwRight[i] ) return false;
  149. // return true;
  150. //}
  151. //
  152. ////设置权位为空
  153. //void CChiHuRight::SetEmpty()
  154. //{
  155. // ZeroMemory( m_dwRight,sizeof(m_dwRight) );
  156. // return;
  157. //}
  158. //
  159. ////获取权位数值
  160. //BYTE CChiHuRight::GetRightData( DWORD dwRight[], BYTE cbMaxCount )
  161. //{
  162. // ASSERT( cbMaxCount >= CountArray(m_dwRight) );
  163. // if( cbMaxCount < CountArray(m_dwRight) ) return 0;
  164. //
  165. // CopyMemory( dwRight,m_dwRight,sizeof(DWORD)*CountArray(m_dwRight) );
  166. // return CountArray(m_dwRight);
  167. //}
  168. //
  169. ////设置权位数值
  170. //bool CChiHuRight::SetRightData( const DWORD dwRight[], BYTE cbRightCount )
  171. //{
  172. // ASSERT( cbRightCount <= CountArray(m_dwRight) );
  173. // if( cbRightCount > CountArray(m_dwRight) ) return false;
  174. //
  175. // ZeroMemory( m_dwRight,sizeof(m_dwRight) );
  176. // CopyMemory( m_dwRight,dwRight,sizeof(DWORD)*cbRightCount );
  177. //
  178. // return true;
  179. //}
  180. //
  181. ////检查仅位是否正确
  182. //bool CChiHuRight::IsValidRight( DWORD dwRight )
  183. //{
  184. // DWORD dwRightHead = dwRight & 0xF0000000;
  185. // for( BYTE i = 0; i < CountArray(m_dwRightMask); i++ )
  186. // if( m_dwRightMask[i] == dwRightHead ) return true;
  187. // return false;
  188. //}
  189. //////////////////////////////////////////////////////////////////////////
  190. //////////////////////////////////////////////////////////////////////////
  191. //静态变量
  192. //麻将数据
  193. BYTE const CGameLogic_tdh::m_cbCardDataArray_ZJ[MAX_REPERTORY_ZJ] =
  194. {
  195. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  196. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  197. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  198. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  199. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  200. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  201. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  202. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  203. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  204. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  205. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  206. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  207. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  208. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  209. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  210. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北 中发白
  211. };
  212. //////////////////////////////////////////////////////////////////////////
  213. BYTE const CGameLogic_tdh::m_cbCardDataArray_ZJ_Two[MAX_REPERTORY_ZJ_Two] =
  214. {
  215. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  216. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  217. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  218. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  219. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  220. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  221. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  222. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  223. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  224. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  225. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  226. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北 中发白
  227. };
  228. //构造函数
  229. CGameLogic_tdh::CGameLogic_tdh(CTableFrameSink_tdh* pTableFramSink)
  230. {
  231. m_cbMagicIndexFirst = MAX_INDEX;
  232. m_cbMagicIndexSecond = MAX_INDEX;
  233. m_pTableFramSink = pTableFramSink;
  234. mIsBaoMjType = 0;
  235. }
  236. //析构函数
  237. CGameLogic_tdh::~CGameLogic_tdh()
  238. {
  239. }
  240. //混乱扑克
  241. BYTE CGameLogic_tdh::RandCardData(BYTE cbCardData[])
  242. {
  243. BYTE cbCardDataTemp[MAX_REPERTORY_ZJ];
  244. BYTE cbMaxCount = 0;
  245. CopyMemory(cbCardDataTemp, m_cbCardDataArray_ZJ, sizeof(m_cbCardDataArray_ZJ));
  246. cbMaxCount = MAX_REPERTORY_ZJ;
  247. //}
  248. //混乱扑克
  249. BYTE cbRandCount = 0, cbPosition = 0;
  250. do
  251. {
  252. cbPosition = rand() % (cbMaxCount - cbRandCount);
  253. cbCardData[cbRandCount++] = cbCardDataTemp[cbPosition];
  254. cbCardDataTemp[cbPosition] = cbCardDataTemp[cbMaxCount - cbRandCount];
  255. } while (cbRandCount < cbMaxCount);
  256. cbRandCount = 0, cbPosition = 0;
  257. ZeroMemory(cbCardDataTemp, sizeof(cbCardDataTemp));
  258. CopyMemory(cbCardDataTemp, cbCardData, sizeof(cbCardDataTemp));
  259. ZeroMemory(cbCardData, sizeof(cbCardData));
  260. do
  261. {
  262. cbPosition = rand() % (cbMaxCount - cbRandCount);
  263. cbCardData[cbRandCount++] = cbCardDataTemp[cbPosition];
  264. cbCardDataTemp[cbPosition] = cbCardDataTemp[cbMaxCount - cbRandCount];
  265. } while (cbRandCount < cbMaxCount);
  266. return cbMaxCount;
  267. }
  268. BYTE CGameLogic_tdh::RandCardData_Two(BYTE cbCardData[])
  269. {
  270. BYTE cbCardDataTemp[MAX_REPERTORY_ZJ_Two];
  271. BYTE cbMaxCount = 0;
  272. CopyMemory(cbCardDataTemp, m_cbCardDataArray_ZJ_Two, sizeof(m_cbCardDataArray_ZJ_Two));
  273. cbMaxCount = MAX_REPERTORY_ZJ_Two;
  274. //}
  275. //混乱扑克
  276. BYTE cbRandCount = 0, cbPosition = 0;
  277. srand((unsigned)time(NULL));
  278. do
  279. {
  280. cbPosition = rand() % (cbMaxCount - cbRandCount);
  281. cbCardData[cbRandCount++] = cbCardDataTemp[cbPosition];
  282. cbCardDataTemp[cbPosition] = cbCardDataTemp[cbMaxCount - cbRandCount];
  283. } while (cbRandCount < cbMaxCount);
  284. cbRandCount = 0, cbPosition = 0;
  285. ZeroMemory(cbCardDataTemp, sizeof(cbCardDataTemp));
  286. CopyMemory(cbCardDataTemp, cbCardData, sizeof(cbCardDataTemp));
  287. ZeroMemory(cbCardData, sizeof(cbCardData));
  288. srand((unsigned)time(NULL));
  289. do
  290. {
  291. cbPosition = rand() % (cbMaxCount - cbRandCount);
  292. cbCardData[cbRandCount++] = cbCardDataTemp[cbPosition];
  293. cbCardDataTemp[cbPosition] = cbCardDataTemp[cbMaxCount - cbRandCount];
  294. } while (cbRandCount < cbMaxCount);
  295. return cbMaxCount;
  296. }
  297. //删除扑克
  298. bool CGameLogic_tdh::RemoveCard(BYTE cbCardIndex[MAX_INDEX], BYTE cbRemoveCard)
  299. {
  300. //效验扑克
  301. ASSERT(IsValidCard(cbRemoveCard));
  302. ASSERT(cbCardIndex[SwitchToCardIndex(cbRemoveCard)]>0);
  303. //删除扑克
  304. BYTE cbRemoveIndex=SwitchToCardIndex(cbRemoveCard);
  305. if (cbCardIndex[cbRemoveIndex]>0)
  306. {
  307. cbCardIndex[cbRemoveIndex]--;
  308. return true;
  309. }
  310. //失败效验
  311. ASSERT(FALSE);
  312. return false;
  313. }
  314. //删除扑克
  315. bool CGameLogic_tdh::RemoveCard(BYTE cbCardIndex[MAX_INDEX], const BYTE cbRemoveCard[], BYTE cbRemoveCount)
  316. {
  317. //删除扑克
  318. for (BYTE i=0;i<cbRemoveCount;i++)
  319. {
  320. //效验扑克
  321. ASSERT(IsValidCard(cbRemoveCard[i]));
  322. ASSERT(cbCardIndex[SwitchToCardIndex(cbRemoveCard[i])]>0);
  323. //删除扑克
  324. BYTE cbRemoveIndex=SwitchToCardIndex(cbRemoveCard[i]);
  325. if (cbCardIndex[cbRemoveIndex]==0)
  326. {
  327. //错误断言
  328. ASSERT(FALSE);
  329. //还原删除
  330. for (BYTE j=0;j<i;j++)
  331. {
  332. ASSERT(IsValidCard(cbRemoveCard[j]));
  333. cbCardIndex[SwitchToCardIndex(cbRemoveCard[j])]++;
  334. }
  335. return false;
  336. }
  337. else
  338. {
  339. //删除扑克
  340. --cbCardIndex[cbRemoveIndex];
  341. }
  342. }
  343. return true;
  344. }
  345. //删除扑克
  346. bool CGameLogic_tdh::RemoveCard(BYTE cbCardData[], BYTE cbCardCount, const BYTE cbRemoveCard[], BYTE cbRemoveCount)
  347. {
  348. //检验数据
  349. ASSERT(cbCardCount<=14);
  350. ASSERT(cbRemoveCount<=cbCardCount);
  351. //定义变量
  352. BYTE cbDeleteCount=0,cbTempCardData[14];
  353. if (cbCardCount>CountArray(cbTempCardData))
  354. return false;
  355. CopyMemory(cbTempCardData,cbCardData,cbCardCount*sizeof(cbCardData[0]));
  356. //置零扑克
  357. for (BYTE i=0;i<cbRemoveCount;i++)
  358. {
  359. for (BYTE j=0;j<cbCardCount;j++)
  360. {
  361. if (cbRemoveCard[i]==cbTempCardData[j])
  362. {
  363. cbDeleteCount++;
  364. cbTempCardData[j]=0;
  365. break;
  366. }
  367. }
  368. }
  369. //成功判断
  370. if (cbDeleteCount!=cbRemoveCount)
  371. {
  372. ASSERT(FALSE);
  373. return false;
  374. }
  375. //清理扑克
  376. BYTE cbCardPos=0;
  377. for (BYTE i=0;i<cbCardCount;i++)
  378. {
  379. if (cbTempCardData[i]!=0)
  380. cbCardData[cbCardPos++]=cbTempCardData[i];
  381. }
  382. return true;
  383. }
  384. void CGameLogic_tdh::SetMagicIndex(BYTE CaiFirstIndex, BYTE CaiSecondIndex){
  385. if (CaiFirstIndex==MAX_INDEX&&CaiSecondIndex==MAX_INDEX)
  386. {
  387. m_BaoMj_MagicType = MagicType_NoMagic;
  388. return;
  389. }
  390. if (CaiSecondIndex==MAX_INDEX)
  391. {
  392. m_BaoMj_MagicType = MagicType_OneMagic;
  393. m_cbMagicIndexFirst = CaiFirstIndex;
  394. m_cbMagicIndexSecond = CaiSecondIndex;
  395. }
  396. else
  397. {
  398. m_BaoMj_MagicType = MagicType_TwoMagic;
  399. m_cbMagicIndexFirst = CaiFirstIndex;
  400. m_cbMagicIndexSecond = CaiSecondIndex;
  401. }
  402. }
  403. //有效判断
  404. bool CGameLogic_tdh::IsValidCard(BYTE cbCardData)
  405. {
  406. BYTE cbValue=(cbCardData&MASK_VALUE);
  407. BYTE cbColor=(cbCardData&MASK_COLOR)>>4;
  408. return (((cbValue>=1)&&(cbValue<=9)&&(cbColor<=2))||((cbValue>=1)&&(cbValue<=7)&&(cbColor==3)));
  409. }
  410. //扑克数目
  411. BYTE CGameLogic_tdh::GetCardCount(const BYTE cbCardIndex[MAX_INDEX])
  412. {
  413. //数目统计
  414. BYTE cbCardCount=0;
  415. for (BYTE i=0;i<MAX_INDEX;i++)
  416. cbCardCount+=cbCardIndex[i];
  417. return cbCardCount;
  418. }
  419. //获取组合
  420. BYTE CGameLogic_tdh::GetWeaveCard(int cbWeaveKind, BYTE cbCenterCard, const BYTE cbMargicOffset[4], BYTE cbCardBuffer[4])
  421. {
  422. //组合扑克
  423. switch (cbWeaveKind)
  424. {
  425. case WIK_LEFT: //上牌操作
  426. {
  427. //设置变量
  428. cbCardBuffer[0]=cbCenterCard;
  429. cbCardBuffer[1]=cbCenterCard+1;
  430. cbCardBuffer[2]=cbCenterCard+2;
  431. return 3;
  432. }
  433. case WIK_RIGHT: //上牌操作
  434. {
  435. //设置变量
  436. cbCardBuffer[0]=cbCenterCard;
  437. cbCardBuffer[1]=cbCenterCard-1;
  438. cbCardBuffer[2]=cbCenterCard-2;
  439. return 3;
  440. }
  441. case WIK_CENTER: //上牌操作
  442. {
  443. //设置变量
  444. cbCardBuffer[0]=cbCenterCard;
  445. cbCardBuffer[1]=cbCenterCard-1;
  446. cbCardBuffer[2]=cbCenterCard+1;
  447. return 3;
  448. }
  449. case WIK_PENG: //碰牌操作
  450. {
  451. //设置变量
  452. cbCardBuffer[0]=cbCenterCard;
  453. cbCardBuffer[1]=cbCenterCard;
  454. cbCardBuffer[2]=cbCenterCard;
  455. return 3;
  456. }
  457. case WIK_AN_GANG: //杠牌操作
  458. {
  459. //设置变量
  460. cbCardBuffer[0]=cbCenterCard;
  461. cbCardBuffer[1]=cbCenterCard;
  462. cbCardBuffer[2]=cbCenterCard;
  463. cbCardBuffer[3]=cbCenterCard;
  464. return 4;
  465. }
  466. case WIK_MING_GANG: //明杠牌操作
  467. {
  468. //设置变量
  469. cbCardBuffer[0] = cbCenterCard;
  470. cbCardBuffer[1] = cbCenterCard;
  471. cbCardBuffer[2] = cbCenterCard;
  472. cbCardBuffer[3] = cbCenterCard;
  473. return 4;
  474. }
  475. case WIK_BU_GANG:
  476. {
  477. cbCardBuffer[0] = cbCenterCard;
  478. cbCardBuffer[1] = cbCenterCard;
  479. cbCardBuffer[2] = cbCenterCard;
  480. cbCardBuffer[3] = cbCenterCard;
  481. return 4;
  482. }
  483. case WIK_DAN_AN_GANG: //暗杠牌操作
  484. {
  485. //设置变量
  486. cbCardBuffer[0] = cbCenterCard;
  487. cbCardBuffer[1] = cbMargicOffset[0];
  488. cbCardBuffer[2] = cbCenterCard;
  489. cbCardBuffer[3] = cbCenterCard;
  490. return 4;
  491. }
  492. case WIK_DAN_MING_GANG:
  493. {
  494. //设置变量
  495. cbCardBuffer[0] = cbCenterCard;
  496. cbCardBuffer[1] = cbMargicOffset[0];
  497. cbCardBuffer[2] = cbCenterCard;
  498. cbCardBuffer[3] = cbCenterCard;
  499. return 4;
  500. }
  501. case WIK_DAN_BU_GANG:
  502. {
  503. //设置变量
  504. cbCardBuffer[0] = cbCenterCard;
  505. cbCardBuffer[1] = cbMargicOffset[0];
  506. cbCardBuffer[2] = cbCenterCard;
  507. cbCardBuffer[3] = cbCenterCard;
  508. return 4;
  509. }
  510. case WIK_DAN_PENG:
  511. {
  512. cbCardBuffer[0] = cbCenterCard;
  513. cbCardBuffer[1] = cbMargicOffset[0];
  514. cbCardBuffer[2] = cbCenterCard;
  515. return 3;
  516. }
  517. case WIK_DAN_CHI:
  518. {
  519. cbCardBuffer[0] = cbCenterCard;
  520. cbCardBuffer[1] = cbMargicOffset[0];
  521. cbCardBuffer[2] = cbMargicOffset[1];
  522. return 3;
  523. }
  524. case WIK_SHUANG_MING_GANG:
  525. {
  526. //设置变量
  527. cbCardBuffer[0] = cbCenterCard;
  528. cbCardBuffer[1] = cbMargicOffset[0];
  529. cbCardBuffer[2] = cbMargicOffset[1];
  530. cbCardBuffer[3] = cbCenterCard;
  531. return 4;
  532. }
  533. case WIK_SHUANG_AN_GANG:
  534. {
  535. //设置变量
  536. cbCardBuffer[0] = cbCenterCard;
  537. cbCardBuffer[1] = cbMargicOffset[0];
  538. cbCardBuffer[2] = cbMargicOffset[1];
  539. cbCardBuffer[3] = cbCenterCard;
  540. return 4;
  541. }
  542. case WIK_SHUANG_PENG:
  543. {
  544. cbCardBuffer[0] = cbCenterCard;
  545. cbCardBuffer[1] = cbMargicOffset[0];
  546. cbCardBuffer[2] = cbMargicOffset[1];
  547. return 3;
  548. }
  549. case WIK_SHUANG_CAICHI:
  550. {
  551. cbCardBuffer[0] = cbCenterCard;
  552. cbCardBuffer[1] = cbMargicOffset[0];
  553. cbCardBuffer[2] = cbMargicOffset[1];
  554. return 3;
  555. }
  556. case WIK_SAN_MING_GANG:
  557. {
  558. //设置变量
  559. cbCardBuffer[0] = cbCenterCard;
  560. cbCardBuffer[1] = cbMargicOffset[0];
  561. cbCardBuffer[2] = cbMargicOffset[1];
  562. cbCardBuffer[3] = cbMargicOffset[2];
  563. return 4;
  564. }
  565. case WIK_SAN_AN_GANG:
  566. {
  567. //设置变量
  568. cbCardBuffer[0] = cbCenterCard;
  569. cbCardBuffer[1] = cbMargicOffset[0];
  570. cbCardBuffer[2] = cbMargicOffset[1];
  571. cbCardBuffer[3] = cbMargicOffset[2];
  572. return 4;
  573. }
  574. case WIK_QUANG_AN_GANG:
  575. {
  576. //设置变量
  577. cbCardBuffer[0] = cbMargicOffset[0];
  578. cbCardBuffer[1] = cbMargicOffset[1];
  579. cbCardBuffer[2] = cbMargicOffset[2];
  580. cbCardBuffer[3] = cbMargicOffset[3];
  581. return 4;
  582. }
  583. default:
  584. {
  585. ASSERT(FALSE);
  586. }
  587. }
  588. return 0;
  589. }
  590. //动作等级,操作特别多
  591. BYTE CGameLogic_tdh::GetUserActionRank(int cbUserAction)
  592. {
  593. //抢杠胡
  594. if (cbUserAction&WIK_ZI_MO) { return 13; }
  595. //胡牌等级
  596. if (cbUserAction&(WIK_CHI_HU | WIK_DI_CHIHU) ) { return 12; }
  597. //杠牌等级
  598. if (cbUserAction&WIK_MING_GANG) { return 11; }
  599. //碰牌等级
  600. if (cbUserAction&WIK_PENG) { return 10; }
  601. //上牌等级
  602. if (cbUserAction&(WIK_RIGHT | WIK_CENTER | WIK_LEFT)) { return 9; }
  603. //单财明杠
  604. if (cbUserAction&WIK_DAN_MING_GANG)
  605. {
  606. return 8;
  607. }
  608. //单财神碰
  609. if (cbUserAction&WIK_DAN_PENG) { return 7; }
  610. //单财神上牌等级
  611. if (cbUserAction&WIK_DAN_CHI) { return 6; }
  612. //双财明杠
  613. if (cbUserAction&WIK_SHUANG_MING_GANG){ return 5; }
  614. //双财神碰
  615. if (cbUserAction&WIK_SHUANG_PENG)return 4;
  616. //双财吃
  617. if (cbUserAction&WIK_SHUANG_CAICHI)return 3;
  618. //三财明杠
  619. if (cbUserAction&WIK_SAN_MING_GANG)return 2;
  620. if (cbUserAction&WIK_ZAHU)return 1;
  621. if (cbUserAction == WIK_NULL )
  622. {
  623. return 0;
  624. }
  625. ASSERT(FALSE);
  626. return 0;
  627. }
  628. //吃牌判断
  629. int CGameLogic_tdh::EstimateEatCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard)
  630. {
  631. //参数效验
  632. ASSERT(IsValidCard(cbCurrentCard));
  633. //过滤判断
  634. if ( cbCurrentCard>=0x31 || IsMagicCard(cbCurrentCard) )
  635. return WIK_NULL;
  636. //吃牌判断
  637. int cbEatKind = 0;
  638. BYTE cbCurrentIndex=SwitchToCardIndex(cbCurrentCard);
  639. //获取手牌财神牌数目
  640. // BYTE CaiShenCount = GetMaigcCardCount(cbCardIndex);
  641. // if (CaiShenCount > 1)
  642. // {
  643. // cbEatKind = WIK_SHUANG_CAICHI;
  644. // }
  645. // if (CaiShenCount > 0)
  646. // {
  647. // BYTE TempCardIndex[MAX_INDEX_TUIDAOHU] = { 0 };
  648. // CopyMemory(TempCardIndex, cbCardIndex, sizeof(TempCardIndex));
  649. //// TempCardIndex[m_cbMagicIndexFirst] = 0;
  650. //// TempCardIndex[m_cbMagicIndexSecond] = 0;
  651. // DeleteMagicCards(TempCardIndex);
  652. // BYTE cbFirstIndex = 0;
  653. // BYTE cbExcursion[3] = { 0, 1, 2 };
  654. // BYTE cbItemKind[3] = { WIK_DAN_CHI, WIK_DAN_CHI, WIK_DAN_CHI };
  655. // for (BYTE i = 0; i < CountArray(cbItemKind); i++)
  656. // {
  657. // BYTE cbValueIndex = cbCurrentIndex % 9;
  658. // if ((cbValueIndex >= cbExcursion[i]) && ((cbValueIndex - cbExcursion[i]) <= 6))
  659. // {
  660. // //吃牌判断
  661. // cbFirstIndex = cbCurrentIndex - cbExcursion[i];
  662. //
  663. // if ((TempCardIndex[cbFirstIndex ] >= 1 && (cbFirstIndex != cbCurrentIndex))
  664. // ||(TempCardIndex[cbFirstIndex + 1] >= 1 && (cbFirstIndex + 1 != cbCurrentIndex))
  665. // || ((cbFirstIndex + 2 != cbCurrentIndex) && TempCardIndex[cbFirstIndex + 2] >= 1))
  666. // {
  667. //
  668. // cbEatKind |= cbItemKind[i];
  669. // }
  670. // }
  671. // }
  672. // }
  673. BYTE cbExcursion[3] = { 0, 1, 2 };
  674. BYTE cbItemKind[3] = { WIK_LEFT, WIK_CENTER, WIK_RIGHT };
  675. //吃牌判断
  676. BYTE cbFirstIndex = 0;
  677. BYTE szTmpIndex[MAX_INDEX] = { 0 };
  678. CopyMemory(szTmpIndex, cbCardIndex, MAX_INDEX);
  679. DeleteMagicCards(szTmpIndex);//删除财神牌,再来判断是否吃
  680. for (BYTE i = 0; i < CountArray(cbItemKind); i++)
  681. {
  682. BYTE cbValueIndex = cbCurrentIndex % 9;
  683. if ((cbValueIndex >= cbExcursion[i]) && ((cbValueIndex - cbExcursion[i]) <= 6))
  684. {
  685. //吃牌判断
  686. cbFirstIndex = cbCurrentIndex - cbExcursion[i];
  687. if ((cbCurrentIndex != cbFirstIndex) && (szTmpIndex[cbFirstIndex] == 0))
  688. continue;
  689. if ((cbCurrentIndex != (cbFirstIndex + 1)) && (szTmpIndex[cbFirstIndex + 1] == 0))
  690. continue;
  691. if ((cbCurrentIndex != (cbFirstIndex + 2)) && (szTmpIndex[cbFirstIndex + 2] == 0))
  692. continue;
  693. //设置类型
  694. cbEatKind |= cbItemKind[i];
  695. }
  696. }
  697. return cbEatKind;
  698. }
  699. //碰牌判断
  700. int CGameLogic_tdh::EstimatePengCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard)
  701. {
  702. int Operator = 0;
  703. //参数效验
  704. ASSERT(IsValidCard(cbCurrentCard));
  705. //过滤判断
  706. if (IsMagicCard(cbCurrentCard))
  707. return WIK_NULL;
  708. //BYTE CaiShenCount = GetMaigcCardCount(cbCardIndex);
  709. //if (CaiShenCount>1)
  710. //{
  711. // Operator = WIK_SHUANG_PENG;
  712. //}
  713. //if (CaiShenCount>0)
  714. //{
  715. // if (cbCardIndex[SwitchToCardIndex(cbCurrentCard)]>0)
  716. // {
  717. // Operator |= WIK_DAN_PENG;
  718. // }
  719. //}
  720. Operator |= ((cbCardIndex[SwitchToCardIndex(cbCurrentCard)] >= 2) ? WIK_PENG : WIK_NULL);
  721. //碰牌判断
  722. return Operator;
  723. }
  724. //杠牌判断
  725. int CGameLogic_tdh::EstimateGangCard(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCurrentCard)
  726. {
  727. int Operator = WIK_NULL;
  728. //参数效验
  729. ASSERT(IsValidCard(cbCurrentCard));
  730. //过滤判断
  731. if ( IsMagicCard(cbCurrentCard) )
  732. return WIK_NULL;
  733. BYTE index = SwitchToCardIndex(cbCurrentCard);
  734. //BYTE CaiShenCount = GetMaigcCardCount(cbCardIndex);
  735. //if (CaiShenCount > 2)
  736. //{
  737. // Operator = WIK_SAN_MING_GANG;
  738. //}
  739. //if (CaiShenCount > 1)
  740. //{
  741. // if (cbCardIndex[index] > 0)
  742. // Operator |= WIK_SHUANG_MING_GANG;
  743. //}
  744. //if (CaiShenCount > 0)
  745. //{
  746. // if (cbCardIndex[index] > 1)
  747. // {
  748. // Operator |= WIK_DAN_MING_GANG;
  749. // }
  750. //}
  751. Operator |= (cbCardIndex[index] == 3) ? WIK_MING_GANG : WIK_NULL;
  752. //杠牌判断
  753. return Operator;
  754. }
  755. //杠牌分析
  756. int CGameLogic_tdh::AnalyseGangCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, tagGangCardResult & GangCardResult)
  757. {
  758. //设置变量
  759. int cbActionMask = WIK_NULL;
  760. BYTE TempCardIndex[MAX_INDEX];
  761. ZeroMemory(TempCardIndex, sizeof(TempCardIndex));
  762. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  763. CopyMemory(TempCardIndex, cbCardIndex, sizeof(TempCardIndex));
  764. BYTE nMagicCount = GetMaigcCardCount(cbCardIndex);
  765. //手上杠牌
  766. for (BYTE i = 0; i < MAX_INDEX; i++)
  767. {
  768. if (IsMagicCard(SwitchToCardData(i)))
  769. {
  770. continue;
  771. }
  772. if (cbCardIndex[i] == 4)
  773. {
  774. BYTE cbCardData = SwitchToCardData(i);
  775. cbActionMask |= WIK_AN_GANG;
  776. if (GangCardResult.cbCardCount < 6){
  777. GangCardResult.cbCardData[GangCardResult.cbCardCount++] = cbCardData;
  778. }
  779. }
  780. }
  781. //if (nMagicCount > 0)//单财杠
  782. //{
  783. // for (BYTE i = 0; i < MAX_INDEX_TUIDAOHU; i++)
  784. // {
  785. // if (IsMagicCard(SwitchToCardData(i)))
  786. // {
  787. // continue;
  788. // }
  789. // if (TempCardIndex[i] >= 3)
  790. // {
  791. // cbActionMask |= WIK_DAN_AN_GANG;
  792. // if (GangCardResult.cbCardCount < 6){
  793. // GangCardResult.cbCardData[GangCardResult.cbCardCount++] = SwitchToCardData(i) | 0x0200;
  794. // }
  795. // }
  796. // }
  797. //}
  798. // [9/4/2017 Zoro]
  799. //先计算组合正杠
  800. //组合杠牌
  801. for (BYTE i = 0; i < cbWeaveCount; i++)
  802. {
  803. if (WeaveItem[i].cbWeaveKind & (WIK_PENG | WIK_DAN_PENG | WIK_SHUANG_PENG))
  804. {
  805. if (cbCardIndex[SwitchToCardIndex(WeaveItem[i].cbCenterCard)] >= 1)
  806. {
  807. cbActionMask |= WIK_BU_GANG;
  808. if (GangCardResult.cbCardCount < 6){
  809. GangCardResult.cbCardData[GangCardResult.cbCardCount++] = WeaveItem[i].cbCenterCard | 0x0100;
  810. }
  811. }
  812. }
  813. }
  814. //在计算组合单财杠
  815. //for (BYTE i = 0; i < cbWeaveCount; i++)
  816. //{
  817. // if (WeaveItem[i].cbWeaveKind & (WIK_PENG | WIK_DAN_PENG | WIK_SHUANG_PENG))
  818. // {
  819. // if (nMagicCount> 0)
  820. // {
  821. // cbActionMask |= WIK_DAN_BU_GANG;
  822. // if (GangCardResult.cbCardCount<6)
  823. // {
  824. // GangCardResult.cbCardData[GangCardResult.cbCardCount++] = WeaveItem[i].cbCenterCard | 0x0800;
  825. // }
  826. // }
  827. // }
  828. //}
  829. //if (nMagicCount > 1)//双财杠
  830. //{
  831. // for (BYTE i = 0; i < MAX_INDEX_TUIDAOHU; i++)
  832. // {
  833. // if (IsMagicCard(SwitchToCardData(i)))
  834. // {
  835. // continue;
  836. // }
  837. // if (TempCardIndex[i] >= 2)
  838. // {
  839. // cbActionMask |= WIK_SHUANG_AN_GANG;
  840. // if (GangCardResult.cbCardCount<6)
  841. // {
  842. // GangCardResult.cbCardData[GangCardResult.cbCardCount++] = SwitchToCardData(i) | 0x0400;
  843. // }
  844. // }
  845. // }
  846. //}
  847. //if (nMagicCount>3)
  848. //{
  849. // cbActionMask |= WIK_QUANG_AN_GANG;
  850. // //GangCardResult.cbCardData[GangCardResult.cbCardCount++] = m_cbLaiZiData;
  851. //}
  852. //if (nMagicCount > 2)
  853. //{
  854. // cbActionMask |= WIK_SAN_AN_GANG;
  855. //}
  856. if (GangCardResult.cbCardCount > 6)
  857. {
  858. GangCardResult.cbCardCount = 6;
  859. }
  860. return cbActionMask;
  861. }
  862. //胡牌分析,bFlag默认false表示正常胡牌,true标示杠上花
  863. int CGameLogic_tdh::AnalyseChiHuCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BYTE cbCurrentCard,
  864. CChiHuRight &ChiHuRight, BYTE& nHuTai, bool bFlag, bool bQiangGangFlag)
  865. {
  866. nHuTai =1;
  867. BYTE cbTmpCardIndex[MAX_INDEX] = { 0 };
  868. CopyMemory(cbTmpCardIndex, cbCardIndex, MAX_INDEX);
  869. cbTmpCardIndex[SwitchToCardIndex(cbCurrentCard)]++;
  870. BYTE CaiShenCount = GetMaigcCardCount(cbTmpCardIndex);
  871. switch (CaiShenCount)
  872. {
  873. default:
  874. {
  875. if (IsSiCaiHu(cbTmpCardIndex, WeaveItem, cbWeaveCount))
  876. {
  877. nHuTai = 2;
  878. ChiHuRight |= ZJ_TAI_SiCaiHu;
  879. return WIK_ZI_MO;
  880. }
  881. if (AnalyseCardNew(cbTmpCardIndex, WeaveItem, cbWeaveCount))
  882. {
  883. m_cbHuCard = cbCurrentCard;
  884. int TmpJiangInColor = mJiangInColor;
  885. mSunTaiJiangInColor = mJiangInColor;
  886. int nTai =1;
  887. if (IsCanHuAllCards(cbCardIndex, WeaveItem, cbWeaveCount))
  888. {
  889. ChiHuRight |= ZJ_TAI_CaiDiao;
  890. nTai=2;
  891. }
  892. if ( bFlag || bQiangGangFlag)
  893. {
  894. ChiHuRight = mChiHuRight;
  895. if (bFlag)
  896. {
  897. nTai=2;
  898. }
  899. if (bQiangGangFlag)
  900. {
  901. nTai=2;
  902. }
  903. nHuTai = nTai;
  904. return WIK_ZI_MO;
  905. }
  906. nHuTai = nTai;
  907. return WIK_ZI_MO;
  908. }
  909. return WIK_NULL;
  910. }
  911. }
  912. }
  913. //
  914. bool CGameLogic_tdh::AnalyseCardNew(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  915. {
  916. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  917. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  918. int nCurrentMagicCount = DeleteMagicCards(TmpcbCardIndex);
  919. int nHaveGangCount = 0;
  920. for (int i = 0; i < MAX_INDEX; i++)
  921. {
  922. if (TmpcbCardIndex[i] == 4)
  923. {
  924. //TmpcbCardIndex[i] = 0;
  925. nHaveGangCount++;
  926. }
  927. }
  928. if (nCurrentMagicCount==2&& GetCardCount(TmpcbCardIndex)==0)
  929. {
  930. return true;
  931. }
  932. bool bHu = TestHu(TmpcbCardIndex, nCurrentMagicCount, WeaveItem, cbWeaveCount);
  933. if (bHu)
  934. {
  935. return true;
  936. }
  937. else
  938. {
  939. if (nHaveGangCount > 0)
  940. {
  941. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  942. int nCurrentMagicCount = DeleteMagicCards(TmpcbCardIndex);
  943. if (TestHu(TmpcbCardIndex, nCurrentMagicCount, WeaveItem, cbWeaveCount))
  944. {
  945. return true;
  946. }
  947. for (int i = 0; i < MAX_INDEX; i++)
  948. {
  949. if (TmpcbCardIndex[i] == 4)
  950. {
  951. TmpcbCardIndex[i] = 1;
  952. }
  953. }
  954. return TestHu(TmpcbCardIndex, nCurrentMagicCount, WeaveItem, cbWeaveCount);
  955. }
  956. }
  957. return bHu;
  958. }
  959. //
  960. bool CGameLogic_tdh::TestHu(const BYTE cbCardIndex[MAX_INDEX], int nCurrentMagicCount, const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  961. {
  962. //////////////////////////////////////////////////////////////////////////
  963. mJiangInColor = -1;
  964. mNeedMinMagicNum = 8;
  965. BYTE cbCardDataWan[MAX_COUNT] = { 0 };
  966. int nCount;
  967. int WanNeedMagicCount, TiaoNeedMagicCount, BingNeedMagicCount, FengNeedMagicCount;//变量分别表示‘万’型需要财神牌数、。。。
  968. int nWanCount, nTiaoCount, nBingCount, nFengCount;
  969. //万
  970. mMagicDataCount = 0;
  971. ZeroMemory(mMagicData, 7);
  972. ZeroMemory(mMagicReplaceCard, MAX_INDEX);
  973. mNeedMinMagicNum = 8;
  974. GetOneColorCards(cbCardIndex, Color_Wan, cbCardDataWan, nCount);
  975. nWanCount = nCount;
  976. GetOneColorNeedMagicCards(cbCardDataWan, nCount, 0);
  977. WanNeedMagicCount = mNeedMinMagicNum;
  978. ShowMagicData();
  979. //////////////////////////////////////////////////////////////////////////
  980. //DebugLog(_T("*********************************************\r\n"));
  981. //条
  982. mMagicDataCount = 0;
  983. ZeroMemory(mMagicData, 7);
  984. mNeedMinMagicNum = 8;
  985. GetOneColorCards(cbCardIndex, Color_Tiao, cbCardDataWan, nCount);
  986. nTiaoCount = nCount;
  987. GetOneColorNeedMagicCards(cbCardDataWan, nCount, 0);
  988. TiaoNeedMagicCount = mNeedMinMagicNum;
  989. ShowMagicData();
  990. //DebugLog(_T("*********************************************\r\n"));
  991. //饼
  992. mMagicDataCount = 0;
  993. ZeroMemory(mMagicData, 7);
  994. mNeedMinMagicNum = 8;
  995. GetOneColorCards(cbCardIndex, Color_Bing, cbCardDataWan, nCount);
  996. nBingCount = nCount;
  997. GetOneColorNeedMagicCards(cbCardDataWan, nCount, 0);
  998. BingNeedMagicCount = mNeedMinMagicNum;
  999. ShowMagicData();
  1000. //DebugLog(_T("*********************************************\r\n"));
  1001. //风
  1002. mMagicDataCount = 0;
  1003. ZeroMemory(mMagicData, 7);
  1004. mNeedMinMagicNum = 8;
  1005. GetOneColorCards(cbCardIndex, Color_Feng, cbCardDataWan, nCount);
  1006. nFengCount = nCount;
  1007. GetOneColorNeedMagicCards(cbCardDataWan, nCount, 0);
  1008. FengNeedMagicCount = mNeedMinMagicNum;
  1009. ShowMagicData();
  1010. //DebugLog(_T("*********************************************\r\n"));
  1011. //将在万中
  1012. ShowMagicReplaceData();
  1013. //手牌全是财神 且满足3N+2
  1014. if (GetCardCount(cbCardIndex) == 0 && nCurrentMagicCount % 3 == 2)
  1015. {
  1016. mJiangInColor = Color_Wan;
  1017. return true;
  1018. }
  1019. //这个 考虑好了在加 主要用于解决2个杠的问题
  1020. // if (WanNeedMagicCount+TiaoNeedMagicCount+BingNeedMagicCount+FengNeedMagicCount== nCurrentMagicCount)
  1021. // {
  1022. // return true;
  1023. //
  1024. // }
  1025. //判断是否是2杠的牌
  1026. int nNeedMagicNum = BingNeedMagicCount + TiaoNeedMagicCount + FengNeedMagicCount;
  1027. if (nNeedMagicNum <= nCurrentMagicCount)
  1028. {
  1029. //DebugLog(_T("jiang in W Need %d Have %d"),nNeedMagicNum,nCurrentMagicCount);
  1030. //剩余几个财神 供给单颜色牌手牌
  1031. int nHasMagicNum = nCurrentMagicCount - nNeedMagicNum;
  1032. BYTE cbTmpCardDataWan[MAX_COUNT] = { 0 };
  1033. int nTmpCount;
  1034. GetOneColorCards(cbCardIndex, Color_Wan, cbTmpCardDataWan, nTmpCount);
  1035. if (nTmpCount>0)
  1036. {
  1037. if (OneCardsCanHu(cbTmpCardDataWan, nTmpCount, nHasMagicNum))
  1038. {
  1039. mJiangInColor = Color_Wan;
  1040. return true;
  1041. }
  1042. }
  1043. }
  1044. //DebugLog(_T("*********************************************\r\n"));
  1045. //tiao
  1046. nNeedMagicNum = WanNeedMagicCount + BingNeedMagicCount + FengNeedMagicCount;
  1047. if (nNeedMagicNum <= nCurrentMagicCount)
  1048. {
  1049. int nHasNum = nCurrentMagicCount - nNeedMagicNum;
  1050. BYTE cbTmpCardDataWan[MAX_COUNT] = { 0 };
  1051. int nTmpCount;
  1052. GetOneColorCards(cbCardIndex, Color_Tiao, cbTmpCardDataWan, nTmpCount);
  1053. if (nTmpCount > 0){
  1054. if (OneCardsCanHu(cbTmpCardDataWan, nTmpCount, nHasNum))
  1055. {
  1056. mJiangInColor = Color_Tiao;
  1057. return true;
  1058. }
  1059. }
  1060. }
  1061. //DebugLog(_T("*********************************************\r\n"));
  1062. //bing
  1063. nNeedMagicNum = WanNeedMagicCount + TiaoNeedMagicCount + FengNeedMagicCount;
  1064. if (nNeedMagicNum <= nCurrentMagicCount)
  1065. {
  1066. int nHasNum = nCurrentMagicCount - nNeedMagicNum;
  1067. BYTE cbTmpCardDataWan[MAX_COUNT] = { 0 };
  1068. int nTmpCount;
  1069. GetOneColorCards(cbCardIndex, Color_Bing, cbTmpCardDataWan, nTmpCount);
  1070. if (nTmpCount > 0){
  1071. if (OneCardsCanHu(cbTmpCardDataWan, nTmpCount, nHasNum))
  1072. {
  1073. mJiangInColor = Color_Bing;
  1074. return true;
  1075. }
  1076. }
  1077. }
  1078. //DebugLog(_T("*********************************************\r\n"));
  1079. //feng
  1080. nNeedMagicNum = WanNeedMagicCount + BingNeedMagicCount + TiaoNeedMagicCount;
  1081. if (nNeedMagicNum <= nCurrentMagicCount)
  1082. {
  1083. int nHasNum = nCurrentMagicCount - nNeedMagicNum;
  1084. BYTE cbTmpCardDataWan[MAX_COUNT] = { 0 };
  1085. int nTmpCount;
  1086. GetOneColorCards(cbCardIndex, Color_Feng, cbTmpCardDataWan, nTmpCount);
  1087. if (nTmpCount > 0){
  1088. if (OneCardsCanHu(cbTmpCardDataWan, nTmpCount, nHasNum))
  1089. {
  1090. mJiangInColor = Color_Feng;
  1091. //如果将在凤牌中 如果东风做将
  1092. return true;
  1093. }
  1094. }
  1095. }
  1096. //DebugLog(_T("*********************************************\r\n"));
  1097. return false;
  1098. }
  1099. //从cbCardIndex 获取 同一花色nColor的手牌牌值cbCardData与数量CardCount
  1100. bool CGameLogic_tdh::GetOneColorCards(const BYTE cbCardIndex[MAX_INDEX], BYTE nColor, BYTE cbCardData[MAX_COUNT], int&CardCount)
  1101. {
  1102. CardCount = 0;
  1103. ZeroMemory(cbCardData, MAX_COUNT);
  1104. int nBegin = 0;
  1105. int nEnd = 0;
  1106. if (nColor == 0)
  1107. {
  1108. nBegin = 0;
  1109. nEnd = 9;
  1110. }
  1111. if (nColor == 1 || nColor == 2){
  1112. nBegin = 9 * nColor;
  1113. nEnd = nBegin + 9;
  1114. }
  1115. if (nColor == 3)
  1116. {
  1117. nBegin = 9 * nColor;
  1118. nEnd = nBegin + 7;
  1119. }
  1120. for (int i = nBegin; i < nEnd; i++)
  1121. {
  1122. if (cbCardIndex[i]>0)
  1123. {
  1124. for (int j = 0; j < cbCardIndex[i]; j++){
  1125. cbCardData[CardCount++] = SwitchToCardData(i);//记录该玩家手牌
  1126. }
  1127. }
  1128. }
  1129. return true;
  1130. }
  1131. //cbCardData:手牌中希望作将的同色牌,nCardCount:手牌数量,nMagicCount:剩余可用癞子数量
  1132. bool CGameLogic_tdh::OneCardsCanHu(const BYTE cbCardData[MAX_COUNT], int nCardCount, int nMagicCount, bool isQuanShun)
  1133. {
  1134. if (nCardCount <= 0)
  1135. {
  1136. //如果没有其他牌做将,那就两个癞子做将(黄石麻将不能2癞子做将)
  1137. if (nMagicCount >= 2)
  1138. {
  1139. return true;
  1140. }
  1141. return false;
  1142. }
  1143. BYTE cbCard = cbCardData[0];
  1144. for (int i = 0; i < nCardCount; i++)
  1145. {
  1146. if (i == nCardCount - 1)//如果只有一张牌
  1147. {
  1148. if (nMagicCount > 0)
  1149. {
  1150. nMagicCount = nMagicCount - 1;
  1151. mNeedMinMagicNum = 8;
  1152. GetOneColorNeedMagicCards(cbCardData, nCardCount - 1, 0, isQuanShun);//该单花色牌型不需要组成整扑,只需要和一个财神牌组成将
  1153. if (mNeedMinMagicNum <= nMagicCount)
  1154. {
  1155. PrintCards(cbCardData, nCardCount );
  1156. return true;
  1157. }
  1158. nMagicCount += 1;
  1159. }
  1160. }
  1161. else
  1162. {
  1163. if (i + 2 == nCardCount || cbCardData[i] != cbCardData[i + 2])//如果不止两张牌,那可能需要整扑一将(该花色牌)
  1164. {
  1165. //DebugLog(_T("Other Pai %d"),i);
  1166. if (test2Combine(cbCardData[i], cbCardData[i + 1]))
  1167. {
  1168. //DebugLog(_T("i=%d card=%02x card=%02x"), i, cbCardData[i], cbCardData[i + 1]);
  1169. mNeedMinMagicNum = 8;
  1170. BYTE tmpCbCardDatas[MAX_COUNT] = { 0 };
  1171. int TmpCardCount = nCardCount;
  1172. BYTE deleteIndex[2];
  1173. deleteIndex[0] = i;
  1174. deleteIndex[1] = i + 1;//有原始的一对将
  1175. DeleteCardDataFromCardDatas(deleteIndex, 2, cbCardData, TmpCardCount, tmpCbCardDatas);
  1176. TmpCardCount = TmpCardCount - 2;//删除一对将
  1177. //再获取(其他牌和财神牌)能否组成整扑
  1178. GetOneColorNeedMagicCards(tmpCbCardDatas, TmpCardCount, 0, isQuanShun);
  1179. if (mNeedMinMagicNum <= nMagicCount)
  1180. {
  1181. //能胡牌
  1182. PrintCards(tmpCbCardDatas, TmpCardCount);
  1183. return true;
  1184. }
  1185. }
  1186. }
  1187. if (nMagicCount > 0 && cbCardData[i] != cbCardData[i + 1])
  1188. {
  1189. nMagicCount -= 1;
  1190. BYTE tmpCbCardDatas[MAX_COUNT] = { 0 };
  1191. int TmpCardCount = nCardCount;
  1192. BYTE DeleteIndex[1];
  1193. DeleteIndex[0] = i;//做将中的一个,另一个为癞子
  1194. DeleteCardDataFromCardDatas(DeleteIndex, 1, cbCardData, TmpCardCount, tmpCbCardDatas);
  1195. TmpCardCount--;
  1196. mNeedMinMagicNum = 8;
  1197. GetOneColorNeedMagicCards(tmpCbCardDatas, TmpCardCount, 0, isQuanShun);
  1198. if (mNeedMinMagicNum <= nMagicCount)
  1199. {
  1200. PrintCards(tmpCbCardDatas, TmpCardCount);
  1201. return true;
  1202. }
  1203. nMagicCount += 1;
  1204. }
  1205. }
  1206. }
  1207. return false;
  1208. }
  1209. //在数组cbCardData中删除DeleteCount个和数组vDeletIndex元素相同的元素,结果重新组合新的数组cbOutCardDatas
  1210. int CGameLogic_tdh::DeleteCardDataFromCardDatas(const BYTE vDeletIndex[MAX_COUNT], int DeleteCount, const BYTE cbCardData[MAX_COUNT], BYTE nCount, BYTE cbOutCardDatas[MAX_COUNT])
  1211. {
  1212. ZeroMemory(cbOutCardDatas, MAX_COUNT);
  1213. int nPaiCount = 0;
  1214. BYTE tmpData[MAX_COUNT] = { 0 };
  1215. CopyMemory(tmpData, cbCardData, nCount);
  1216. for (int i = 0; i < DeleteCount; i++)
  1217. {
  1218. tmpData[vDeletIndex[i]] = 0;
  1219. }
  1220. for (int i = 0; i < nCount; i++)
  1221. {
  1222. if (tmpData[i] != 0)
  1223. {
  1224. cbOutCardDatas[nPaiCount++] = tmpData[i];
  1225. }
  1226. }
  1227. return true;
  1228. }
  1229. //
  1230. int CGameLogic_tdh::PrintCards(const BYTE cbCardData[MAX_COUNT], int nCout)
  1231. {
  1232. std::wstring StrItems;
  1233. StrItems = _T("PrintCards ");
  1234. for (int i = 0; i < nCout; i++)
  1235. {
  1236. std::wstring item;
  1237. TCHAR szBuffer[MAX_COUNT] = { 0 };
  1238. switch (GetCardColor(cbCardData[i]))
  1239. {
  1240. case Color_Wan:{
  1241. wsprintf(szBuffer, _T("%dW"), GetCardValue(cbCardData[i]));
  1242. break;
  1243. }
  1244. case Color_Tiao:{
  1245. wsprintf(szBuffer, _T("%dT"), GetCardValue(cbCardData[i]));
  1246. break;
  1247. }
  1248. case Color_Bing:{
  1249. wsprintf(szBuffer, _T("%dB"), GetCardValue(cbCardData[i]));
  1250. break;
  1251. }
  1252. case Color_Feng:{
  1253. switch (GetCardValue(cbCardData[i]))
  1254. {
  1255. case 1: _tcscpy_s(szBuffer, _tclen(_T("东")) + 1, _T("东")); break;
  1256. case 2:_tcscpy_s(szBuffer, _tclen(_T("南")) + 1, _T("南")); break;
  1257. case 3: _tcscpy_s(szBuffer, _tclen(_T("西")) + 1, _T("西")); break;
  1258. case 4:_tcscpy_s(szBuffer, _tclen(_T("北")) + 1, _T("北")); break;
  1259. case 5:_tcscpy_s(szBuffer, _tclen(_T("中")) + 1, _T("中")); break;
  1260. case 6: _tcscpy_s(szBuffer, _tclen(_T("发")) + 1, _T("发")); break;
  1261. case 7:_tcscpy_s(szBuffer, _tclen(_T("白")) + 1, _T("白")); break;
  1262. }
  1263. break;
  1264. }
  1265. }
  1266. item.append(_T("\t"));
  1267. item.append(szBuffer);
  1268. item.append(_T("\t"));
  1269. StrItems += item;
  1270. }
  1271. StrItems.append(_T("\r\n"));
  1272. //DebugLog(StrItems.c_str());
  1273. return true;
  1274. }
  1275. //
  1276. /*
  1277. int CGameLogic_tdh::AnalyseCardTaiNum(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  1278. {
  1279. mChiHuRight.SetEmpty();
  1280. //首先算是不是 辣子胡 如果是 其他的就不用算了。封顶
  1281. bool WeavieIsLaZi = true;
  1282. mTaiRight = 0;
  1283. int nTai=0;
  1284. //bool bHaveMagic=0;
  1285. //落地牌是否全是碰/顺
  1286. int luodiKind = 0; //1 顺 2 碰 3非全顺/全碰
  1287. for (int i = 0; i < cbWeaveCount; i++)
  1288. {
  1289. if (((WeaveItem[i].cbWeaveKind == WIK_DAN_PENG) || (WeaveItem[i].cbWeaveKind == WIK_SHUANG_PENG) || (WeaveItem[i].cbWeaveKind == WIK_PENG) ||
  1290. (WeaveItem[i].cbWeaveKind == WIK_MING_GANG) || (WeaveItem[i].cbWeaveKind == WIK_QUANG_AN_GANG) || (WeaveItem[i].cbWeaveKind == WIK_SAN_AN_GANG)||
  1291. (WeaveItem[i].cbWeaveKind == WIK_SHUANG_AN_GANG) || (WeaveItem[i].cbWeaveKind == WIK_DAN_AN_GANG) || (WeaveItem[i].cbWeaveKind == WIK_AN_GANG)||
  1292. (WeaveItem[i].cbWeaveKind == WIK_SAN_MING_GANG) || (WeaveItem[i].cbWeaveKind == WIK_SHUANG_MING_GANG) || (WeaveItem[i].cbWeaveKind == WIK_DAN_MING_GANG)||
  1293. (WeaveItem[i].cbWeaveKind == WIK_BU_GANG) || (WeaveItem[i].cbWeaveKind == WIK_DAN_BU_GANG)
  1294. ))
  1295. {
  1296. //计算是否有各种加台刻字
  1297. if (WeaveItem[i].cbCenterCard < 0x31)
  1298. {
  1299. WeavieIsLaZi = false;
  1300. }
  1301. if (WeaveItem[i].cbCenterCard == 0x31)
  1302. {
  1303. //DebugLog(_T("落地派中 发现东风刻字 %02x +2台"), WeaveItem[i].cbCenterCard);
  1304. mChiHuRight |= ZJ_TAI_DongFeng;
  1305. mTaiRight |= ZJ_TAI_DongFeng;
  1306. nTai += 2;
  1307. }
  1308. if ((WeaveItem[i].cbCenterCard == 0x35))
  1309. {
  1310. //DebugLog(_T("落地派中 发现中发白刻字 %02x +1台"), WeaveItem[i].cbCenterCard);
  1311. mChiHuRight |= ZJ_TAI_ZFB;
  1312. mTaiRight |= ZJ_TAI_ZFB;
  1313. nTai += 1;
  1314. }
  1315. if ( WeaveItem[i].cbCenterCard == 0x36 )
  1316. {
  1317. //DebugLog(_T("落地派中 发现中发白刻字 %02x +1台"), WeaveItem[i].cbCenterCard);
  1318. mChiHuRight |= ZJ_TAI_ZFB;
  1319. mTaiRight |= ZJ_TAI_ZFB;
  1320. nTai += 1;
  1321. }
  1322. if ((WeaveItem[i].cbCenterCard == 0x37))
  1323. {
  1324. //DebugLog(_T("落地派中 发现中发白刻字 %02x +1台"), WeaveItem[i].cbCenterCard);
  1325. mChiHuRight |= ZJ_TAI_ZFB;
  1326. mTaiRight |= ZJ_TAI_ZFB;
  1327. nTai += 1;
  1328. }
  1329. if (luodiKind == 1)
  1330. {
  1331. luodiKind = 3;
  1332. }
  1333. if (luodiKind == 0)
  1334. {
  1335. luodiKind = 2;
  1336. }
  1337. continue;
  1338. }
  1339. if ((
  1340. (WeaveItem[i].cbWeaveKind == WIK_DAN_CHI)
  1341. || (WeaveItem[i].cbWeaveKind == WIK_SHUANG_CAICHI)
  1342. || (WeaveItem[i].cbWeaveKind == WIK_LEFT)
  1343. || (WeaveItem[i].cbWeaveKind == WIK_CENTER)
  1344. || (WeaveItem[i].cbWeaveKind == WIK_RIGHT)
  1345. ))
  1346. {
  1347. WeavieIsLaZi = false;
  1348. if (luodiKind == 2)
  1349. {
  1350. luodiKind = 3;
  1351. }
  1352. if (luodiKind == 0)
  1353. {
  1354. luodiKind = 1;
  1355. }
  1356. continue;
  1357. }
  1358. }
  1359. //落地牌分析完毕
  1360. //////////////////////////////////////////////////////////////////////////
  1361. //全字 分析
  1362. if (WeavieIsLaZi == true)
  1363. {
  1364. for (int i = 0; i < 27; i++)
  1365. {
  1366. if (cbCardIndex[i]>0&&!IsMagicCard(SwitchToCardData(i)))//手牌中存在不是字牌,并且该牌不是财神牌(癞子与癞子皮)
  1367. {
  1368. WeavieIsLaZi = false;
  1369. break;
  1370. }
  1371. }
  1372. }
  1373. if (WeavieIsLaZi == true)
  1374. {
  1375. mChiHuRight |= ZJ_TAI_QuanZi;
  1376. mTaiRight |= ZJ_TAI_QuanZi;
  1377. return 7;
  1378. }
  1379. //////////////////////////////////////////////////////////////////////////
  1380. //////////////////////////////////////////////////////////////////////////
  1381. if (IsQingYiSe(cbCardIndex, WeaveItem, cbWeaveCount))
  1382. {
  1383. nTai += 3;
  1384. mChiHuRight |= ZJ_TAI_QingYiSe;
  1385. mTaiRight |= ZJ_TAI_QingYiSe;
  1386. //DebugLog(_T("清一色 +3台"));
  1387. }
  1388. //更新算法 计算手牌包含刻字情况
  1389. //财东东 123 123 11 123
  1390. BYTE cbCardIndexTmp[MAX_INDEX];
  1391. tagWeaveItem WeaveItemTmp[5];
  1392. BYTE cbWeaveCountTmp;
  1393. ZeroMemory(cbCardIndexTmp, MAX_INDEX);
  1394. ZeroMemory(WeaveItemTmp, sizeof(WeaveItemTmp));
  1395. cbWeaveCountTmp = 0;
  1396. CopyMemory(cbCardIndexTmp, cbCardIndex, MAX_INDEX);
  1397. CopyMemory(WeaveItemTmp, WeaveItem, sizeof(tagWeaveItem)*cbWeaveCount);
  1398. cbWeaveCountTmp = cbWeaveCount;
  1399. int nFengTai=0;
  1400. BOOL haveFengKe=FALSE;
  1401. for (int i = 0; i < 4; i++)
  1402. {
  1403. if (HaveFengKe(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp, 27))//东风刻字
  1404. {
  1405. nTai += 2;
  1406. nFengTai += 2;
  1407. mChiHuRight |= ZJ_TAI_DongFeng;
  1408. mTaiRight |= ZJ_TAI_DongFeng;
  1409. haveFengKe = TRUE;
  1410. //DebugLog(_T("手牌中 发现[东风]刻字 +2台"));
  1411. //如果 删掉东风+财神 依然可以胡牌 那么就删掉3张牌
  1412. }
  1413. else
  1414. {
  1415. break;
  1416. }
  1417. }
  1418. for (int i = 0; i < 4; i++)
  1419. {
  1420. //计算中发白 刻字个数
  1421. if (HaveFengKe(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp, 31))
  1422. {
  1423. nTai++;
  1424. nFengTai++;
  1425. mChiHuRight |= ZJ_TAI_ZFB;
  1426. mTaiRight |= ZJ_TAI_ZFB;
  1427. haveFengKe = TRUE;
  1428. //DebugLog(_T("手牌中 发现[中发白]有2张 可能有刻字 +1台"));
  1429. }
  1430. else
  1431. {
  1432. break;
  1433. }
  1434. }
  1435. for (int i = 0; i < 4; i++)
  1436. {
  1437. //计算中发白 刻字个数
  1438. if (HaveFengKe(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp, 32))
  1439. {
  1440. nTai++;
  1441. nFengTai++;
  1442. mChiHuRight |= ZJ_TAI_ZFB;
  1443. mTaiRight |= ZJ_TAI_ZFB;
  1444. haveFengKe = TRUE;
  1445. //DebugLog(_T("手牌中 发现[中发白]有2张 可能有刻字 +1台"));
  1446. }
  1447. else
  1448. {
  1449. break;
  1450. }
  1451. }
  1452. for (int i = 0; i < 4; i++)
  1453. {
  1454. //计算中发白 刻字个数
  1455. if (HaveFengKe(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp, 33))
  1456. {
  1457. nTai++;
  1458. nFengTai++;
  1459. mChiHuRight |= ZJ_TAI_ZFB;
  1460. mTaiRight |= ZJ_TAI_ZFB;
  1461. haveFengKe = TRUE;
  1462. //DebugLog(_T("手牌中 发现[中发白]有2张 可能有刻字 +1台"));
  1463. }
  1464. else
  1465. {
  1466. break;
  1467. }
  1468. }
  1469. if (!HaveMagic(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp))
  1470. {
  1471. nTai += 1;
  1472. mChiHuRight |= ZJ_TAI_WuMagic;
  1473. mTaiRight |= ZJ_TAI_WuMagic;
  1474. //DebugLog(_T("无财神 +1台"));
  1475. }
  1476. //是清一色 并且清一色的花色 不是风则 不走风刻的计算
  1477. if (!(mChiHuRight&ZJ_TAI_QingYiSe).IsEmpty() && nFengTai>0&&nFengTai<4)
  1478. {
  1479. BYTE color = 0;
  1480. //得到清一色的花色
  1481. for (int i = 0; i < MAX_INDEX;i++)
  1482. {
  1483. if (cbCardIndex[i]>0 && !IsMagicCard(SwitchToCardData(i)))
  1484. {
  1485. color = GetCardColor(SwitchToCardData(i));
  1486. break;
  1487. }
  1488. }
  1489. if (color!=Color_Feng)
  1490. {
  1491. nTai -= nFengTai;
  1492. mChiHuRight -= ZJ_TAI_ZFB;
  1493. mChiHuRight -= ZJ_TAI_DongFeng;
  1494. if (mTaiRight&ZJ_TAI_ZFB)
  1495. {
  1496. mTaiRight ^= ZJ_TAI_ZFB;
  1497. }
  1498. if (mTaiRight&ZJ_TAI_DongFeng)
  1499. {
  1500. mTaiRight ^= ZJ_TAI_DongFeng;
  1501. }
  1502. haveFengKe = FALSE;
  1503. cbWeaveCountTmp = 0;
  1504. CopyMemory(cbCardIndexTmp, cbCardIndex, MAX_INDEX);
  1505. CopyMemory(WeaveItemTmp, WeaveItem, sizeof(tagWeaveItem)*cbWeaveCount);
  1506. cbWeaveCountTmp = cbWeaveCount;
  1507. }
  1508. }
  1509. if (!(mChiHuRight&ZJ_TAI_QingYiSe).IsEmpty() && nFengTai > 3)
  1510. {
  1511. BYTE color = 0;
  1512. //得到清一色的花色
  1513. for (int i = 0; i < MAX_INDEX; i++)
  1514. {
  1515. if (cbCardIndex[i]>0 && !IsMagicCard(SwitchToCardData(i)))
  1516. {
  1517. color = GetCardColor(SwitchToCardData(i));
  1518. break;
  1519. }
  1520. }
  1521. if (color != Color_Feng)
  1522. {
  1523. nTai -= 3;
  1524. mChiHuRight -= ZJ_TAI_QingYiSe;
  1525. if (mTaiRight&ZJ_TAI_QingYiSe)
  1526. {
  1527. mTaiRight ^= ZJ_TAI_QingYiSe;
  1528. }
  1529. cbWeaveCountTmp = 0;
  1530. CopyMemory(cbCardIndexTmp, cbCardIndex, MAX_INDEX);
  1531. CopyMemory(WeaveItemTmp, WeaveItem, sizeof(tagWeaveItem)*cbWeaveCount);
  1532. cbWeaveCountTmp = cbWeaveCount;
  1533. }
  1534. }
  1535. if (luodiKind != 3)
  1536. {
  1537. //碰碰胡 和全顺 只能算出一个来 剩下的一个不要算了。
  1538. bool bOK = false;
  1539. //全碰
  1540. if (IsPengPengHu(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp))
  1541. {
  1542. nTai += 1;
  1543. mChiHuRight |= ZJ_TAI_PengPeng;
  1544. mTaiRight |= ZJ_TAI_PengPeng;
  1545. //DebugLog(_T("碰碰胡 +1台"));
  1546. bOK = true;
  1547. }
  1548. //
  1549. if (bOK == false && haveFengKe==FALSE)
  1550. {
  1551. if (IsQuanShun(cbCardIndex, WeaveItem, cbWeaveCount))
  1552. {
  1553. nTai += 1;
  1554. mChiHuRight |= ZJ_TAI_QuanShun;
  1555. mTaiRight |= ZJ_TAI_QuanShun;
  1556. // DebugLog(_T("全顺 +1台"));
  1557. }
  1558. }
  1559. }
  1560. //if (cbCardIndexTmp[31] >= 3 || cbCardIndexTmp[32] >= 3 || cbCardIndexTmp[33] >= 3)
  1561. //{
  1562. // nTai++;
  1563. // mChiHuRight |= ZJ_TAI_ZFB;
  1564. // mTaiRight |= ZJ_TAI_ZFB;
  1565. // //DebugLog(_T("手牌中 发现[中发白]刻字 +1台"));
  1566. //}
  1567. if ((mChiHuRight&ZJ_TAI_QingYiSe).IsEmpty())
  1568. {
  1569. if (IsCardsIsHunYiSe(cbCardIndexTmp, WeaveItemTmp, cbWeaveCountTmp))
  1570. {
  1571. nTai += 1;
  1572. mChiHuRight |= ZJ_TAI_HunYiSe;
  1573. mTaiRight |= ZJ_TAI_HunYiSe;
  1574. }
  1575. }
  1576. if (!(mChiHuRight&ZJ_TAI_QuanShun).IsEmpty()&& mSunTaiJiangInColor ==Color_Feng)
  1577. {
  1578. int nMagic = DeleteMagicCards(cbCardIndexTmp);
  1579. if (mSunTaiJiangInColor ==Color_Feng)
  1580. {
  1581. if (nMagic>0)
  1582. {
  1583. if (cbCardIndexTmp[27] == 1
  1584. || cbCardIndexTmp[31] == 1
  1585. || cbCardIndexTmp[32] == 1
  1586. || cbCardIndexTmp[33] == 1
  1587. )
  1588. {
  1589. //OutputDebugString(_T("财神+东 中发白做将 不让胡"));
  1590. if (nTai>1)
  1591. {
  1592. mTaiRight ^= ZJ_TAI_QuanShun;
  1593. mChiHuRight -= ZJ_TAI_QuanShun;
  1594. nTai--;
  1595. return nTai;
  1596. }
  1597. mTaiRight = WIK_NULL;
  1598. mChiHuRight.SetEmpty();
  1599. return 0;
  1600. }
  1601. if (cbCardIndexTmp[27] == 2
  1602. || cbCardIndexTmp[31] == 2
  1603. || cbCardIndexTmp[32] == 2
  1604. || cbCardIndexTmp[33] == 2
  1605. )
  1606. {
  1607. ////OutputDebugString(_T(" 中发白做将 不让胡"));
  1608. if (nTai > 1)
  1609. {
  1610. mTaiRight ^= ZJ_TAI_QuanShun;
  1611. mChiHuRight -= ZJ_TAI_QuanShun;
  1612. nTai--;
  1613. return nTai;
  1614. }
  1615. mTaiRight = WIK_NULL;
  1616. mChiHuRight.SetEmpty();
  1617. return 0;
  1618. }
  1619. }
  1620. else
  1621. {
  1622. if (cbCardIndexTmp[27] == 2
  1623. || cbCardIndexTmp[31] == 2
  1624. || cbCardIndexTmp[32] == 2
  1625. || cbCardIndexTmp[33] == 2
  1626. )
  1627. {
  1628. ////OutputDebugString(_T(" 中发白做将 不让胡"));
  1629. if (nTai > 1)
  1630. {
  1631. mTaiRight ^= ZJ_TAI_QuanShun;
  1632. mChiHuRight -= ZJ_TAI_QuanShun;
  1633. nTai--;
  1634. return nTai;
  1635. }
  1636. mTaiRight = WIK_NULL;
  1637. mChiHuRight.SetEmpty();
  1638. return 0;
  1639. }
  1640. }
  1641. }
  1642. //仅有全顺时 如果东 中发白 做将 不让胡
  1643. }
  1644. //if ((cbCardIndexTmp[27] == 1 || cbCardIndexTmp[27] ==2 && !IsMagicCard(SwitchToCardData(27)))
  1645. // || (cbCardIndexTmp[31] == 1 && !IsMagicCard(SwitchToCardData(31)))
  1646. // || (cbCardIndexTmp[32] == 1 && !IsMagicCard(SwitchToCardData(32)))
  1647. // || (cbCardIndexTmp[33] == 1 && !IsMagicCard(SwitchToCardData(33)))
  1648. // )
  1649. //{
  1650. // nTai = 0;
  1651. // QueryPerformanceCounter(&nEndTime);
  1652. // strAddString.Format(_T("财神+东 中发白作将 全顺不能胡 花费时间 %f 秒"), (double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart);
  1653. // m_ResultList.AddString(strAddString);
  1654. // return;
  1655. //}
  1656. return nTai;
  1657. }*/
  1658. //
  1659. //bool CGameLogic::isHaveMaigc(const BYTE cardMagicIndex[4])
  1660. //{
  1661. // for (int i = 0; i < 4; i++){
  1662. // if (cardMagicIndex[i]>0)
  1663. // {
  1664. // return false;
  1665. // }
  1666. // }
  1667. // return false;
  1668. //}
  1669. //
  1670. bool CGameLogic_tdh::HaveMagic(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  1671. {
  1672. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  1673. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  1674. int nMagicCount = DeleteMagicCards(TmpcbCardIndex);
  1675. if (nMagicCount > 0)
  1676. {
  1677. return true;
  1678. }
  1679. for (int i = 0; i < cbWeaveCount; i++)
  1680. {
  1681. if (WeaveItem[i].cbWeaveKind&(
  1682. WIK_DAN_CHI |
  1683. WIK_SHUANG_CAICHI |
  1684. WIK_DAN_PENG | WIK_SHUANG_PENG |
  1685. WIK_DAN_MING_GANG | WIK_SHUANG_MING_GANG | WIK_SAN_MING_GANG | WIK_DAN_BU_GANG |
  1686. WIK_DAN_AN_GANG | WIK_SHUANG_AN_GANG | WIK_SAN_AN_GANG | WIK_QUANG_AN_GANG
  1687. ))
  1688. {
  1689. return true;
  1690. }
  1691. if (WeaveItem[i].cbWeaveKind == WIK_BU_GANG && WeaveItem[i].cbMargicOffset[0] != 0)
  1692. {
  1693. return true;
  1694. }
  1695. }
  1696. return false;
  1697. }
  1698. //
  1699. bool CGameLogic_tdh::IsPengPengHu(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  1700. {
  1701. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  1702. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  1703. for (int i = 0; i < cbWeaveCount; i++)
  1704. {
  1705. if (WeaveItem[i].cbWeaveKind
  1706. & (WIK_DAN_CHI |
  1707. WIK_SHUANG_CAICHI |
  1708. WIK_LEFT | WIK_CENTER | WIK_RIGHT
  1709. ))//单财吃、双财吃、左、中、右吃
  1710. {
  1711. return false;
  1712. }
  1713. }
  1714. int nMagic = DeleteMagicCards(TmpcbCardIndex);
  1715. //计算出剩余的牌 全部变成刻字需要多少张财神
  1716. //碰碰胡 分2种 3杠一对 4刻字一对
  1717. int nNeedMagic = 0;
  1718. int nGangCount=0;
  1719. for (int i = 0; i < MAX_INDEX; i++)
  1720. {
  1721. if (TmpcbCardIndex[i] == 1 || TmpcbCardIndex[i] == 2)
  1722. {
  1723. nNeedMagic += (3 - TmpcbCardIndex[i]);
  1724. }
  1725. if (TmpcbCardIndex[i]==4)
  1726. {
  1727. nNeedMagic += 2;
  1728. nGangCount++;
  1729. }
  1730. }
  1731. //if (nGangCount>1)
  1732. //{
  1733. // return false;
  1734. //}
  1735. if (nNeedMagic == nMagic + 1 || nNeedMagic ==nMagic%3 +1||(nNeedMagic==0&& nMagic%3==2))
  1736. {
  1737. return true;
  1738. }
  1739. //计算有几个杠 如果杠需要的财神=手牌财神+2 则 是碰碰胡
  1740. nNeedMagic = 0;
  1741. for (int i = 0; i < MAX_INDEX; i++)
  1742. {
  1743. if (TmpcbCardIndex[i] == 1 || TmpcbCardIndex[i] == 2 || TmpcbCardIndex[i] == 3)
  1744. {
  1745. nNeedMagic += (4 - TmpcbCardIndex[i]);
  1746. }
  1747. }
  1748. if (nNeedMagic == nMagic + 2 || nNeedMagic == nMagic % 3 + 2 )
  1749. {
  1750. return true;
  1751. }
  1752. return false;
  1753. }
  1754. //
  1755. bool CGameLogic_tdh::IsQuanShun(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  1756. {
  1757. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  1758. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  1759. for (int i = 0; i < cbWeaveCount; i++)
  1760. {
  1761. if (!(WeaveItem[i].cbWeaveKind
  1762. &(WIK_CENTER | WIK_DAN_CHI | WIK_SHUANG_CAICHI|WIK_RIGHT|WIK_LEFT)
  1763. ))
  1764. {
  1765. return false;
  1766. }
  1767. }
  1768. //如果有风牌 不可能是全顺
  1769. //将手牌 遍历一次 把能够组成顺子 且 剩下的还能胡的牌 扔到组合里面。如果最后 剩下2张一样的牌 就判定是全顺
  1770. int nMagicCount = DeleteMagicCards(TmpcbCardIndex);
  1771. int nFengCardCount=0;
  1772. BYTE nFengCard[MAX_INDEX] = { 0 };
  1773. for (int i = 0; i < 7; i++)
  1774. {
  1775. if (TmpcbCardIndex[27 + i] >= 3)
  1776. {
  1777. return false;
  1778. }
  1779. if (TmpcbCardIndex[27 + i] >= 1)
  1780. {
  1781. nFengCard[nFengCardCount] = 27 + i;
  1782. nFengCardCount++;
  1783. }
  1784. }
  1785. if (nFengCardCount>=2)
  1786. {
  1787. return false;
  1788. }
  1789. BYTE cbUserIndexCardTmp[MAX_INDEX] = { 0 };
  1790. CopyMemory(cbUserIndexCardTmp, TmpcbCardIndex, MAX_INDEX);
  1791. //////////////////////////////////////////////////////////////////////////
  1792. {
  1793. BYTE cbJiangIndex[MAX_INDEX] = { 0 };
  1794. for (int i = 0; i < MAX_INDEX; i++)
  1795. {
  1796. if (cbUserIndexCardTmp[i] == 0)
  1797. {
  1798. continue;
  1799. }
  1800. if (cbUserIndexCardTmp[i] >= 2)
  1801. {
  1802. cbJiangIndex[i] = 1;
  1803. }
  1804. }
  1805. for (int i = 0; i < MAX_INDEX; i++)
  1806. {
  1807. BYTE cbTmpCardIndex[MAX_INDEX] = { 0 };
  1808. CopyMemory(cbTmpCardIndex, cbUserIndexCardTmp, MAX_INDEX);
  1809. if (cbJiangIndex[i] == 0)
  1810. {
  1811. continue;
  1812. }
  1813. if (cbJiangIndex[i] == 1)
  1814. {
  1815. cbTmpCardIndex[i] -= 2;
  1816. //计算剩余的牌 全顺需要财神个数
  1817. int nNeedMagicCount = 0;
  1818. BYTE cbColorCards[4][MAX_INDEX] = { 0 };
  1819. int cbColorCardCount[MAX_COUNT] = { 0 };
  1820. for (int iColor = 0; iColor < 4; iColor++)
  1821. {
  1822. mNeedMinMagicNum = 8;
  1823. GetOneColorCards(cbTmpCardIndex, iColor, cbColorCards[iColor], cbColorCardCount[iColor]);
  1824. int nNeedMagic = 0;
  1825. GetOneColorNeedMagicCards(cbColorCards[iColor], cbColorCardCount[iColor], 0, true);
  1826. nNeedMagic = mNeedMinMagicNum;
  1827. nNeedMagicCount += nNeedMagic;
  1828. CString str;
  1829. str.Format(_T("花色 %d 需要财神个数 %d 才能组成全顺"), iColor, nNeedMagic);
  1830. }
  1831. if (nNeedMagicCount == nMagicCount)
  1832. {
  1833. if (nFengCardCount==1)
  1834. {
  1835. if (nFengCard[0]!=i)
  1836. {
  1837. continue;
  1838. }
  1839. }
  1840. CString str;
  1841. str.Format(_T("全顺 %02x 做将"), SwitchToCardData(i));
  1842. ////OutputDebugString(str);
  1843. return true;
  1844. }
  1845. }
  1846. }
  1847. }
  1848. //////////////////////////////////////////////////////////////////////////
  1849. //正将没有找到 尝试找找财将
  1850. {
  1851. if (nMagicCount >= 1)
  1852. {
  1853. BYTE cbJiangIndex[MAX_INDEX] = { 0 };
  1854. for (int i = 0; i < MAX_INDEX; i++)
  1855. {
  1856. if (cbUserIndexCardTmp[i] == 0)
  1857. {
  1858. continue;
  1859. }
  1860. if (cbUserIndexCardTmp[i] >= 1)
  1861. {
  1862. cbJiangIndex[i] = 1;
  1863. }
  1864. }
  1865. for (int i = 0; i < MAX_INDEX; i++)
  1866. {
  1867. BYTE cbTmpCardIndex[MAX_INDEX] = { 0 };
  1868. CopyMemory(cbTmpCardIndex, cbUserIndexCardTmp, MAX_INDEX);
  1869. if (cbJiangIndex[i] == 0)
  1870. {
  1871. continue;
  1872. }
  1873. if (cbJiangIndex[i] == 1)
  1874. {
  1875. cbTmpCardIndex[i] -= 1;
  1876. int nTmpMagicCount=nMagicCount-1;
  1877. //计算剩余的牌 全顺需要财神个数
  1878. int nNeedMagicCount = 0;
  1879. BYTE cbColorCards[4][MAX_INDEX] = { 0 };
  1880. int cbColorCardCount[MAX_COUNT] = { 0 };
  1881. for (int iColor = 0; iColor < 4; iColor++)
  1882. {
  1883. mNeedMinMagicNum = 8;
  1884. GetOneColorCards(cbTmpCardIndex, iColor, cbColorCards[iColor], cbColorCardCount[iColor]);
  1885. int nNeedMagic = 0;
  1886. GetOneColorNeedMagicCards(cbColorCards[iColor], cbColorCardCount[iColor], 0, true);
  1887. nNeedMagic = mNeedMinMagicNum;
  1888. nNeedMagicCount += nNeedMagic;
  1889. CString str;
  1890. str.Format(_T("花色 %d 需要财神个数 %d 才能组成全顺"), iColor, nNeedMagic);
  1891. }
  1892. if (nNeedMagicCount == nTmpMagicCount||nNeedMagicCount==nTmpMagicCount%3)
  1893. {
  1894. if (nFengCardCount == 1)
  1895. {
  1896. if (nFengCard[0] != i)
  1897. {
  1898. continue;
  1899. }
  1900. }
  1901. CString str;
  1902. str.Format(_T("全顺 %02x 财神 做将"), SwitchToCardData(i));
  1903. return true;
  1904. }
  1905. }
  1906. }
  1907. }
  1908. }
  1909. //////////////////////////////////////////////////////////////////////////
  1910. //双财将
  1911. {
  1912. //财将 也没有 那就试试 财财将
  1913. if (nMagicCount >= 2)
  1914. {
  1915. BYTE cbTmpCardIndex[MAX_INDEX] = { 0 };
  1916. CopyMemory(cbTmpCardIndex, cbUserIndexCardTmp, MAX_INDEX);
  1917. nMagicCount -= 2;
  1918. //计算剩余的牌 全顺需要财神个数
  1919. int nNeedMagicCount = 0;
  1920. BYTE cbColorCards[4][MAX_INDEX] = { 0 };
  1921. int cbColorCardCount[MAX_COUNT] = { 0 };
  1922. for (int iColor = 0; iColor < 4; iColor++)
  1923. {
  1924. mNeedMinMagicNum = 8;
  1925. GetOneColorCards(cbTmpCardIndex, iColor, cbColorCards[iColor], cbColorCardCount[iColor]);
  1926. int nNeedMagic = 0;
  1927. //nNeedMagicCount = nNeedMagicCount + cbColorCardCount[iColor] * 3 - cbColorCardCount[iColor];
  1928. //nNeedMagic = cbColorCardCount[iColor] * 3 - cbColorCardCount[iColor];
  1929. GetOneColorNeedMagicCards(cbColorCards[iColor], cbColorCardCount[iColor], 0, true);
  1930. nNeedMagic = mNeedMinMagicNum;
  1931. nNeedMagicCount += nNeedMagic;
  1932. CString str;
  1933. str.Format(_T("花色 %d 需要财神个数 %d 才能组成全顺"), iColor, nNeedMagic);
  1934. }
  1935. if (nNeedMagicCount == nMagicCount||nNeedMagicCount==nMagicCount%3)
  1936. {
  1937. CString str;
  1938. str.Format(_T("全顺 财神 财神 做将"));
  1939. return true;
  1940. }
  1941. }
  1942. }
  1943. //////////////////////////////////////////////////////////////////////////
  1944. return false;
  1945. }
  1946. //
  1947. bool CGameLogic_tdh::IsCardsIsHunYiSe(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BOOL HaveFengKe)
  1948. {
  1949. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  1950. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  1951. //////////////////////////////////////////////////////////////////////////
  1952. //无风牌 不是混一色
  1953. int cbFengCount = 0;
  1954. int cbItemColor = -1;
  1955. bool bHasFeng2 = false;
  1956. for (int i = 0; i < cbWeaveCount; i++)
  1957. {
  1958. BYTE cbColor = GetCardColor(WeaveItem[i].cbCenterCard);
  1959. if (cbColor == Color_Feng)
  1960. {
  1961. bHasFeng2 = true;
  1962. cbFengCount++;
  1963. continue;
  1964. }
  1965. if (cbItemColor == -1)
  1966. {
  1967. cbItemColor = cbColor;
  1968. }
  1969. if (cbItemColor != cbColor)
  1970. {
  1971. return false;
  1972. }
  1973. }
  1974. //////////////////////////////////////////////////////////////////////////
  1975. //删除风 删除财神 判断是否是一色
  1976. int nCurrentMagicCount = DeleteMagicCards(TmpcbCardIndex);
  1977. //如果没有 东南西北中发白 不可能是混一色
  1978. for (int i = 1; i < 8; i++)
  1979. {
  1980. if (TmpcbCardIndex[26 + i] != 0 )
  1981. {
  1982. bHasFeng2 = true;
  1983. break;
  1984. }
  1985. else
  1986. {
  1987. continue;
  1988. }
  1989. }
  1990. if (!bHasFeng2&&!cbFengCount&&!HaveFengKe)
  1991. {
  1992. return false;
  1993. }
  1994. if (cbItemColor != -1)
  1995. {
  1996. for (BYTE i = 0; i < 27; i++){
  1997. if (TmpcbCardIndex[i] != 0)
  1998. {
  1999. if (GetCardColor(SwitchToCardData(i)) != cbItemColor)
  2000. {
  2001. return false;
  2002. }
  2003. }
  2004. }
  2005. }
  2006. else
  2007. {
  2008. BYTE cbFirst = 0;
  2009. //遍历前 27张0-26
  2010. //得到第一张颜色 如果后面的颜色与第一个不一样,返回false
  2011. for (BYTE i = 0; i < 27; i++){
  2012. if (TmpcbCardIndex[i] != 0)
  2013. {
  2014. if (cbFirst == 0)
  2015. {
  2016. cbFirst = SwitchToCardData(i);
  2017. continue;
  2018. }
  2019. if (GetCardColor(cbFirst) != GetCardColor(SwitchToCardData(i)))
  2020. {
  2021. return false;
  2022. }
  2023. }
  2024. }
  2025. }
  2026. return true;
  2027. }
  2028. //听牌分析,
  2029. bool CGameLogic_tdh::AnalyseTingCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BYTE *m_cbTingPaiData,
  2030. const BYTE FanHui[MAX_INDEX], BYTE wChairID, BYTE wBaoUserID, BYTE BaoTai)
  2031. {
  2032. //复制数据
  2033. BYTE cbCardIndexTemp[MAX_INDEX];
  2034. CopyMemory(cbCardIndexTemp, cbCardIndex, sizeof(cbCardIndexTemp));
  2035. //BYTE FanHui[MAX_INDEX] = { 0 };
  2036. //IsCanChangCardAndCount(cbCardIndexTemp, FanHui);
  2037. BYTE cbCardCount = GetCardCount(cbCardIndexTemp);
  2038. if (cbCardCount > 1 && (cbCardCount - 1) % 3 != 0)
  2039. {
  2040. ASSERT(false);
  2041. return false;
  2042. }
  2043. CChiHuRight chr;
  2044. BYTE TaiShu = 0;
  2045. bool isHu = false;
  2046. for (BYTE i = 0; i < MAX_INDEX; i++)
  2047. {
  2048. if (FanHui[i]==0
  2049. && !IsMagicCard(SwitchToCardData(i)))
  2050. {
  2051. continue;
  2052. }
  2053. BYTE CardTempData = SwitchToCardData(i);
  2054. if (WIK_ZI_MO & AnalyseChiHuCard(cbCardIndexTemp, WeaveItem, cbWeaveCount, CardTempData, chr, TaiShu))
  2055. {
  2056. //翻财神
  2057. m_cbTingPaiData[i] = TaiShu;
  2058. isHu = true;
  2059. }
  2060. else
  2061. {
  2062. m_cbTingPaiData[i] = 0;
  2063. }
  2064. }
  2065. return isHu;
  2066. }
  2067. //是否听牌
  2068. //bool CGameLogic::IsTingCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, const BYTE FanHui[MAX_INDEX])
  2069. //{
  2070. // //复制数据
  2071. // BYTE cbCardIndexTemp[MAX_INDEX];
  2072. // CopyMemory(cbCardIndexTemp, cbCardIndex, sizeof(cbCardIndexTemp));
  2073. // //BYTE FanHui[MAX_INDEX] = { 0 };
  2074. // //IsCanChangCardAndCount(cbCardIndexTemp, FanHui);
  2075. // for (BYTE i = 0; i < MAX_INDEX; i++)
  2076. // {
  2077. // if (FanHui[i] == 0)continue;
  2078. // BYTE cbTempCardData = SwitchToCardData(i);
  2079. // CChiHuRight chr;
  2080. // BYTE TaiShu = 0;
  2081. // if (WIK_ZI_MO & AnalyseChiHuCard(cbCardIndexTemp, WeaveItem, cbWeaveCount, cbTempCardData,chr,TaiShu))
  2082. // return true;
  2083. // }
  2084. // return false;
  2085. //}
  2086. //扑克转换
  2087. BYTE CGameLogic_tdh::SwitchToCardData(BYTE cbCardIndex)
  2088. {
  2089. //ASSERT(cbCardIndex<34);
  2090. return ((cbCardIndex/9)<<4)|(cbCardIndex%9+1);
  2091. }
  2092. //扑克转换
  2093. BYTE CGameLogic_tdh::SwitchToCardIndex(BYTE cbCardData)
  2094. {
  2095. ASSERT(IsValidCard(cbCardData));
  2096. return ((cbCardData&MASK_COLOR)>>4)*9+(cbCardData&MASK_VALUE)-1;
  2097. }
  2098. //扑克转换
  2099. BYTE CGameLogic_tdh::SwitchToCardData(const BYTE cbCardIndex[MAX_INDEX], BYTE cbCardData[MAX_COUNT])
  2100. {
  2101. //转换扑克
  2102. BYTE cbPosition=0;
  2103. for (BYTE i=0;i<MAX_INDEX;i++)
  2104. {
  2105. if (cbCardIndex[i]!=0)
  2106. {
  2107. for (BYTE j=0;j<cbCardIndex[i];j++)
  2108. {
  2109. ASSERT(cbPosition<=MAX_COUNT);
  2110. cbCardData[cbPosition++]=SwitchToCardData(i);
  2111. }
  2112. }
  2113. }
  2114. return cbPosition;
  2115. }
  2116. //扑克转换
  2117. BYTE CGameLogic_tdh::SwitchToCardIndex(const BYTE cbCardData[], BYTE cbCardCount, BYTE cbCardIndex[MAX_INDEX])
  2118. {
  2119. //设置变量
  2120. ZeroMemory(cbCardIndex,sizeof(BYTE)*MAX_INDEX);
  2121. //转换扑克
  2122. for (BYTE i=0;i<cbCardCount;i++)
  2123. {
  2124. ASSERT(IsValidCard(cbCardData[i]));
  2125. cbCardIndex[SwitchToCardIndex(cbCardData[i])]++;
  2126. }
  2127. return cbCardCount;
  2128. }
  2129. //分析扑克 无癞子情况下是否可以胡牌,标志AnalyseItemArray.GetCount()>0
  2130. bool CGameLogic_tdh::AnalyseCard(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, CAnalyseItemArray & AnalyseItemArray)
  2131. {
  2132. //计算数目
  2133. BYTE cbCardCount = GetCardCount(cbCardIndex);
  2134. //效验数目
  2135. if ((cbCardCount<2) || (cbCardCount>MAX_COUNT) || ((cbCardCount - 2) % 3 != 0))
  2136. return false;
  2137. //变量定义
  2138. BYTE cbKindItemCount = 0;//组合个数
  2139. tagKindItem KindItem[27 * 2 + 7 + 14];
  2140. ZeroMemory(KindItem, sizeof(KindItem));
  2141. //需求判断
  2142. BYTE cbLessKindItem = (cbCardCount - 2) / 3;//表示手牌需要几个组合才能胡牌
  2143. ASSERT((cbLessKindItem + cbWeaveCount) == 4);
  2144. //单吊判断
  2145. if (cbLessKindItem == 0)
  2146. {
  2147. //牌眼判断
  2148. for (BYTE i = 0; i < MAX_INDEX; i++)
  2149. {
  2150. if (cbCardIndex[i] == 2)
  2151. {
  2152. //变量定义
  2153. tagAnalyseItem AnalyseItem;
  2154. ZeroMemory(&AnalyseItem, sizeof(AnalyseItem));
  2155. //设置结果
  2156. for (BYTE j = 0; j < cbWeaveCount; j++)
  2157. {
  2158. AnalyseItem.cbWeaveKind[j] = WeaveItem[j].cbWeaveKind;
  2159. AnalyseItem.cbCenterCard[j] = WeaveItem[j].cbCenterCard;
  2160. GetWeaveCard(WeaveItem[j].cbWeaveKind, WeaveItem[j].cbCenterCard, WeaveItem[j].cbMargicOffset, AnalyseItem.cbCardData[j]);
  2161. }
  2162. AnalyseItem.cbCardEye = SwitchToCardData(i);
  2163. AnalyseItem.bMagicEye = false;
  2164. //插入结果
  2165. AnalyseItemArray.Add(AnalyseItem);
  2166. return true;
  2167. }
  2168. }
  2169. return false;
  2170. }
  2171. //拆分分析,用户手上的临时牌变量
  2172. BYTE cbMagicCardIndex[MAX_INDEX];
  2173. CopyMemory(cbMagicCardIndex, cbCardIndex, sizeof(cbMagicCardIndex));
  2174. if (cbCardCount >= 3)
  2175. {
  2176. for (BYTE i = 0; i < MAX_INDEX; i++)
  2177. {
  2178. //同牌判断
  2179. if (cbMagicCardIndex[i] >= 3)
  2180. {
  2181. ASSERT(cbKindItemCount < CountArray(KindItem));
  2182. KindItem[cbKindItemCount].cbCardIndex[0] = i;
  2183. KindItem[cbKindItemCount].cbCardIndex[1] = i;
  2184. KindItem[cbKindItemCount].cbCardIndex[2] = i;
  2185. KindItem[cbKindItemCount].cbWeaveKind = WIK_PENG;
  2186. KindItem[cbKindItemCount].cbCenterCard = SwitchToCardData(i);
  2187. KindItem[cbKindItemCount].cbValidIndex[0] = i;
  2188. KindItem[cbKindItemCount].cbValidIndex[1] = i;
  2189. KindItem[cbKindItemCount].cbValidIndex[2] = i;
  2190. cbKindItemCount++;
  2191. }
  2192. //连牌判断
  2193. if ((i < (MAX_INDEX - 9)) && ((i % 9) < 7))
  2194. {
  2195. //只要财神牌数加上3个顺序索引的牌数大于等于3,则进行组合
  2196. if (cbMagicCardIndex[i] + cbMagicCardIndex[i + 1] + cbMagicCardIndex[i + 2] >= 3)
  2197. {
  2198. BYTE cbIndex[3] = { cbMagicCardIndex[i], cbMagicCardIndex[i + 1], cbMagicCardIndex[i + 2] };
  2199. int nMagicCountTemp = 0;
  2200. BYTE cbValidIndex[3];
  2201. while (cbIndex[0] + cbIndex[1] + cbIndex[2] >= 3)
  2202. {
  2203. for (BYTE j = 0; j < CountArray(cbIndex); j++)
  2204. {
  2205. if (cbIndex[j] > 0)
  2206. {
  2207. cbIndex[j]--;
  2208. cbValidIndex[j] = i + j;
  2209. }
  2210. else
  2211. {
  2212. nMagicCountTemp--;
  2213. }
  2214. }
  2215. if (nMagicCountTemp == 0)
  2216. {
  2217. ASSERT(cbKindItemCount < CountArray(KindItem));
  2218. KindItem[cbKindItemCount].cbCardIndex[0] = i;
  2219. KindItem[cbKindItemCount].cbCardIndex[1] = i + 1;
  2220. KindItem[cbKindItemCount].cbCardIndex[2] = i + 2;
  2221. KindItem[cbKindItemCount].cbWeaveKind = WIK_LEFT;
  2222. KindItem[cbKindItemCount].cbCenterCard = SwitchToCardData(i);
  2223. CopyMemory(KindItem[cbKindItemCount].cbValidIndex, cbValidIndex, sizeof(cbValidIndex));
  2224. cbKindItemCount++;
  2225. }
  2226. else break;
  2227. }
  2228. }
  2229. }
  2230. }
  2231. }
  2232. //组合分析
  2233. if (cbKindItemCount >= cbLessKindItem)
  2234. {
  2235. //变量定义
  2236. BYTE cbCardIndexTemp[MAX_INDEX];
  2237. ZeroMemory(cbCardIndexTemp, sizeof(cbCardIndexTemp));
  2238. //变量定义
  2239. BYTE cbIndex[4] = { 0, 1, 2, 3 };
  2240. tagKindItem * pKindItem[4];
  2241. ZeroMemory(&pKindItem, sizeof(pKindItem));
  2242. //开始组合
  2243. do
  2244. {
  2245. //设置变量
  2246. CopyMemory(cbCardIndexTemp, cbCardIndex, sizeof(cbCardIndexTemp));
  2247. for (BYTE i = 0; i < cbLessKindItem; i++)
  2248. pKindItem[i] = &KindItem[cbIndex[i]];
  2249. //数量判断
  2250. bool bEnoughCard = true;
  2251. for (BYTE i = 0; i < cbLessKindItem * 3; i++)
  2252. {
  2253. //存在判断
  2254. BYTE cbCardIndex = pKindItem[i / 3]->cbValidIndex[i % 3];
  2255. if (cbCardIndexTemp[cbCardIndex] == 0)
  2256. {
  2257. bEnoughCard = false;
  2258. break;
  2259. }
  2260. else
  2261. cbCardIndexTemp[cbCardIndex]--;
  2262. }
  2263. //胡牌判断
  2264. if (bEnoughCard == true)
  2265. {
  2266. //牌眼判断
  2267. BYTE cbCardEye = 0;
  2268. bool bMagicEye = false;
  2269. for (BYTE i = 0; i < MAX_INDEX; i++)
  2270. {
  2271. if (cbCardIndexTemp[i] == 2)
  2272. {
  2273. cbCardEye = SwitchToCardData(i);
  2274. break;
  2275. }
  2276. }
  2277. //组合类型
  2278. if (cbCardEye != 0)
  2279. {
  2280. //变量定义
  2281. tagAnalyseItem AnalyseItem;
  2282. ZeroMemory(&AnalyseItem, sizeof(AnalyseItem));
  2283. //设置组合
  2284. for (BYTE i = 0; i < cbWeaveCount; i++)
  2285. {
  2286. AnalyseItem.cbWeaveKind[i] = WeaveItem[i].cbWeaveKind;
  2287. AnalyseItem.cbCenterCard[i] = WeaveItem[i].cbCenterCard;
  2288. GetWeaveCard(WeaveItem[i].cbWeaveKind, WeaveItem[i].cbCenterCard, WeaveItem[i].cbMargicOffset,
  2289. AnalyseItem.cbCardData[i]);
  2290. }
  2291. //设置牌型
  2292. for (BYTE i = 0; i < cbLessKindItem; i++)
  2293. {
  2294. AnalyseItem.cbWeaveKind[i + cbWeaveCount] = pKindItem[i]->cbWeaveKind;
  2295. AnalyseItem.cbCenterCard[i + cbWeaveCount] = pKindItem[i]->cbCenterCard;
  2296. AnalyseItem.cbCardData[cbWeaveCount + i][0] = SwitchToCardData(pKindItem[i]->cbValidIndex[0]);
  2297. AnalyseItem.cbCardData[cbWeaveCount + i][1] = SwitchToCardData(pKindItem[i]->cbValidIndex[1]);
  2298. AnalyseItem.cbCardData[cbWeaveCount + i][2] = SwitchToCardData(pKindItem[i]->cbValidIndex[2]);
  2299. }
  2300. //设置牌眼
  2301. AnalyseItem.cbCardEye = cbCardEye;
  2302. AnalyseItem.bMagicEye = bMagicEye;
  2303. //插入结果
  2304. AnalyseItemArray.Add(AnalyseItem);
  2305. }
  2306. }
  2307. //设置索引
  2308. if (cbIndex[cbLessKindItem - 1] == (cbKindItemCount - 1))
  2309. {
  2310. BYTE i = cbLessKindItem - 1;
  2311. for (; i > 0; i--)
  2312. {
  2313. if ((cbIndex[i - 1] + 1) != cbIndex[i])
  2314. {
  2315. BYTE cbNewIndex = cbIndex[i - 1];
  2316. for (BYTE j = (i - 1); j < cbLessKindItem; j++)
  2317. cbIndex[j] = cbNewIndex + j - i + 2;
  2318. break;
  2319. }
  2320. }
  2321. if (i == 0)
  2322. break;
  2323. }
  2324. else
  2325. cbIndex[cbLessKindItem - 1]++;
  2326. } while (true);
  2327. }
  2328. return (AnalyseItemArray.GetCount() > 0);
  2329. }
  2330. //删除癞子牌
  2331. BYTE CGameLogic_tdh::DeleteMagicCards(BYTE cbCardIndex[MAX_INDEX])
  2332. {
  2333. if (m_BaoMj_MagicType==MagicType_NoMagic)
  2334. {
  2335. return 0;
  2336. }
  2337. if (m_BaoMj_MagicType==MagicType_OneMagic)
  2338. {
  2339. BYTE cbCount = cbCardIndex[m_cbMagicIndexFirst];
  2340. cbCardIndex[m_cbMagicIndexFirst] = 0;
  2341. return cbCount;
  2342. }
  2343. if (m_BaoMj_MagicType==MagicType_TwoMagic)
  2344. {
  2345. BYTE cbCardData[2] = { 0 };
  2346. BYTE cbCount = cbCardIndex[m_cbMagicIndexFirst] + cbCardIndex[m_cbMagicIndexSecond];
  2347. cbCardIndex[m_cbMagicIndexFirst] = 0;
  2348. cbCardIndex[m_cbMagicIndexSecond] = 0;
  2349. return cbCount;
  2350. }
  2351. return 0;
  2352. }
  2353. BYTE CGameLogic_tdh::DeleteMagicCards(BYTE cbCardIndex[MAX_INDEX], int nDeleteCount)
  2354. {
  2355. int HaveMagicCount = GetMaigcCardCount(cbCardIndex);
  2356. if (nDeleteCount>HaveMagicCount || HaveMagicCount>8)
  2357. {
  2358. CString strInfo;
  2359. strInfo.Format(_T("DeleteMagicCards Have Magic=%d Delete=%d"), HaveMagicCount, nDeleteCount);
  2360. //OutputDebugString(strInfo);
  2361. return 0;
  2362. }
  2363. if (m_BaoMj_MagicType==MagicType_NoMagic)
  2364. {
  2365. return 0;
  2366. }
  2367. if (m_BaoMj_MagicType == MagicType_OneMagic)
  2368. {
  2369. if ((cbCardIndex[m_cbMagicIndexFirst] - nDeleteCount)>4 || (cbCardIndex[m_cbMagicIndexFirst] - nDeleteCount )<0)
  2370. {
  2371. return 0;
  2372. }
  2373. cbCardIndex[m_cbMagicIndexFirst] = cbCardIndex[m_cbMagicIndexFirst] - nDeleteCount;
  2374. return nDeleteCount;
  2375. }
  2376. if (m_BaoMj_MagicType==MagicType_TwoMagic)
  2377. {
  2378. BYTE nConut = 0;
  2379. int nFirstMagicCount = cbCardIndex[m_cbMagicIndexFirst];
  2380. int nSecondMagicCount = cbCardIndex[m_cbMagicIndexSecond];
  2381. if (nDeleteCount > (nFirstMagicCount + nSecondMagicCount))
  2382. {
  2383. return 0;
  2384. }
  2385. for (int i = 0; i < nDeleteCount; i++)
  2386. {
  2387. if (cbCardIndex[m_cbMagicIndexFirst] > 0) {
  2388. cbCardIndex[m_cbMagicIndexFirst]--;
  2389. nConut++;
  2390. }
  2391. else if (cbCardIndex[m_cbMagicIndexSecond] > 0)
  2392. {
  2393. cbCardIndex[m_cbMagicIndexSecond]--;
  2394. nConut++;
  2395. }
  2396. }
  2397. return nConut;
  2398. }
  2399. return 0;
  2400. }
  2401. //获取牌值需要财神牌个数nNeedNum,组成扑(扑指的是顺子或者三重牌(比如 一饼二饼三饼 或者东风东风东风))
  2402. int CGameLogic_tdh::GetOneColorNeedMagicCards(const BYTE cbCardData[MAX_COUNT], int DataCount, int nNeedNum, bool isShun)
  2403. {
  2404. //CString strTmpPrint;
  2405. //strTmpPrint = _T("GetOneColorNeedMagicCards 分析 ");
  2406. //{
  2407. // for (int i = 0; i < DataCount; i++)
  2408. // {
  2409. // CString tmp;
  2410. // tmp.Format(_T(" %02x"), cbCardData[i]);
  2411. // strTmpPrint.Append(tmp);
  2412. // }
  2413. // strTmpPrint.Append(_T("\r\n"));
  2414. // //OutputDebugString(strTmpPrint);
  2415. //}
  2416. if (mNeedMinMagicNum == 0)
  2417. {
  2418. return -1;
  2419. }
  2420. if (nNeedNum >= mNeedMinMagicNum)
  2421. {
  2422. return -1;
  2423. }
  2424. switch (DataCount)
  2425. {
  2426. case 0:{//cbCardData内没有同一花色的牌不需要财神牌变
  2427. mNeedMinMagicNum = min(nNeedNum, mNeedMinMagicNum);//0
  2428. break;
  2429. }
  2430. case 1:{
  2431. mNeedMinMagicNum = min(nNeedNum + 2, mNeedMinMagicNum);
  2432. CString strTmp;
  2433. strTmp.Format(_T("财神充当碰牌 需要2财神 %02X\r\n "), cbCardData[0]);
  2434. ////OutputDebugString(strTmp);
  2435. //mMagicData[mMagicDataCount++] = cbCardData[0];
  2436. break;
  2437. }
  2438. case 2:{
  2439. BYTE cbFirst = cbCardData[0];
  2440. BYTE cbSecend = cbCardData[1];
  2441. //花色是3 为 东南西北中发白 不可能出现顺子
  2442. if (GetCardColor(cbSecend) == 3)
  2443. {
  2444. if (cbFirst == cbSecend&!isShun)
  2445. {
  2446. //DebugLog(_T("GetOneColorNeedMagicCards 风牌只有刻字 %02x %02x %02x\r\n"),cbFirst,cbSecend,cbFirst);
  2447. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 1);
  2448. ////OutputDebugString(_T("财神是风牌的碰\r\n"));
  2449. mMagicData[mMagicDataCount++] = cbFirst;
  2450. }
  2451. else
  2452. {
  2453. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 4);
  2454. }
  2455. }
  2456. else if (cbSecend - cbFirst < 3)//判断相差两个顺序牌需要财神mMagicData变能“碰”、“吃”(左、中、右)
  2457. {
  2458. //DebugLog(_T("GetOneColorNeedMagicCards 顺子/刻字 %02x %02x magic\r\n"), cbFirst, cbSecend);
  2459. if (cbSecend-cbFirst==0)
  2460. {
  2461. CString strTmp;
  2462. strTmp.Format(_T("财神充当碰牌 %02X\r\n "), cbFirst);
  2463. ////OutputDebugString(strTmp);
  2464. mMagicData[mMagicDataCount++] = cbFirst;
  2465. }
  2466. else if (cbSecend-cbFirst==1)
  2467. {
  2468. if (GetCardValue(cbFirst)==1)
  2469. {
  2470. CString strTmp;
  2471. strTmp.Format(_T("财神充当 右吃 %02X\r\n "), cbSecend + 1);
  2472. ////OutputDebugString(strTmp);
  2473. mMagicData[mMagicDataCount++] = cbSecend+1;
  2474. }
  2475. else
  2476. {
  2477. CString strTmp;
  2478. strTmp.Format(_T("财神充当 左吃 %02X\r\n "), cbFirst - 1);
  2479. ////OutputDebugString(strTmp);
  2480. mMagicData[mMagicDataCount++] = cbFirst - 1;
  2481. }
  2482. }
  2483. else if (cbSecend-cbFirst==2)
  2484. {
  2485. CString strTmp;
  2486. strTmp.Format(_T("财神充当 中吃 %02X\r\n "), cbFirst+1);
  2487. ////OutputDebugString(strTmp);
  2488. mMagicData[mMagicDataCount++] = cbFirst+1;
  2489. }
  2490. if (isShun&&cbSecend - cbFirst == 0)
  2491. {
  2492. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 4);
  2493. }
  2494. else
  2495. {
  2496. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 1);
  2497. }
  2498. }
  2499. else
  2500. {
  2501. if (isShun)
  2502. {
  2503. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 4);
  2504. }
  2505. else{
  2506. mNeedMinMagicNum = min(mNeedMinMagicNum, nNeedNum + 4);
  2507. }
  2508. }
  2509. break;
  2510. }
  2511. default:
  2512. {
  2513. //取前三张
  2514. BYTE cbFirst = cbCardData[0];
  2515. BYTE cbSecend = cbCardData[1];
  2516. BYTE cbThree = cbCardData[2];
  2517. //第一个自己一扑
  2518. if (nNeedNum + 2 < mNeedMinMagicNum)
  2519. {
  2520. GetOneColorNeedMagicCards(cbCardData + 1, DataCount - 1, nNeedNum + 2, isShun);//从cbCardData一个一个元素开始,所以DataCount - 1,需要两个财神才能成(扑)
  2521. }
  2522. //第一个跟其它的一个一扑
  2523. if (nNeedNum + 1 < mNeedMinMagicNum){
  2524. if (GetCardColor(cbFirst) == 3){//东南西北中发白牌型
  2525. if (cbFirst == cbSecend)
  2526. {
  2527. GetOneColorNeedMagicCards(cbCardData + 2, DataCount - 2, nNeedNum + 1, isShun);//如果是刻字(两两相等),则需要+1财神牌变,才能碰(即成扑)
  2528. }
  2529. }
  2530. else
  2531. {
  2532. for (int i = 1; i < DataCount; i++)
  2533. {
  2534. if (nNeedNum + 1 >= mNeedMinMagicNum)//财神数最多7个,还有一个是第一次摸牌显示在台桌上无效
  2535. {
  2536. break;
  2537. }
  2538. cbSecend = cbCardData[i];
  2539. if (i + 1 != DataCount){
  2540. cbThree = cbCardData[i + 1];
  2541. if (cbThree == cbSecend){
  2542. continue;
  2543. }
  2544. }
  2545. if (GetCardValue(cbSecend) - GetCardValue(cbFirst) < 3)
  2546. {
  2547. //删除 此时的 p1 p2
  2548. /*BYTE *pTmpData = new BYTE[DataCount];
  2549. ZeroMemory(pTmpData, DataCount);
  2550. int nCount = 0;
  2551. for (int j = 0; j < DataCount; j++)
  2552. {
  2553. if (j == i || j == 0)
  2554. {
  2555. continue;
  2556. }
  2557. pTmpData[nCount++] = cbCardData[j];
  2558. }*/
  2559. if (isShun&&GetCardValue(cbSecend) - GetCardValue(cbFirst)==0)
  2560. {
  2561. BYTE delCards[2] = { 0 };
  2562. delCards[0] = cbFirst;
  2563. delCards[1] = cbSecend;
  2564. BYTE outCards[14] = { 0 };
  2565. DeleteCards(cbCardData, 14, delCards, 2, outCards);
  2566. GetOneColorNeedMagicCards(outCards, DataCount - 2, nNeedNum + 4, isShun);
  2567. }
  2568. else
  2569. {
  2570. BYTE delCards[2] = { 0 };
  2571. delCards[0] = cbFirst;
  2572. delCards[1] = cbSecend;
  2573. BYTE outCards[14] = { 0 };
  2574. DeleteCards(cbCardData, 14, delCards, 2, outCards);
  2575. GetOneColorNeedMagicCards(outCards, DataCount - 2, nNeedNum + 1, isShun);
  2576. }
  2577. }
  2578. else
  2579. {
  2580. break;
  2581. }
  2582. }
  2583. }
  2584. }
  2585. //第一个和其它两个一扑
  2586. //后面间隔两张张不跟前面一张相同222234
  2587. //可能性为222 234
  2588. for (int i = 1; i < DataCount; i++){
  2589. if (nNeedNum >= mNeedMinMagicNum){
  2590. break;
  2591. }
  2592. cbSecend = cbCardData[i];
  2593. if (i + 2 < DataCount)
  2594. {
  2595. if (cbCardData[i + 2] == cbSecend)
  2596. {
  2597. continue;
  2598. }
  2599. }
  2600. for (unsigned int j = i + 1; j < DataCount; j++)
  2601. {
  2602. if (nNeedNum >= mNeedMinMagicNum)
  2603. {
  2604. break;
  2605. }
  2606. cbThree = cbCardData[j];
  2607. if (cbFirst == cbThree)
  2608. {
  2609. //不处理
  2610. }
  2611. if (j + 1 < DataCount)
  2612. {
  2613. if (cbThree == cbCardData[j + 1])
  2614. {
  2615. continue;
  2616. }
  2617. }
  2618. if (isShun)
  2619. {
  2620. if (test3combineToShun(cbFirst, cbSecend, cbThree))
  2621. {
  2622. //删除 1 2 3
  2623. BYTE delCards[3] = { 0 };
  2624. delCards[0] = cbFirst;
  2625. delCards[1] = cbSecend;
  2626. delCards[2] = cbThree;
  2627. BYTE outCards[14] = { 0 };
  2628. DeleteCards(cbCardData, 14, delCards, 3, outCards);
  2629. CString strDeletecards;
  2630. CString strout = _T("删除 ");
  2631. for (int i = 0; i < 3; i++)
  2632. {
  2633. strDeletecards.Format(_T("%02x "), delCards[i]);
  2634. strout += strDeletecards;
  2635. }
  2636. ////OutputDebugString(strout);
  2637. GetOneColorNeedMagicCards(outCards, DataCount - 3, nNeedNum, isShun);
  2638. }
  2639. }
  2640. else
  2641. {
  2642. if (test3Combine(cbFirst, cbSecend, cbThree))
  2643. {
  2644. //删除 1 2 3
  2645. BYTE delCards[3] = { 0 };
  2646. delCards[0] = cbFirst;
  2647. delCards[1] = cbSecend;
  2648. delCards[2] = cbThree;
  2649. BYTE outCards[14] = { 0 };
  2650. DeleteCards(cbCardData, 14, delCards, 3, outCards);
  2651. CString strDeletecards;
  2652. CString strout = _T("删除 ");
  2653. for (int i = 0; i < 3; i++)
  2654. {
  2655. strDeletecards.Format(_T("%02x "), delCards[i]);
  2656. strout += strDeletecards;
  2657. }
  2658. ////OutputDebugString(strout);
  2659. GetOneColorNeedMagicCards(outCards, DataCount - 3, nNeedNum, isShun);
  2660. }
  2661. }
  2662. }
  2663. }
  2664. }
  2665. break;
  2666. }
  2667. }
  2668. //钻牌
  2669. bool CGameLogic_tdh::IsMagicCard( BYTE cbCardData )
  2670. {
  2671. if (m_BaoMj_MagicType==MagicType_NoMagic)
  2672. {
  2673. return false;
  2674. }
  2675. if (m_BaoMj_MagicType==MagicType_OneMagic)
  2676. {
  2677. if (SwitchToCardIndex(cbCardData)==m_cbMagicIndexFirst)
  2678. {
  2679. return true;
  2680. }
  2681. }
  2682. if (m_BaoMj_MagicType==MagicType_TwoMagic)
  2683. {
  2684. if (SwitchToCardIndex(cbCardData) == m_cbMagicIndexFirst ||
  2685. SwitchToCardIndex(cbCardData) == m_cbMagicIndexSecond)
  2686. return true;
  2687. }
  2688. return false;
  2689. }
  2690. //test3
  2691. bool CGameLogic_tdh::test3Combine(const BYTE cbCard1, const BYTE cbCard2, const BYTE cbCard3)
  2692. {
  2693. //花色不同 不能组合
  2694. if (GetCardColor(cbCard1) != GetCardColor(cbCard2) || GetCardColor(cbCard1) != GetCardColor(cbCard3))
  2695. {
  2696. return false;
  2697. }
  2698. //刻字
  2699. if (cbCard1 == cbCard2&& cbCard2 == cbCard3)
  2700. {
  2701. // DebugLog(_T("test3Combine 刻字 %02x %02x %02x\r\n"), cbCard1, cbCard2, cbCard3);
  2702. return true;
  2703. }
  2704. //风牌不能组成顺子
  2705. if (GetCardColor(cbCard3) == 3)
  2706. {
  2707. return false;
  2708. }
  2709. if (cbCard1 + 1 == cbCard2&& cbCard2 + 1 == cbCard3)
  2710. {
  2711. // DebugLog(_T("test3Combine 顺子 %02x %02x %02x\r\n"), cbCard1, cbCard2, cbCard3);
  2712. return true;
  2713. }
  2714. return false;
  2715. }
  2716. bool CGameLogic_tdh::test3combineToShun(const BYTE cbCard1, const BYTE cbCard2, const BYTE cbCard3)
  2717. {
  2718. //花色不同 不能组合
  2719. if (GetCardColor(cbCard1) != GetCardColor(cbCard2) || GetCardColor(cbCard1) != GetCardColor(cbCard3))
  2720. {
  2721. return false;
  2722. }
  2723. //风牌不能组成顺子
  2724. if (GetCardColor(cbCard3) == 3)
  2725. {
  2726. return false;
  2727. }
  2728. if (cbCard1 + 1 == cbCard2&& cbCard2 + 1 == cbCard3)
  2729. {
  2730. // DebugLog(_T("test3Combine 顺子 %02x %02x %02x\r\n"), cbCard1, cbCard2, cbCard3);
  2731. return true;
  2732. }
  2733. return false;
  2734. }
  2735. //test2
  2736. bool CGameLogic_tdh::test2Combine(const BYTE cbCard1, const BYTE cbCard2)
  2737. {
  2738. if (cbCard1 == cbCard2)
  2739. {
  2740. // DebugLog(_T("test3Combine peng %02x %02x \r\n"), cbCard1, cbCard2);
  2741. return true;
  2742. }
  2743. return false;
  2744. }
  2745. //排序,根据牌值排序
  2746. bool CGameLogic_tdh::SortCardList( BYTE cbCardData[MAX_COUNT], BYTE cbCardCount )
  2747. {
  2748. //数目过虑
  2749. if (cbCardCount==0||cbCardCount>MAX_COUNT) return false;
  2750. //排序操作
  2751. bool bSorted=true;
  2752. BYTE cbSwitchData=0,cbLast=cbCardCount-1;
  2753. do
  2754. {
  2755. bSorted=true;
  2756. for (BYTE i=0;i<cbLast;i++)
  2757. {
  2758. if (cbCardData[i]>cbCardData[i+1])
  2759. {
  2760. //设置标志
  2761. bSorted=false;
  2762. //扑克数据
  2763. cbSwitchData=cbCardData[i];
  2764. cbCardData[i]=cbCardData[i+1];
  2765. cbCardData[i+1]=cbSwitchData;
  2766. }
  2767. }
  2768. cbLast--;
  2769. } while(bSorted==false);
  2770. return true;
  2771. }
  2772. //编码
  2773. //WORD占两个字节,
  2774. //num占高三位,剩下给倍数
  2775. //uFangShu 7位
  2776. //PaiZhi 占用低六位,
  2777. WORD CGameLogic_tdh::GetValue(BYTE uNum, BYTE uFangShu, WORD PaiZhi)
  2778. {
  2779. CString strJiaMi;
  2780. strJiaMi.Format(_T("[zoro] PaiZhi=0x%x fanshu=%d num=%d\r\n"),PaiZhi,uFangShu,uNum);
  2781. //OutputDebugString(strJiaMi);
  2782. WORD mcd = PaiZhi | (uFangShu << 6) | (uNum << 13);
  2783. int cbCard;
  2784. int cbFan;
  2785. int cbNum;
  2786. cbCard = mcd & 0x003F;
  2787. cbFan = (mcd & 0x07C0) >> 6;
  2788. cbNum = (mcd & 0xE000) >> 13;
  2789. CString strJieMi;
  2790. strJiaMi.Format(_T("[zoro] JieMI PaiZhi=0x%x fanshu=%d num=%d\r\n"), cbCard, cbFan, cbNum);
  2791. //OutputDebugString(strJieMi);
  2792. if (cbCard!=PaiZhi||cbFan!=uFangShu||cbNum!=uNum)
  2793. {
  2794. OutputDebugString(_T("加解密失败"));
  2795. }
  2796. return mcd;
  2797. }
  2798. //解码
  2799. BYTE CGameLogic_tdh::DeCodeCard(const WORD cbCardData)
  2800. {
  2801. BYTE TempCardData = cbCardData & 0x003F;
  2802. return TempCardData;
  2803. }
  2804. //解码番薯
  2805. BYTE CGameLogic_tdh::DeCodeFanshu(const WORD cbCardData)
  2806. {
  2807. //BYTE num = (cbCardData & 0x3800) >> 11;
  2808. BYTE fanshu = (cbCardData & 0x07C0) >> 6;
  2809. //BYTE TempCardData = cbCardData & 0x003F;
  2810. return fanshu;
  2811. }
  2812. bool CGameLogic_tdh::PeiPai(BYTE ParZhi[MAX_REPERTORY_ZJ])
  2813. {
  2814. std::ifstream in;
  2815. std::string filename = "zuopai.dat";
  2816. in.open(filename);
  2817. if (!in.is_open())
  2818. {
  2819. return false;
  2820. }
  2821. static BYTE TempCardData[MAX_REPERTORY_ZJ];
  2822. ZeroMemory(TempCardData, sizeof(TempCardData));
  2823. BYTE tempCount = 0;
  2824. char ch[1];
  2825. while (!in.eof())
  2826. {
  2827. in.read(ch, 1);
  2828. TempCardData[tempCount++] = ch[0];
  2829. }
  2830. in.close();
  2831. if (tempCount<MAX_REPERTORY_ZJ)
  2832. {
  2833. return false;
  2834. }
  2835. for (BYTE i = 0; i < MAX_REPERTORY_ZJ; i++)
  2836. {
  2837. ASSERT(i < MAX_REPERTORY_ZJ);
  2838. ParZhi[i] = TempCardData[MAX_REPERTORY_ZJ - i - 1];
  2839. }
  2840. return true;
  2841. }
  2842. BYTE CGameLogic_tdh::GetEndCard(BYTE cbCardIndex[MAX_INDEX])
  2843. {
  2844. for (BYTE i = MAX_INDEX - 1; i >= 0; i--)
  2845. {
  2846. if (cbCardIndex[i] > 0 && !IsMagicCard(SwitchToCardData(i)))
  2847. {
  2848. return SwitchToCardData(i);
  2849. }
  2850. }
  2851. if (m_BaoMj_MagicType==MagicType_OneMagic)
  2852. {
  2853. return SwitchToCardData(m_cbMagicIndexFirst);
  2854. }
  2855. if (m_BaoMj_MagicType==MagicType_TwoMagic)
  2856. {
  2857. if (m_cbMagicIndexFirst > m_cbMagicIndexSecond)
  2858. {
  2859. return SwitchToCardData(m_cbMagicIndexFirst);
  2860. }
  2861. return SwitchToCardData(m_cbMagicIndexSecond);
  2862. }
  2863. }
  2864. /*
  2865. // 胡法分析函数
  2866. */
  2867. //大对子
  2868. bool CGameLogic_tdh::IsPengPeng(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], const BYTE cbItemCount)
  2869. {
  2870. for (BYTE i = 0; i < cbItemCount; i++)
  2871. {
  2872. if (WeaveItem[i].cbWeaveKind&(WIK_LEFT | WIK_RIGHT | WIK_CENTER))
  2873. return false;
  2874. }
  2875. BYTE cbCardCount = GetCardCount(cbCardIndex);
  2876. BYTE DanCount = 0;
  2877. BYTE DuiZiCount = 0;
  2878. for (BYTE i = 0; i<MAX_INDEX; i++)
  2879. {
  2880. if (cbCardIndex[i] == 3)
  2881. {
  2882. DuiZiCount++;
  2883. }
  2884. if (cbCardIndex[i] == 2)
  2885. {
  2886. DanCount++;
  2887. }
  2888. }
  2889. switch (cbCardCount)
  2890. {
  2891. case 2:
  2892. if (DanCount == 1)
  2893. return true;
  2894. case 5:
  2895. if (DuiZiCount == 1 && DanCount == 1)
  2896. return true;
  2897. case 8:
  2898. if (DuiZiCount == 2 && DanCount == 1)
  2899. return true;
  2900. case 11:
  2901. if (DuiZiCount == 3 && DanCount == 1)
  2902. return true;
  2903. case 14:
  2904. if (DuiZiCount == 4 && DanCount == 1)
  2905. return true;
  2906. default:
  2907. return false;
  2908. }
  2909. return false;
  2910. }
  2911. //清一色牌
  2912. bool CGameLogic_tdh::IsQingYiSe(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], const BYTE cbItemCount)
  2913. {
  2914. ////胡牌判断
  2915. //BYTE cbCardColor = 0xFF;
  2916. //for (BYTE i = 0; i < MAX_INDEX; i++)
  2917. //{
  2918. // if (cbCardIndex[i] != 0)
  2919. // {
  2920. // //花色判断
  2921. // if (cbCardColor != 0xFF)
  2922. // return false;
  2923. // //设置花色
  2924. // cbCardColor = (SwitchToCardData(i)&MASK_COLOR);
  2925. // //设置索引
  2926. // i = (i / 9 + 1) * 9 - 1;
  2927. // }
  2928. //}
  2929. ////组合判断
  2930. //for (BYTE i = 0; i<cbItemCount; i++)
  2931. //{
  2932. // BYTE cbCenterCard = WeaveItem[i].cbCenterCard;
  2933. // if ((cbCenterCard&MASK_COLOR) != cbCardColor) return false;
  2934. //}
  2935. //return true;
  2936. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  2937. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  2938. //////////////////////////////////////////////////////////////////////////
  2939. //有风牌 不是青一色
  2940. int cbItemColor = -1;
  2941. for (int i = 0; i < cbItemCount; i++)
  2942. {
  2943. BYTE cbColor = GetCardColor(WeaveItem[i].cbCenterCard);
  2944. if (cbColor == Color_Feng)
  2945. {
  2946. return false;
  2947. }
  2948. if (cbItemColor == -1)
  2949. {
  2950. cbItemColor = cbColor;
  2951. }
  2952. if (cbItemColor != cbColor)
  2953. {
  2954. return false;
  2955. }
  2956. }
  2957. //////////////////////////////////////////////////////////////////////////
  2958. //删除风 删除财神 判断是否是一色
  2959. int nCurrentMagicCount = DeleteMagicCards(TmpcbCardIndex);
  2960. //如果有 东南西北中发白 不可能是青一色
  2961. bool bHasFeng2 = false;
  2962. for (int i = 1; i < 8; i++)
  2963. {
  2964. if (TmpcbCardIndex[26 + i] >0 )
  2965. {
  2966. return false;
  2967. }
  2968. }
  2969. if (cbItemColor != -1)
  2970. {
  2971. for (BYTE i = 0; i < 27; i++){
  2972. if (TmpcbCardIndex[i] != 0)
  2973. {
  2974. if (GetCardColor(SwitchToCardData(i)) != cbItemColor)
  2975. {
  2976. return false;
  2977. }
  2978. }
  2979. }
  2980. }
  2981. else
  2982. {
  2983. BYTE cbFirst = 0;
  2984. //遍历前 27张0-26
  2985. //得到第一张颜色 如果后面的颜色与第一个不一样,返回false
  2986. for (BYTE i = 0; i < 27; i++){
  2987. if (TmpcbCardIndex[i] != 0)
  2988. {
  2989. if (cbFirst == 0)
  2990. {
  2991. cbFirst = SwitchToCardData(i);
  2992. continue;
  2993. }
  2994. if (GetCardColor(cbFirst) != GetCardColor(SwitchToCardData(i)))
  2995. {
  2996. return false;
  2997. }
  2998. }
  2999. }
  3000. }
  3001. return true;
  3002. }
  3003. //门前清
  3004. bool CGameLogic_tdh::IsMenQianQing(const tagWeaveItem WeaveItem[], const BYTE cbWeaveCount)
  3005. {
  3006. for (int i = 0; i < cbWeaveCount; i++)
  3007. {
  3008. if (WeaveItem[i].cbWeaveKind & (WIK_LEFT|WIK_RIGHT|WIK_CENTER|WIK_PENG|WIK_MING_GANG|WIK_BU_GANG))
  3009. {
  3010. return false;
  3011. }
  3012. }
  3013. return true;
  3014. }
  3015. bool CGameLogic_tdh::HaveFengKe(BYTE cbCardIndex[MAX_INDEX], tagWeaveItem WeaveItem[], BYTE& cbItemCount,int nCardIndex)
  3016. {
  3017. //手牌已经有3个或以上 东风,则不需要计算了,有
  3018. BYTE cbCardTmpIndex[MAX_INDEX];
  3019. ZeroMemory(cbCardTmpIndex, MAX_INDEX);
  3020. CopyMemory(cbCardTmpIndex, cbCardIndex, MAX_INDEX);
  3021. if (cbCardTmpIndex[nCardIndex] >= 3 && !IsMagicCard(SwitchToCardData(nCardIndex))){
  3022. //手牌减去3个东风
  3023. cbCardTmpIndex[nCardIndex] -= 3;
  3024. WeaveItem[cbItemCount].cbCenterCard = SwitchToCardData(nCardIndex);
  3025. WeaveItem[cbItemCount].cbWeaveKind = WIK_PENG;
  3026. CopyMemory(cbCardIndex, cbCardTmpIndex, MAX_INDEX);
  3027. cbItemCount = cbItemCount + 1;
  3028. return true;
  3029. }
  3030. int nCountGang=0;
  3031. BYTE cbIndex[4] = { 0 };
  3032. for (int i = 0; i < MAX_INDEX;i++)
  3033. {
  3034. if (cbCardTmpIndex[i]==4&&!IsMagicCard(SwitchToCardData(i)))
  3035. {
  3036. cbIndex[nCountGang++]=i;
  3037. }
  3038. }
  3039. if (nCountGang>=2)
  3040. {
  3041. BYTE cbCardTmp2Index[MAX_INDEX];
  3042. ZeroMemory(cbCardTmp2Index, MAX_INDEX);
  3043. CopyMemory(cbCardTmp2Index, cbCardTmpIndex, MAX_INDEX);
  3044. int nMagicTmpCount = DeleteMagicCards(cbCardTmp2Index);
  3045. for (int i = 0; i < nCountGang; i++)
  3046. {
  3047. cbCardTmp2Index[cbIndex[i]] = 1;
  3048. }
  3049. if (nMagicTmpCount>3)
  3050. {
  3051. nMagicTmpCount -= 3;
  3052. }
  3053. if (!TestHu(cbCardTmp2Index, nMagicTmpCount, WeaveItem, cbItemCount))
  3054. {
  3055. return false;
  3056. }
  3057. }
  3058. //如果手牌有 1/2 东风,怎计算一下 拿财神配合一下 剩下的牌胡不胡
  3059. // if (cbCardIndex[nCardIndex]>0)
  3060. // {
  3061. int nMagic = GetMaigcCardCount(cbCardIndex);
  3062. if (cbCardIndex[nCardIndex] !=0&& IsMagicCard(SwitchToCardData(nCardIndex)))//
  3063. {
  3064. if (nMagic<3)
  3065. {
  3066. return false;
  3067. }
  3068. //减去三个财神 判断能不能胡
  3069. if (DeleteMagicCards(cbCardTmpIndex, 3) != 3){
  3070. return false;
  3071. }
  3072. {
  3073. tagWeaveItem TmpWeaveItem[7];
  3074. ZeroMemory(TmpWeaveItem, sizeof(TmpWeaveItem));
  3075. CopyMemory(TmpWeaveItem, WeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3076. int cbItemCountTmp = cbItemCount;
  3077. TmpWeaveItem[cbItemCountTmp].cbCenterCard = SwitchToCardData(nCardIndex);
  3078. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SHUANG_PENG;
  3079. if (AnalyseCardNew(cbCardTmpIndex, TmpWeaveItem, cbItemCountTmp))
  3080. {
  3081. cbItemCount = cbItemCountTmp + 1;
  3082. CopyMemory(cbCardIndex, cbCardTmpIndex, MAX_INDEX);
  3083. CopyMemory(WeaveItem, TmpWeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3084. return true;
  3085. }
  3086. }
  3087. //////////////////////////////////////////////////////////////////////////////
  3088. //减去4个财神 判断能不能胡
  3089. ZeroMemory(cbCardTmpIndex, MAX_INDEX);
  3090. CopyMemory(cbCardTmpIndex, cbCardIndex, MAX_INDEX);
  3091. if (GetMaigcCardCount(cbCardIndex)>=4)
  3092. {
  3093. if (DeleteMagicCards(cbCardTmpIndex, 4) != 4){
  3094. return false;
  3095. }
  3096. {
  3097. tagWeaveItem TmpWeaveItem[7];
  3098. ZeroMemory(TmpWeaveItem, sizeof(TmpWeaveItem));
  3099. CopyMemory(TmpWeaveItem, WeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3100. int cbItemCountTmp = cbItemCount;
  3101. TmpWeaveItem[cbItemCountTmp].cbCenterCard = SwitchToCardData(nCardIndex);
  3102. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SAN_MING_GANG;
  3103. if (AnalyseCardNew(cbCardTmpIndex, TmpWeaveItem, cbItemCountTmp))
  3104. {
  3105. cbItemCount = cbItemCountTmp + 1;
  3106. CopyMemory(cbCardIndex, cbCardTmpIndex, MAX_INDEX);
  3107. CopyMemory(WeaveItem, TmpWeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3108. return true;
  3109. }
  3110. }
  3111. }
  3112. }
  3113. else
  3114. {
  3115. if (nMagic + cbCardIndex[nCardIndex] < 3)
  3116. {
  3117. return false;
  3118. }
  3119. }
  3120. //组成3张刻字
  3121. int nDeleteMagic = 0;
  3122. if (cbCardIndex[nCardIndex]<4)
  3123. {
  3124. nDeleteMagic = 3 - cbCardIndex[nCardIndex];
  3125. cbCardTmpIndex[nCardIndex] = 0;
  3126. if (DeleteMagicCards(cbCardTmpIndex, nDeleteMagic) == nDeleteMagic)
  3127. {
  3128. tagWeaveItem TmpWeaveItem[7];
  3129. ZeroMemory(TmpWeaveItem, sizeof(TmpWeaveItem));
  3130. CopyMemory(TmpWeaveItem, WeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3131. int cbItemCountTmp = cbItemCount;
  3132. TmpWeaveItem[cbItemCountTmp].cbCenterCard = SwitchToCardData(nCardIndex);
  3133. if (nDeleteMagic == 1)
  3134. {
  3135. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_DAN_PENG;
  3136. }
  3137. else if (nDeleteMagic == 2)
  3138. {
  3139. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SHUANG_PENG;
  3140. }
  3141. else
  3142. {
  3143. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SHUANG_PENG;
  3144. }
  3145. if (AnalyseCardNew(cbCardTmpIndex, TmpWeaveItem, cbItemCountTmp))
  3146. {
  3147. cbItemCount = cbItemCountTmp + 1;
  3148. CopyMemory(cbCardIndex, cbCardTmpIndex, MAX_INDEX);
  3149. CopyMemory(WeaveItem, TmpWeaveItem, sizeof(tagWeaveItem)*cbItemCount);
  3150. return true;
  3151. }
  3152. }
  3153. }
  3154. //组成4张杠
  3155. {
  3156. ZeroMemory(cbCardTmpIndex, MAX_INDEX);
  3157. CopyMemory(cbCardTmpIndex, cbCardIndex, MAX_INDEX);
  3158. if (nMagic + cbCardIndex[nCardIndex]<4)
  3159. {
  3160. return false;
  3161. }
  3162. int nDeleteMagic = 4 - cbCardIndex[nCardIndex];
  3163. cbCardTmpIndex[nCardIndex] = 0;
  3164. if (DeleteMagicCards(cbCardTmpIndex, nDeleteMagic) == nDeleteMagic)
  3165. {
  3166. tagWeaveItem TmpWeaveItem[7];
  3167. CopyMemory(TmpWeaveItem, WeaveItem, sizeof(WeaveItem));
  3168. int cbItemCountTmp = cbItemCount;
  3169. TmpWeaveItem[cbItemCountTmp].cbCenterCard = SwitchToCardData(nCardIndex);
  3170. if (nDeleteMagic == 1)
  3171. {
  3172. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_DAN_MING_GANG;
  3173. }
  3174. else if (nDeleteMagic == 2)
  3175. {
  3176. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SHUANG_PENG;
  3177. }
  3178. else{
  3179. TmpWeaveItem[cbItemCountTmp].cbWeaveKind = WIK_SAN_MING_GANG;
  3180. }
  3181. if (AnalyseCardNew(cbCardTmpIndex, TmpWeaveItem, cbItemCountTmp))
  3182. {
  3183. CopyMemory(cbCardIndex, cbCardTmpIndex, MAX_INDEX);
  3184. CopyMemory(WeaveItem, TmpWeaveItem, sizeof(TmpWeaveItem));
  3185. cbItemCount = cbItemCountTmp+1;
  3186. return true;
  3187. }
  3188. }
  3189. }
  3190. // }
  3191. return false;
  3192. }
  3193. //获取癞子个数
  3194. BYTE CGameLogic_tdh::GetMaigcCardCount(const BYTE cbCardIndex[MAX_INDEX])
  3195. {
  3196. if (m_BaoMj_MagicType==MagicType_NoMagic)
  3197. {
  3198. return 0;
  3199. }
  3200. if (m_BaoMj_MagicType==MagicType_OneMagic)
  3201. {
  3202. return cbCardIndex[m_cbMagicIndexFirst];
  3203. }
  3204. if (m_BaoMj_MagicType==MagicType_TwoMagic)
  3205. {
  3206. return cbCardIndex[m_cbMagicIndexFirst] + cbCardIndex[m_cbMagicIndexSecond];
  3207. }
  3208. return 0;
  3209. }
  3210. //对财神牌可变牌判断
  3211. void CGameLogic_tdh::IsCanChangCardAndCount(const BYTE cbCardIndex[MAX_INDEX], BYTE Fanhui[MAX_INDEX])
  3212. {
  3213. //目的 减少后续的计算里量
  3214. //遍历手牌,将包含的牌 附近的2张牌 设置为1,因为只有相关的牌才可能产生影响,不产生影响的牌 不必要计算
  3215. //如果手牌没有万字 则可以在后续计算时 排除万字计算
  3216. ZeroMemory(Fanhui, MAX_INDEX);
  3217. for (int UserCardIndex = 0; UserCardIndex < MAX_INDEX; UserCardIndex++)
  3218. {
  3219. if (UserCardIndex>31||UserCardIndex==27)
  3220. {
  3221. Fanhui[UserCardIndex] = 1;
  3222. continue;
  3223. }
  3224. if (cbCardIndex[UserCardIndex] != 0)
  3225. {
  3226. if (UserCardIndex < 27)
  3227. {
  3228. if ((UserCardIndex % 9) > 2 && (UserCardIndex % 9) < 7)
  3229. {
  3230. //如果有 3-7 的手牌 则把前后2张牌 都设置为 有用的牌,留下来计算
  3231. for (int j = UserCardIndex - 2; j <= UserCardIndex + 2; j++)
  3232. {
  3233. Fanhui[j] = 1;
  3234. }
  3235. }
  3236. else if ((UserCardIndex % 9) <= 2)
  3237. {
  3238. //如水果是1-2 则把后两张设置为可用
  3239. BYTE GaoWei = UserCardIndex / 9;
  3240. for (int j = 9 * GaoWei; j <= UserCardIndex + 2; j++)
  3241. {
  3242. Fanhui[j] = 1;
  3243. }
  3244. }
  3245. else
  3246. {
  3247. //如水果是8-9 则把前两张设置为可用
  3248. for (int j = UserCardIndex - 2; j < (1 + UserCardIndex / 9) * 9; j++)
  3249. {
  3250. Fanhui[j] = 1;
  3251. }
  3252. }
  3253. }
  3254. else
  3255. {
  3256. //风牌都设置为1
  3257. Fanhui[UserCardIndex] = 1;
  3258. }
  3259. }
  3260. }
  3261. }
  3262. void CGameLogic_tdh::ShowMagicData()
  3263. {
  3264. if (mMagicDataCount==0)
  3265. {
  3266. return;
  3267. }
  3268. CString strData;
  3269. strData = _T("财神充当以下牌 ");
  3270. for (int i = 0; i < mMagicDataCount;i++)
  3271. {
  3272. mMagicReplaceCard[SwitchToCardIndex(mMagicData[i])] = 1;
  3273. CString strTmpData;
  3274. strTmpData.Format(_T(" %02x "), mMagicData[i]);
  3275. strData.Append(strTmpData);
  3276. }
  3277. strData.Append(_T("\r\n"));
  3278. ////OutputDebugString(strData);
  3279. }
  3280. void CGameLogic_tdh::ShowMagicReplaceData()
  3281. {
  3282. CString strData;
  3283. strData = _T("ShowMagicReplaceData 财神充当以下牌 ----------\r\n");
  3284. for (int n = 0; n < MAX_INDEX;n++)
  3285. {
  3286. if (mMagicReplaceCard[n]>0)
  3287. {
  3288. CString strTmpData;
  3289. strTmpData.Format(_T(" %02x "), SwitchToCardData(n));
  3290. strData.Append(strTmpData);
  3291. }
  3292. }
  3293. strData.Append(_T("\r\n"));
  3294. ////OutputDebugString(strData);
  3295. }
  3296. //删掉pSrc数组中有和pDeleteCards中的nDelCount个元素相等的元素,再将删了元素的数组pSrc,重新按序放入一个新的数组中Cards
  3297. void CGameLogic_tdh::DeleteCards(const BYTE* pSrc, int nCount, const BYTE* pDeleteCards, int nDelCount, BYTE Cards[14]) {
  3298. BYTE * pTmpSrc = new BYTE[nCount];
  3299. ZeroMemory(pTmpSrc, nCount);
  3300. CopyMemory(pTmpSrc, pSrc, nCount);
  3301. for (int i = 0; i < nDelCount; i++)
  3302. {
  3303. for (int nSrc = 0; nSrc < nCount; nSrc++) {
  3304. if (pDeleteCards[i]== pTmpSrc[nSrc])
  3305. {
  3306. pTmpSrc[nSrc] = 0;
  3307. break;
  3308. }
  3309. }
  3310. }
  3311. int nCountOut = 0;
  3312. ZeroMemory(Cards, 14);
  3313. for (int i = 0; i < nCount; i++)
  3314. {
  3315. if (pTmpSrc[i]!=0)
  3316. {
  3317. Cards[nCountOut++] = pTmpSrc[i];
  3318. }
  3319. }
  3320. delete pTmpSrc;
  3321. pTmpSrc = NULL;
  3322. }
  3323. BOOL CGameLogic_tdh::IsCanHuAllCards(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  3324. {
  3325. BYTE TmpcbCardIndex[MAX_INDEX] = { 0 };
  3326. CopyMemory(TmpcbCardIndex, cbCardIndex, MAX_INDEX);
  3327. int begin = 26;//0验证所有 26 只验证东西南北中发白
  3328. int nCanHuCount = 0;
  3329. for (int i = begin; i < MAX_INDEX; i++)
  3330. {
  3331. if (TmpcbCardIndex[i] == 4)
  3332. {
  3333. continue;
  3334. }
  3335. TmpcbCardIndex[i]++;
  3336. if (!AnalyseCardNew(TmpcbCardIndex, WeaveItem, cbWeaveCount))
  3337. {
  3338. TmpcbCardIndex[i]--;
  3339. return FALSE;
  3340. }
  3341. else
  3342. {
  3343. TmpcbCardIndex[i]--;
  3344. if (TmpcbCardIndex[i]==0)
  3345. {
  3346. nCanHuCount++;
  3347. if (nCanHuCount>2)
  3348. {
  3349. return TRUE;
  3350. }
  3351. }
  3352. }
  3353. }
  3354. //由于系统产生了卡顿现象,先修改是否为财吊的算法,仅判断 是否可以胡 东西南北中发白
  3355. return TRUE;
  3356. }
  3357. BOOL CGameLogic_tdh::IsSiCaiHu(const BYTE cbCardIndex[MAX_INDEX], const tagWeaveItem WeaveItem[], BYTE cbWeaveCount)
  3358. {
  3359. return GetMaigcCardCount(cbCardIndex) == 4;
  3360. }
  3361. //////////////////////////////////////////////////////////////////////////