诸暨麻将添加redis
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

803 rader
17 KiB

  1. #include "StdAfx.h"
  2. #include ".\androidai.h"
  3. /////////////////////////////////////////////////////////////////////////////////////
  4. //CAndroidAIBase
  5. CAndroidAIBase::CAndroidAIBase()
  6. {
  7. memset(m_byCardData,0xff,sizeof(m_byCardData));
  8. }
  9. CAndroidAIBase::~CAndroidAIBase()
  10. {
  11. }
  12. //设置牌
  13. void CAndroidAIBase::SetCardData( const BYTE cbCardData[],BYTE byCardCount, tagWeaveItem wi[MAX_WEAVE], BYTE cbWeaveCount )
  14. {
  15. //复制牌
  16. CopyMemory(m_byCardData,cbCardData,sizeof(BYTE)*byCardCount);
  17. m_byCardCount = byCardCount;
  18. //初始化
  19. ZeroMemory(m_bSelect,sizeof(m_bSelect));
  20. //
  21. ZeroMemory(m_byThreeCard,sizeof(m_byThreeCard));
  22. m_byThreeCount = 0;
  23. ZeroMemory(m_byGoodThreeCard,sizeof(m_byGoodThreeCard));
  24. m_byGoodThreeCount = 0;
  25. //
  26. ZeroMemory(m_byTwoCard,sizeof(m_byTwoCard));
  27. m_byTwoCount = 0;
  28. ZeroMemory(m_byGoodTwoCard,sizeof(m_byGoodTwoCard));
  29. m_byGoodTwoCount = 0;
  30. //
  31. ZeroMemory(m_byRemainThree,sizeof(m_byRemainThree));
  32. m_byRemainThreeCount = 0;
  33. ZeroMemory(m_byRemainTwo,sizeof(m_byRemainTwo));
  34. m_byRemainTwoCount = 0;
  35. //
  36. m_nMaxScoreThree = m_nMaxScoreTwo = 0;
  37. m_nActionScore = 0;
  38. m_nScoreThree = m_nScoreTwo = 0;
  39. //
  40. m_bHaveJiang = false;
  41. //
  42. m_byBadlyCard = 0xff;
  43. //胡牌限制条件
  44. m_cbColorCount = 0;
  45. ZeroMemory( m_cbColor,sizeof(m_cbColor) );
  46. m_cbMinColorCount = MAX_COUNT;
  47. //搜索花色
  48. for( BYTE i = 0; i < byCardCount; i++ )
  49. {
  50. m_cbColor[(cbCardData[i]/9)]++;
  51. }
  52. for( BYTE i = 0; i < cbWeaveCount; i++ )
  53. {
  54. m_cbColor[(wi[i].cbCenterCard&MASK_COLOR)>>4]++;
  55. }
  56. for( BYTE i = 0; i < 3; i++ )
  57. {
  58. if( m_cbColor[i] > 0 )
  59. m_cbColorCount++;
  60. if( m_cbColor[i] < m_cbMinColorCount )
  61. m_cbMinColorCount = m_cbColor[i];
  62. }
  63. }
  64. //获取最差牌
  65. BYTE CAndroidAIBase::GetBadlyCard()
  66. {
  67. return m_byBadlyCard;
  68. }
  69. //获取最大分
  70. int CAndroidAIBase::GetMaxScore()
  71. {
  72. return m_nActionScore+m_nMaxScoreThree+m_nMaxScoreTwo;
  73. }
  74. //两只牌是否是边的
  75. bool CAndroidAIBase::IsEdge( BYTE byCard1,BYTE byCard2 )
  76. {
  77. if( 0 == byCard1%9 || 8 == byCard2%9 )
  78. return true;
  79. return false;
  80. }
  81. //搜索相同牌
  82. bool CAndroidAIBase::SearchSameCard( BYTE byCardData,BYTE &byIndex1,BYTE &byIndex2 )
  83. {
  84. //
  85. byIndex1 = FindIndex(byCardData);
  86. if( byIndex1 == 0xff ) return false;
  87. byIndex2 = FindIndex(byCardData,byIndex1+1);
  88. if( byIndex2 == 0xff ) return false;
  89. return true;
  90. }
  91. //搜索连牌
  92. bool CAndroidAIBase::SearchLinkCard( BYTE byCardData,BYTE &byIndex1,BYTE &byIndex2 )
  93. {
  94. //效验
  95. if( byCardData >= 27 ) return false;
  96. //第二,三只
  97. BYTE byCard1 = byCardData+1;
  98. BYTE byCard2 = byCardData+2;
  99. if( byCard1 >= 27 || byCard2 >= 27 || byCardData/9 != byCard1/9 || byCardData/9 != byCard2/9 )
  100. return false;
  101. //寻找
  102. byIndex1 = FindIndex(byCard1);
  103. if( byIndex1 == 0xff ) return false;
  104. byIndex2 = FindIndex(byCard2);
  105. if( byIndex2 == 0xff ) return false;
  106. return true;
  107. }
  108. //搜索两只同牌
  109. bool CAndroidAIBase::SearchSameCardRemain( BYTE byCardData,BYTE &byIndex,BYTE byStart )
  110. {
  111. byIndex = FindIndexRemain(byCardData,byStart);
  112. return 0xff==byIndex?false:true;
  113. }
  114. //搜索有卡连牌
  115. bool CAndroidAIBase::SearchLinkCardRemain( BYTE byCardData,BYTE byLinkType,BYTE &byIndex,BYTE byStart )
  116. {
  117. //验证
  118. if( byCardData >= 27 ) return false;
  119. //判断类型
  120. BYTE byCard1 = 0xff;
  121. if( 0 == byLinkType ) //紧连
  122. byCard1 = byCardData+1;
  123. else if( 1 == byLinkType ) //有卡
  124. byCard1 = byCardData+2;
  125. //过滤
  126. if( byCard1 >= 27 || byCardData/9 != byCard1/9 ) return false;
  127. byIndex = FindIndexRemain(byCard1,byStart);
  128. return 0xff==byIndex?false:true;
  129. }
  130. //搜索牌
  131. BYTE CAndroidAIBase::FindIndex( BYTE byCardData,BYTE byStart )
  132. {
  133. for( BYTE i = byStart; i < m_byCardCount; i++ )
  134. {
  135. if( byCardData == m_byCardData[i] && !m_bSelect[i] )
  136. return i;
  137. }
  138. return 0xff;
  139. }
  140. //在移除最佳三只后搜索牌
  141. BYTE CAndroidAIBase::FindIndexRemain( BYTE byCardData,BYTE byStart )
  142. {
  143. for( BYTE i = byStart; i < m_byRemainThreeCount; i++ )
  144. {
  145. if( byCardData == m_byRemainThree[i] && !m_bSelect[i] )
  146. return i;
  147. }
  148. return 0xff;
  149. }
  150. //移除牌
  151. bool CAndroidAIBase::RemoveCard( BYTE byCardIndex )
  152. {
  153. //效验
  154. ASSERT( m_byCardCount > 0 );
  155. if( m_byCardCount == 0 ) return false;
  156. ASSERT( byCardIndex >= 0 && byCardIndex < MAX_INDEX );
  157. if( byCardIndex < 0 || byCardIndex >= MAX_INDEX ) return false;
  158. //删除
  159. BYTE byCount = m_byCardCount;
  160. m_byCardCount = 0;
  161. bool bFound = false;
  162. for( BYTE i = 0; i < byCount; i++ )
  163. {
  164. if( i == byCardIndex )
  165. {
  166. bFound = true;
  167. continue;
  168. }
  169. m_byCardData[m_byCardCount++] = m_byCardData[i];
  170. }
  171. if( bFound )
  172. m_byCardData[byCount-1] = 0xff;
  173. return bFound;
  174. }
  175. //移除牌值
  176. bool CAndroidAIBase::RemoveCardData( BYTE byCardData )
  177. {
  178. //效验
  179. ASSERT( m_byCardCount > 0 );
  180. if( m_byCardCount == 0 ) return false;
  181. //删除
  182. BYTE byCount = m_byCardCount;
  183. m_byCardCount = 0;
  184. bool bFound = false;
  185. for( BYTE i = 0; i < byCount; i++ )
  186. {
  187. if( !bFound && m_byCardData[i] == byCardData )
  188. {
  189. bFound = true;
  190. continue;
  191. }
  192. m_byCardData[m_byCardCount++] = m_byCardData[i];
  193. }
  194. if( bFound)
  195. m_byCardData[byCount-1] = 0xff;
  196. return bFound;
  197. }
  198. /////////////////////////////////////////////////////////////////////////////////////
  199. //CAndroidAI
  200. CAndroidAI::CAndroidAI(void)
  201. {
  202. ZeroMemory(m_byEnjoinOutCard,sizeof(m_byEnjoinOutCard));
  203. m_byEnjoinOutCount = 0;
  204. }
  205. CAndroidAI::~CAndroidAI(void)
  206. {
  207. }
  208. //思考
  209. void CAndroidAI::Think()
  210. {
  211. //重置
  212. m_nMaxScoreThree = 0;
  213. m_nMaxScoreTwo = 0;
  214. //分析三只
  215. AnalyseThree();
  216. //如果没三只
  217. BYTE i;
  218. if( m_nMaxScoreThree == 0 || m_byRemainThreeCount == 0 )
  219. {
  220. m_byRemainThreeCount = m_byCardCount;
  221. for( i = 0; i < m_byRemainThreeCount; i++ )
  222. m_byRemainThree[i] = m_byCardData[i];
  223. }
  224. //分析两只
  225. AnalyseTwo();
  226. if( m_nMaxScoreTwo == 0 )
  227. {
  228. m_byRemainTwoCount = m_byRemainThreeCount;
  229. for( i = 0; i < m_byRemainTwoCount; i++ )
  230. m_byRemainTwo[i] = m_byRemainThree[i];
  231. }
  232. //如果全部是两只
  233. if( m_byRemainTwoCount == 0 )
  234. {
  235. SearchTwo();
  236. return;
  237. }
  238. //分析一只
  239. AnalyseOne();
  240. }
  241. //从最佳两只牌组合中搜索最差牌
  242. BYTE CAndroidAI::GetBadlyIn2Card()
  243. {
  244. BYTE byBadly = 0xff;
  245. int nMin = 33;
  246. int nScore;
  247. BYTE byCard;
  248. for( BYTE i = 0; i < m_byGoodTwoCount*2; i++ )
  249. {
  250. byCard = m_byGoodTwoCard[i];
  251. if( IsEnjoinOutCard(byCard) ) continue;
  252. if( byCard >= 27 ) //如果是字
  253. {
  254. nScore = 2;
  255. }
  256. else if( byCard%9 == 0 || byCard%9 == 8 ) //如果是一或者九
  257. {
  258. nScore = 6;
  259. }
  260. else
  261. {
  262. nScore = 10;
  263. }
  264. nScore += AddScore(byCard);
  265. //去除一种花色
  266. if( m_cbColorCount == 3 && m_cbColor[(byCard/9)] == m_cbMinColorCount )
  267. nScore -= 10;
  268. if( nScore < nMin )
  269. {
  270. nMin = nScore;
  271. byBadly = byCard;
  272. }
  273. }
  274. return byBadly;
  275. }
  276. //从最佳三只牌组合中搜索最差牌
  277. BYTE CAndroidAI::GetBadlyIn3Card()
  278. {
  279. BYTE byBadly = 0xff;
  280. int nMin = 33;
  281. int nScore;
  282. BYTE byCard;
  283. for( BYTE i = 0; i < m_byGoodThreeCount*3; i++ )
  284. {
  285. byCard = m_byGoodThreeCard[i];
  286. if( IsEnjoinOutCard(byCard) ) continue;
  287. if( byCard >= 27 ) //如果是字
  288. {
  289. nScore = 2;
  290. }
  291. else if( byCard%9 == 0 || byCard%9 == 8 ) //如果是一或者九
  292. {
  293. nScore = 6;
  294. }
  295. else
  296. {
  297. nScore = 10;
  298. }
  299. nScore += AddScore(byCard);
  300. //去除一种花色
  301. if( m_cbColorCount == 3 && m_cbColor[(byCard/9)] == m_cbMinColorCount )
  302. nScore -= 10;
  303. if( nScore < nMin )
  304. {
  305. nMin = nScore;
  306. byBadly = byCard;
  307. }
  308. }
  309. return byBadly;
  310. }
  311. //设置禁止出的牌
  312. void CAndroidAI::SetEnjoinOutCard( const BYTE cbEnjoinOutCard[],BYTE cbEnjoinOutCount )
  313. {
  314. m_byEnjoinOutCount = cbEnjoinOutCount;
  315. if( m_byEnjoinOutCount > 0 )
  316. {
  317. CopyMemory(m_byEnjoinOutCard,cbEnjoinOutCard,sizeof(BYTE)*cbEnjoinOutCount);
  318. }
  319. }
  320. //模拟操作
  321. void CAndroidAI::SetAction( BYTE byActionMask,BYTE byActionCard )
  322. {
  323. //验证
  324. ASSERT( byActionCard >=0 && byActionCard < 34 );
  325. if( byActionCard >= 34 ) return;
  326. //枚举
  327. switch( byActionMask )
  328. {
  329. case WIK_LEFT:
  330. {
  331. m_nActionScore = 300;
  332. VERIFY( RemoveCardData(byActionCard+1) );
  333. VERIFY( RemoveCardData(byActionCard+2) );
  334. //禁止出的牌
  335. m_byEnjoinOutCount = 0;
  336. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard;
  337. if( byActionCard%9 < 7 )
  338. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard+3;
  339. break;
  340. }
  341. case WIK_CENTER:
  342. {
  343. m_nActionScore = 300;
  344. VERIFY( RemoveCardData(byActionCard-1) );
  345. VERIFY( RemoveCardData(byActionCard+1) );
  346. //禁止出的牌
  347. m_byEnjoinOutCount = 0;
  348. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard;
  349. break;
  350. }
  351. case WIK_RIGHT:
  352. {
  353. m_nActionScore = 300;
  354. VERIFY( RemoveCardData(byActionCard-2) );
  355. VERIFY( RemoveCardData(byActionCard-1) );
  356. //禁止出的牌
  357. m_byEnjoinOutCount = 0;
  358. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard;
  359. if( byActionCard%9 > 3 )
  360. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard-3;
  361. break;
  362. }
  363. case WIK_PENG:
  364. {
  365. m_nActionScore = 300;;
  366. VERIFY( RemoveCardData(byActionCard) );
  367. VERIFY( RemoveCardData(byActionCard) );
  368. //禁止出的牌
  369. m_byEnjoinOutCount = 0;
  370. m_byEnjoinOutCard[m_byEnjoinOutCount++] = byActionCard;
  371. break;
  372. }
  373. case WIK_GANG:
  374. {
  375. VERIFY( RemoveCardData(byActionCard) );
  376. BYTE byIndex = FindIndex(byActionCard);
  377. if( byIndex != 0xff )
  378. {
  379. m_nActionScore = 300;
  380. VERIFY( RemoveCardData(byActionCard) );
  381. VERIFY( RemoveCardData(byActionCard) );
  382. byIndex = FindIndex(byActionCard);
  383. if( byIndex != 0xff )
  384. VERIFY( RemoveCardData(byActionCard) );
  385. }
  386. break;
  387. }
  388. default:
  389. ASSERT( FALSE );
  390. }
  391. }
  392. //重置得分
  393. void CAndroidAI::ResetScore()
  394. {
  395. m_nActionScore = m_nMaxScoreThree = m_nMaxScoreTwo = 0;
  396. }
  397. //加权
  398. int CAndroidAI::AddScore( BYTE byCardData )
  399. {
  400. int nScore = 0;
  401. if( byCardData >= 27 )
  402. {
  403. return 0;
  404. }
  405. if( byCardData%9 != 0 && FindIndex(byCardData-1) != 0xff ) //如果剩余的牌中有比其少一的牌
  406. {
  407. if( byCardData%9 != 1 ) //如果当前牌不是二类即加3
  408. {
  409. nScore += 3;
  410. }
  411. else
  412. {
  413. nScore += 1;
  414. }
  415. }
  416. if( byCardData%9 != 8 && FindIndex(byCardData+1) != 0xff ) //如果剩余的牌中有比起多一个的牌
  417. {
  418. if( byCardData%9 != 7 )
  419. {
  420. nScore += 3;
  421. }
  422. else
  423. {
  424. nScore += 1;
  425. }
  426. }
  427. if( byCardData%9 > 1 && FindIndex(byCardData-2) != 0xff ) //如果剩余的牌中有比其少二的牌(如3—5,1_3等)
  428. {
  429. nScore += 2;
  430. }
  431. if( byCardData%9 < 7 && FindIndex(byCardData+2) != 0xff ) //如果剩余的牌中有比其多二的牌
  432. {
  433. nScore += 2;
  434. }
  435. return nScore;
  436. }
  437. //分析三只
  438. void CAndroidAI::AnalyseThree()
  439. {
  440. BYTE byIndex1,byIndex2;
  441. BYTE i = 0;
  442. for( ; i < m_byCardCount; i++ )
  443. {
  444. if( !m_bSelect[i] )
  445. {
  446. m_bSelect[i] = true;
  447. //搜索三只
  448. if( SearchSameCard(m_byCardData[i],byIndex1,byIndex2) )
  449. {
  450. //临时记录
  451. m_byThreeCard[m_byThreeCount*3] = m_byCardData[i];
  452. m_byThreeCard[m_byThreeCount*3+1] = m_byCardData[i];
  453. m_byThreeCard[m_byThreeCount*3+2] = m_byCardData[i];
  454. //递归
  455. m_byThreeCount++;
  456. m_nScoreThree += 300;
  457. m_bSelect[byIndex1] = true;
  458. m_bSelect[byIndex2] = true;
  459. AnalyseThree();
  460. m_bSelect[byIndex1] = false;
  461. m_bSelect[byIndex2] = false;
  462. m_nScoreThree -= 300;
  463. m_byThreeCount--;
  464. }
  465. //搜索连牌
  466. if( SearchLinkCard(m_byCardData[i],byIndex1,byIndex2) )
  467. {
  468. //临时记录
  469. m_byThreeCard[m_byThreeCount*3] = m_byCardData[i];
  470. m_byThreeCard[m_byThreeCount*3+1] = m_byCardData[i]+1;
  471. m_byThreeCard[m_byThreeCount*3+2] = m_byCardData[i]+2;
  472. //递归
  473. m_byThreeCount++;
  474. m_nScoreThree += 300;
  475. m_bSelect[byIndex1] = true;
  476. m_bSelect[byIndex2] = true;
  477. AnalyseThree();
  478. m_bSelect[byIndex1] = false;
  479. m_bSelect[byIndex2] = false;
  480. m_nScoreThree -= 300;
  481. m_byThreeCount--;
  482. }
  483. m_bSelect[i] = false;
  484. }
  485. }
  486. //如果搜索到分数更高的
  487. if( m_nScoreThree > m_nMaxScoreThree )
  488. {
  489. //记录剩下的
  490. m_byRemainThreeCount = 0;
  491. m_nMaxScoreThree = m_nScoreThree;
  492. for( i = 0; i < m_byCardCount; i++ )
  493. {
  494. if( !m_bSelect[i] )
  495. m_byRemainThree[m_byRemainThreeCount++] = m_byCardData[i];
  496. }
  497. //记录最佳三只组合
  498. m_byGoodThreeCount = m_byThreeCount;
  499. CopyMemory(m_byGoodThreeCard,m_byThreeCard,sizeof(m_byThreeCard));
  500. }
  501. }
  502. //分析两只
  503. void CAndroidAI::AnalyseTwo()
  504. {
  505. BYTE byIndex;
  506. BYTE i = 0;
  507. for(; i < m_byRemainThreeCount; i++ )
  508. {
  509. if( !m_bSelect[i] )
  510. {
  511. m_bSelect[i] = true;
  512. //搜索两只相同
  513. if( SearchSameCardRemain(m_byRemainThree[i],byIndex,i+1) )
  514. {
  515. //临时记录
  516. m_byTwoCard[m_byTwoCount*2] = m_byRemainThree[i];
  517. m_byTwoCard[m_byTwoCount*2+1] = m_byRemainThree[byIndex];
  518. //判断将
  519. m_byTwoCount++;
  520. int nGoodSame = 90;
  521. if( !m_bHaveJiang )
  522. {
  523. m_bHaveJiang = true;
  524. nGoodSame = 120;
  525. }
  526. //递归
  527. m_nScoreTwo += nGoodSame;
  528. m_bSelect[byIndex] = true;
  529. AnalyseTwo();
  530. m_bSelect[byIndex] = false;
  531. if( 120 == nGoodSame )
  532. m_bHaveJiang = false;
  533. m_nScoreTwo -= nGoodSame;
  534. m_byTwoCount--;
  535. }
  536. //搜索紧连牌
  537. if( SearchLinkCardRemain(m_byRemainThree[i],0,byIndex,i+1) )
  538. {
  539. //临时记录
  540. m_byTwoCard[m_byTwoCount*2] = m_byRemainThree[i];
  541. m_byTwoCard[m_byTwoCount*2+1] = m_byRemainThree[byIndex];
  542. //判断边
  543. m_byTwoCount++;
  544. int nGoodLink;
  545. if( IsEdge(m_byRemainThree[i],m_byRemainThree[byIndex]) )
  546. nGoodLink = 80;
  547. else nGoodLink = 100;
  548. //递归
  549. m_nScoreTwo += nGoodLink;
  550. m_bSelect[byIndex] = true;
  551. AnalyseTwo();
  552. m_bSelect[byIndex] = false;
  553. m_nScoreTwo -= nGoodLink;
  554. m_byTwoCount--;
  555. }
  556. //搜索有卡的连牌
  557. if( SearchLinkCardRemain(m_byRemainThree[i],1,byIndex,i+1) )
  558. {
  559. //临时记录
  560. m_byTwoCard[m_byTwoCount*2] = m_byRemainThree[i];
  561. m_byTwoCard[m_byTwoCount*2+1] = m_byRemainThree[byIndex];
  562. //判断边
  563. m_byTwoCount++;
  564. int nGoodLink;
  565. if( IsEdge(m_byRemainThree[i],m_byRemainThree[byIndex]) )
  566. nGoodLink = 70;
  567. else nGoodLink = 90;
  568. //递归
  569. m_nScoreTwo += nGoodLink;
  570. m_bSelect[byIndex] = true;
  571. AnalyseTwo();
  572. m_bSelect[byIndex] = false;
  573. m_nScoreTwo -= nGoodLink;
  574. m_byTwoCount--;
  575. }
  576. m_bSelect[i] = false;
  577. }
  578. }
  579. //如果有分数更高的
  580. if( m_nScoreTwo > m_nMaxScoreTwo )
  581. {
  582. //记录剩下的
  583. m_nMaxScoreTwo = m_nScoreTwo;
  584. m_byRemainTwoCount = 0;
  585. for( i = 0; i < m_byRemainThreeCount; i++ )
  586. {
  587. if( !m_bSelect[i] )
  588. m_byRemainTwo[m_byRemainTwoCount++] = m_byRemainThree[i];
  589. }
  590. //记录最佳两只组合
  591. m_byGoodTwoCount = m_byTwoCount;
  592. CopyMemory(m_byGoodTwoCard,m_byTwoCard,sizeof(m_byTwoCard));
  593. }
  594. }
  595. //分析单只
  596. void CAndroidAI::AnalyseOne()
  597. {
  598. BYTE byCard;
  599. int nScore;
  600. int nMin = 33;
  601. for(int i = 0;i < m_byRemainTwoCount;i++ ) //找出最差的一张牌
  602. {
  603. byCard = m_byRemainTwo[i];
  604. if( IsEnjoinOutCard(byCard) ) continue;
  605. if( byCard >= 27 ) //如果是字
  606. {
  607. nScore = 2;
  608. }
  609. else if( byCard%9 == 0 || byCard%9 == 8 ) //如果是一或者九
  610. {
  611. nScore = 6;
  612. }
  613. else
  614. {
  615. nScore = 10;
  616. }
  617. nScore += AddScore(byCard);
  618. //去除一种花色
  619. if( m_cbColorCount == 3 && m_cbColor[(byCard/9)] == m_cbMinColorCount )
  620. nScore -= 10;
  621. if( nScore < nMin )
  622. {
  623. nMin = nScore;
  624. m_byBadlyCard = byCard;
  625. }
  626. }
  627. }
  628. //从两只组合中分析
  629. void CAndroidAI::SearchTwo()
  630. {
  631. //定义变量
  632. BYTE byCardTwo[MAX_COUNT];
  633. BYTE byCardTwoCount = 0;
  634. bool bTeamHave = false;
  635. //设置变量
  636. for( int i = 0;i < m_byRemainThreeCount;i++ )
  637. byCardTwo[byCardTwoCount++] = m_byRemainThree[i];
  638. //仅有一对
  639. if( byCardTwoCount == 2 ) //如果只有两张牌
  640. {
  641. if( byCardTwo[0] == byCardTwo[1] ) //胡牌
  642. {
  643. if( !IsEnjoinOutCard(byCardTwo[0]) )
  644. m_byBadlyCard = byCardTwo[0];
  645. return;
  646. }
  647. m_byRemainTwoCount = 2;
  648. m_byRemainTwo[0] = byCardTwo[0];
  649. m_byRemainTwo[1] = byCardTwo[1];
  650. AnalyseOne();
  651. }
  652. else
  653. {
  654. bool bSameHave = false;
  655. int nMinScore = 33;
  656. int nScore[8];
  657. memset(nScore,33,sizeof(nScore));
  658. for( BYTE j = 0;j < byCardTwoCount/2;j++ ) //循环纪录每张牌的分数
  659. {
  660. if( byCardTwo[j*2] == byCardTwo[j*2 + 1] ) //对子
  661. {
  662. if( bSameHave )
  663. {
  664. nScore[j] = 6;
  665. }
  666. else
  667. {
  668. nScore[j] = 8;
  669. bSameHave = true;
  670. }
  671. }
  672. else if( byCardTwo[j*2] == byCardTwo[j*2+1] - 1 ) //紧连门子
  673. {
  674. if( byCardTwo[j*2]%9 == 0 || byCardTwo[j*2+1]%9 == 8 )
  675. {
  676. nScore[j] = 4;
  677. }
  678. else
  679. {
  680. nScore[j] = 7;
  681. }
  682. }
  683. else //漏一个门子
  684. {
  685. if( byCardTwo[j*2]%9 == 0 || byCardTwo[j*2+1]%9 == 8 )
  686. nScore[j] = 3;
  687. else
  688. nScore[j] = 5;
  689. }
  690. }
  691. for( BYTE k = 0;k < byCardTwoCount/2;k++) //找出分数最小的一张牌就是最差的一张
  692. {
  693. if( nScore[k] < nMinScore )
  694. {
  695. if( byCardTwo[k*2] % 9 == 0 && !IsEnjoinOutCard(byCardTwo[k*2]) )
  696. {
  697. m_byBadlyCard = byCardTwo[k*2];
  698. }
  699. else if( byCardTwo[k*2+1] % 9 == 8 && !IsEnjoinOutCard(byCardTwo[k*2+1]) )
  700. {
  701. m_byBadlyCard = byCardTwo[k*2+1];
  702. }
  703. else
  704. {
  705. int nIndex = rand()%2;
  706. if( IsEnjoinOutCard(byCardTwo[k*2+nIndex]) )
  707. {
  708. nIndex = (nIndex+1)%2;
  709. if( IsEnjoinOutCard(byCardTwo[k*2+nIndex]) ) continue;
  710. else m_byBadlyCard = byCardTwo[k*2+nIndex];
  711. }
  712. else m_byBadlyCard = byCardTwo[k*2+nIndex];
  713. }
  714. nMinScore = nScore[k];
  715. }
  716. }
  717. }
  718. }
  719. //判断牌是否禁止出
  720. bool CAndroidAI::IsEnjoinOutCard( BYTE byCard )
  721. {
  722. for( BYTE i = 0; i < m_byEnjoinOutCount; i++ )
  723. {
  724. if( byCard == m_byEnjoinOutCard[i] )
  725. return true;
  726. }
  727. return false;
  728. }
  729. /////////////////////////////////////////////////////////////////////////////////////