诸暨麻将添加redis
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

3857 righe
95 KiB

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