Game.cpp
上传用户:kkzhu_0
上传日期:2007-01-05
资源大小:214k
文件大小:14k
源码类别:

棋牌游戏

开发平台:

Visual C++

  1. /* =====================================================================
  2. 五子棋分析程序:
  3.   1996.4 刘国辉
  4.   说明:
  5.   约定:
  6.  ‘W' 代表白棋
  7.   'B' 代表黑棋
  8.   'N' 代表空地
  9. (1)平分函数:
  10.   int Dump( int x,int Wf )
  11.   X   在一条线上的子数
  12.   WF    = 1 两边都没有被堵住  例如   NNWWWNB..
  13. = 0 一边被堵住               BWWWNNW..
  14. = 2 跨越式的                 WWWNW..
  15. 返回一个分数
  16. (2)线扫描函数:
  17.   int SreachLine( char *FLine,int M,int MF )
  18.   FLine 线指针,指向一个字符串    NNNWWWBWWWN...
  19.   M     字符个数
  20.   WF ='W'或'B'表示对黑或白进行平分
  21. 返回一个分数
  22.  (3)面扫描函数:
  23.  long SreachArea( char *Area[15],int M,char WF )
  24.   ....
  25. ===================================================================== */
  26. #include "game.h"
  27. #include <stdlib.h>
  28. int CFive::WF1_1;
  29. int CFive::WF1_2;
  30. int CFive::WF1_3;
  31. int CFive::WF1_4;
  32. int CFive::WF0_1;
  33. int CFive::WF0_2;
  34. int CFive::WF0_3;
  35. int CFive::WF0_4;
  36. int CFive::WF2_3;
  37. int CFive::WF2_4;
  38. int CFive::WF5;
  39. int CFive::DeepMax;
  40. int CFive::BreadthMax;
  41. int CFive::Delta;
  42. int CFive::ThreadDeepMax;
  43. char CFive::FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
  44. CList<Step,Step> CFive::StepList;
  45. CList<Count,Count> CFive::TempDeepList;
  46. IMPLEMENT_SERIAL( CFive, CWinThread, 1 )
  47. CFive::CFive( char side ):EndEvent( FALSE,TRUE )
  48. {
  49. int i,j;
  50. WF0_1 = 2;
  51. WF0_2 = 10;
  52. WF0_3 = 500;
  53. WF0_4 = 5000;
  54. WF1_1 = 1;
  55. WF1_2 = 20;
  56. WF1_3 = 21;
  57. WF1_4 = 500;
  58. WF2_3 = 400;
  59. WF2_4 = 450;
  60. WF5   = 30000;
  61. CurDeep = DeepMax  = 1;
  62. CurBreadth = BreadthMax = 1;
  63. CurThreadDeep = ThreadDeepMax = 0;
  64. Delta = 0;
  65. CurSide = side;
  66. for( i = 0;i < FIVE_MAX_LINE;i++ )
  67. for( j = 0;j < FIVE_MAX_LINE;j++ )
  68.      FiveArea[i][j] = 'N';
  69. }
  70. CFive::CFive( char side,int deep,int breadth,int threaddeep ):EndEvent( FALSE,TRUE )
  71. {
  72. CurDeep       = deep-1;
  73. CurThreadDeep = threaddeep-1;
  74. CurBreadth    = breadth-Delta;
  75. CurSide = (side == 'B'?'W':'B');
  76. }
  77. CFive::~CFive()
  78. {
  79. DeepList.RemoveAll();
  80. CountList.RemoveAll();
  81. }
  82. void CFive::WzqInit( char side,BOOL flags )
  83. {
  84. int i,j;
  85. CurSide = side;
  86. CurDeep = DeepMax;
  87. CurBreadth = BreadthMax;
  88. CurThreadDeep = ThreadDeepMax;
  89. StepList.RemoveAll();
  90. TempDeepList.RemoveAll();
  91. CountList.RemoveAll();
  92. DeepList.RemoveAll();
  93. for( i = 0;i < FIVE_MAX_LINE;i++ )
  94. for( j = 0;j < FIVE_MAX_LINE;j++ )
  95.      FiveArea[i][j] = 'N';
  96. if( flags == FALSE )
  97. {
  98. int mx,my;
  99. mx = FIVE_MAX_LINE/2 -2;
  100. my = mx;
  101. mx += rand()%4;
  102. my += rand()%4;
  103. FiveArea[mx][my] = CurSide;
  104. }
  105. }
  106. void CFive::SetParam( int breadth,int deep,int thread,int delta )
  107. {
  108. BreadthMax = breadth;
  109. DeepMax = deep;
  110. ThreadDeepMax = thread;
  111. Delta = delta;
  112. CurBreadth = breadth;
  113. CurThreadDeep = deep;
  114. CurDeep = deep;
  115. }
  116. void CFive::GetParam( int& breadth,int& deep,int& thread,int& delta )
  117. {
  118. breadth = BreadthMax;
  119. deep    = DeepMax;
  120. thread  = ThreadDeepMax;
  121. delta   = Delta;
  122. }
  123. int CFive::Dump( int x ,int Wf )
  124. if( Wf == 1 )
  125. {
  126. switch(x)
  127. {
  128. case 1:return WF0_1;
  129. case 2:return WF0_2;
  130. case 3:return WF0_3;
  131. case 4:return WF0_4;
  132. }
  133. }
  134. else if( Wf == 0 )
  135. {
  136. switch(x)
  137. {
  138. case 1:return WF1_1;
  139. case 2:return WF1_2;
  140. case 3:return WF1_3;
  141. case 4:return WF1_4;
  142. }
  143. }
  144. else if( Wf == 2 )
  145. if( x == 4 )
  146. return WF2_4;
  147. if( x == 3 )
  148. return WF2_3;
  149. }
  150.   if( x == 5 )
  151. {
  152. return WF5;
  153. }
  154.   return -1;
  155. }
  156. int CFive::GetDump( int x,int Wf )
  157. {
  158. return Dump( x,Wf );
  159. }
  160. void CFive::SetDump( int x ,int Wf,int c )
  161. if( Wf == 1 )
  162. {
  163. switch(x)
  164. {
  165. case 1:
  166. WF1_1 = c;
  167. return;
  168. case 2:
  169. WF1_2 = c;
  170. return;
  171. case 3:
  172. WF1_3 = c;
  173. return;
  174. case 4:
  175. WF1_4 = c;
  176. return;
  177. }
  178. }
  179. else if( Wf == 0 )
  180. {
  181. switch(x)
  182. {
  183. case 1:
  184. WF0_1 = c;
  185. return;
  186. case 2:
  187. WF0_2 = c;
  188. return;
  189. case 3:
  190. WF0_3 = c;
  191. return;
  192. case 4:
  193. WF0_4 = c;
  194. return;
  195. }
  196. }
  197. else if( Wf == 2 )
  198. if( x == 4 )
  199. {WF2_4 = c;
  200. return;
  201. }
  202. if( x == 3 )
  203. {
  204. WF2_3 = c;
  205. return;
  206. }
  207. }
  208. if( x == 5 )
  209. {
  210. WF5 = c;
  211. return;
  212. }
  213. }
  214. long CFive::SreachLine( char *Fline,int M,char Nf )
  215.  { 
  216. char Wf;
  217. int  i = 0;
  218. int  j = 0;
  219. int  n = 0;
  220. int  k = 0;
  221. long count = 0;
  222. if( Nf == 'B' )
  223. Wf = 'W';
  224. else 
  225. Wf = 'B';
  226. while( M - j >= 5 )
  227. while( Fline[ i+j ] != Wf && i+j < M )
  228. i++;
  229. if( i > 4 )
  230. for( k = 0; k < i; k++ )
  231. {
  232. n = 0;
  233. while( Fline[ j+k ] == Nf && k < i )
  234. n++;
  235. k++; 
  236. }
  237. if( n )
  238. if( n > 4 )
  239. return -1;              //发现5子
  240. if( n == k || k == i )
  241. Wf = 0;
  242. else
  243. Wf = 1;
  244. if( n == 2 && Wf == 1 )
  245. if((k+1<i&&Fline[ j+k+1 ] == Nf)||( k>3&&Fline[ j+k-4 ]==Nf))
  246.        { 
  247.      n++;
  248.          Wf = 2;
  249.        }
  250. if( n == 3 && Wf == 0 )
  251. if((k+1<i&&Fline[ j+k+1 ] == Nf)||( k>4&&Fline[ j+k-5 ]==Nf))
  252.        { 
  253.      n++;
  254.  Wf = 2; 
  255.        }
  256. count = count + Dump( n , Wf );
  257. }
  258. }
  259. }
  260. j = j + i + 1;
  261. i = 0;
  262. }
  263. return count;
  264.  }
  265. long CFive::SreachArea( char Area[][FIVE_MAX_LINE],char Nf )
  266.  { 
  267. int i,j,cbak;
  268. long count = 0;
  269. char Fline[FIVE_MAX_LINE];
  270. for( i = 0; i < FIVE_MAX_LINE; i++ )
  271. for( j = 0; j < FIVE_MAX_LINE; j++ )
  272. Fline[j] = Area[i][j];
  273. cbak = SreachLine( Fline,FIVE_MAX_LINE,Nf );
  274. if( cbak == -1 )
  275. return -1;
  276. else 
  277. count = count + (long)cbak;
  278. }
  279.  for( i = 0; i < FIVE_MAX_LINE; i++ )
  280.  { 
  281.  for( j = 0; j < FIVE_MAX_LINE; j++ )
  282.  Fline[j] = Area[j][i];
  283.  cbak = SreachLine( Fline,FIVE_MAX_LINE,Nf );
  284.  if( cbak == -1 )
  285.  return -1;
  286.  else 
  287.  count = count + (long)cbak;
  288.  }
  289.  for( i = 0; i < FIVE_MAX_LINE - 4; i++ )
  290.   { 
  291.  for( j = 0; j < FIVE_MAX_LINE - i; j++ )
  292.  Fline[j] = Area[i+j][j];
  293.  cbak = SreachLine( Fline, FIVE_MAX_LINE-i, Nf );
  294.  if( cbak == -1 )
  295.  return -1;
  296.  else count = count + (long)cbak;
  297.  }
  298.  for( i = FIVE_MAX_LINE-1; i > 3; i-- )
  299.  { 
  300.  for( j = 0; j < i+1; j++ )
  301.  Fline[j] = Area[i-j][j];
  302.  cbak = SreachLine( Fline, i+1, Nf );
  303.  if( cbak == -1 )
  304.  return -1;
  305.  else 
  306.  count = count + (long)cbak;
  307.  }
  308.  for( i = 0; i < FIVE_MAX_LINE - 5; i++ )
  309.   { 
  310.  for( j = 0; j < FIVE_MAX_LINE - i; j++ )
  311.  Fline[j] = Area[i+j][FIVE_MAX_LINE-j];
  312.  cbak = SreachLine( Fline, FIVE_MAX_LINE-i, Nf );
  313.  if( cbak == -1 )
  314.  return -1;
  315.  else 
  316.  count = count + (long)cbak;
  317.   }
  318.  for( i = FIVE_MAX_LINE-1; i > 4; i-- )
  319.   { 
  320.  for( j = 0; j < i+1; j++ )
  321.  Fline[j] = Area[i-j][FIVE_MAX_LINE-j];
  322.  cbak = SreachLine( Fline, i+1, Nf );
  323.  if( cbak == -1 )
  324.  return -1;
  325.  else 
  326.  count = count + (long)cbak;
  327.   }
  328.  return count;
  329.  }
  330. int CFive::WzqRun( int &mm, int &nn )
  331. {
  332. char     Mf,Nf;
  333. int      i,j;
  334. double   max;
  335. POSITION pos;
  336. Count    tempcount,temp_count;
  337. Nf = CurSide;
  338. for( i = 0;i<FIVE_MAX_LINE;i++ )
  339. for( j = 0;j<FIVE_MAX_LINE;j++ )
  340.         if( FiveArea[i][j] == 'N' )
  341.     goto START_RUN_FIVE_0;
  342. return WZQ_PING;
  343. START_RUN_FIVE_0:
  344. if( FiveArea[mm][nn] != 'N' )
  345. return WZQ_ERROR;
  346. Mf = (Nf == 'B'?'W':'B');
  347. if( SreachArea( FiveArea,Nf ) == -1 )
  348. return WZQ_I;
  349. if( SreachArea( FiveArea,Mf ) == -1 )
  350. return WZQ_YOU;
  351. FiveArea[mm][nn] = Nf;
  352. if( SreachArea( FiveArea,Nf ) == -1 )
  353. return WZQ_I;
  354. if( SreachArea( FiveArea,Mf ) == -1 )
  355. return WZQ_YOU;
  356. for( i = 0;i<FIVE_MAX_LINE;i++ )
  357. for( j = 0;j<FIVE_MAX_LINE;j++ )
  358.         if( FiveArea[i][j] == 'N' )
  359.     goto START_RUN_FIVE_1;
  360. return WZQ_PING;
  361. START_RUN_FIVE_1:
  362. TempDeepList.RemoveAll();
  363. DeepList.RemoveAll();
  364. CountList.RemoveAll();
  365. CreateThread();
  366. CSingleLock event( &EndEvent );
  367. event.Lock();                   //Wait for this thread exit
  368. event.Unlock();
  369. max = -999999999;
  370. pos = TempDeepList.GetHeadPosition();
  371. while( pos )
  372. {
  373. tempcount = TempDeepList.GetNext(pos);
  374. if( max < tempcount.count )
  375. {
  376. temp_count = tempcount;
  377. max = tempcount.count;
  378. mm  = tempcount.step.m;
  379. nn  = tempcount.step.n;
  380. }
  381. }
  382. StepList.AddTail( temp_count.step );
  383. TempDeepList.RemoveAll();
  384. DeepList.RemoveAll();
  385. CountList.RemoveAll();
  386. EndEvent.ResetEvent();
  387. return WZQ_RUN;
  388. }
  389. void CFive::Serialize( CArchive& ar )
  390. {
  391. if (ar.IsStoring())
  392. {
  393. // TODO: add storing code here
  394. }
  395. else
  396. {
  397. // TODO: add loading code here
  398. }
  399. }
  400. void CFive::CalRun( char Nf,LEVE leve )
  401. {
  402. if( CurBreadth <= 0 )
  403. {
  404. char   Mf;
  405. int    i,j,num;
  406. double Ncount,Mcount,TempCount,TempCount1,wf5temp;
  407. Count  *pCount,temp;
  408. char   Area[FIVE_MAX_LINE][FIVE_MAX_LINE];
  409. POSITION pos;
  410. Step     steptemp;
  411. Mf = ( Nf == 'B'?'W':'B');
  412. pCount = new Count[CurBreadth];
  413. for( i = 0;i < CurBreadth;i++ )
  414. {
  415. pCount[i].count = -9999;
  416. pCount[i].step.side = 'E';
  417. }
  418. for( i = 0;i < FIVE_MAX_LINE;i++ )
  419. for( j = 0;j < FIVE_MAX_LINE;j++ )
  420.     Area[i][j] = FiveArea[i][j];
  421.     pos = DeepList.GetHeadPosition( );
  422. while(pos != NULL)
  423. {
  424. steptemp = DeepList.GetNext(pos);
  425. Area[steptemp.m][steptemp.n] = steptemp.side;
  426. }
  427. switch( leve )
  428. {
  429. case COUNT_INC:
  430. Ncount = SreachArea( Area,Nf );
  431. for( i = 0;i < FIVE_MAX_LINE;i++ )
  432. {
  433. for( j = 0;j < FIVE_MAX_LINE;j++ )
  434. {
  435.     if( Area[i][j] == 'N' )
  436. {
  437. Area[i][j] = Nf;
  438. wf5temp = SreachArea( Area,Nf );
  439. if( wf5temp == -1 )
  440. wf5temp = 2*Dump( 5,10 ) + Ncount;
  441. TempCount = wf5temp - Ncount;
  442. if( TempCount > pCount[0].count )
  443. {
  444. pCount[0].count     = TempCount;
  445. pCount[0].step.side = Nf;
  446. pCount[0].step.m    = i;
  447. pCount[0].step.n    = j;
  448. for( num = 1;num < CurBreadth;num++ )
  449. if( pCount[0].count > pCount[num].count )
  450.       {
  451.      temp = pCount[num];
  452.  pCount[num] = pCount[0];
  453.  pCount[0] = temp;
  454.       }
  455. }
  456. Area[i][j] = 'N';
  457. }
  458. }
  459. }
  460. break;
  461. case COUNT_SUB:
  462. Mcount = SreachArea( Area,Mf );
  463. for( i = 0;i < FIVE_MAX_LINE;i++ )
  464. {
  465. for( j = 0;j < FIVE_MAX_LINE;j++ )
  466. {
  467.     if( Area[i][j] == 'N' )
  468. {
  469. Area[i][j] = Nf;
  470. TempCount = Mcount - SreachArea( Area,Mf );
  471. if( TempCount > pCount[0].count )
  472. {
  473. pCount[0].count     = TempCount;
  474. pCount[0].step.side = Nf;
  475. pCount[0].step.m    = i;
  476. pCount[0].step.n    = j;
  477. for( num = 1;num < CurBreadth;num++ )
  478. if( pCount[0].count > pCount[num].count )
  479.       {
  480.      temp = pCount[num];
  481.  pCount[num] = pCount[0];
  482.  pCount[0] = temp;
  483.       }
  484. }
  485. Area[i][j] = 'N';
  486. }
  487. }
  488. }
  489. break;
  490. case COUNT_MID:
  491. Mcount = SreachArea( Area,Mf );
  492. Ncount = SreachArea( Area,Nf );
  493. for( i = 0;i < FIVE_MAX_LINE;i++ )
  494. {
  495. for( j = 0;j < FIVE_MAX_LINE;j++ )
  496. {
  497.     if( Area[i][j] == 'N' )
  498. {
  499. Area[i][j] = Nf;
  500. wf5temp = SreachArea( Area,Nf );
  501. if( wf5temp == -1 )
  502. wf5temp = Ncount + 2*Dump( 5,10 );
  503. TempCount1 = wf5temp - Ncount;
  504. TempCount = Mcount - SreachArea( Area,Mf );
  505. TempCount = TempCount + TempCount1;
  506. if( TempCount > pCount[0].count )
  507. {
  508. pCount[0].count     = TempCount;
  509. pCount[0].step.side = Nf;
  510. pCount[0].step.m    = i;
  511. pCount[0].step.n    = j;
  512. for( num = 1;num < CurBreadth;num++ )
  513. if( pCount[0].count > pCount[num].count )
  514.       {
  515.      temp = pCount[num];
  516.  pCount[num] = pCount[0];
  517.  pCount[0] = temp;
  518.       }
  519. }
  520. Area[i][j] = 'N';
  521. }
  522. }
  523. }
  524. break;
  525. }
  526. for( num = 0;num < CurBreadth;num++ )
  527. if( pCount[num].step.side != 'E' )
  528.     CountList.AddHead( pCount[num] );
  529. delete pCount;
  530.   }//end if( CurBreadth <= 0 )
  531. }
  532. void CFive::AddDeepList( Step step )
  533. {
  534. DeepList.AddTail( step );
  535. }
  536. Step CFive::GetLastDeepList()
  537. {
  538. return DeepList.GetTail();
  539. }
  540. double CFive::GetStepCount()
  541. {
  542. POSITION pos;
  543. double   temp;
  544. Count    steptemp;
  545. temp = 0;
  546. pos = DeepList.GetHeadPosition();
  547. while(pos != NULL)
  548. {
  549. steptemp = CountList.GetNext(pos);
  550.         temp = steptemp.count + temp;
  551. }
  552. return (temp+CurCount);
  553. }
  554. void CFive::ThreadRun()
  555. {
  556. if( CurDeep <=0&&CurBreadth <= 0 )
  557. {
  558. EndEvent.SetEvent();
  559. return;
  560. }
  561. if( CurThreadDeep < 0 )
  562. {
  563. POSITION pos,postemp;
  564. CFive **pFive;
  565. int i,num;
  566. i = 0;
  567. CalRun( CurSide, COUNT_INC );
  568. num = CountList.GetCount();
  569. pFive = (CFive**)new BYTE[sizeof(CFive*)*num];
  570. pos = CountList.GetHeadPosition();
  571. while(pos)
  572. {
  573. pFive[i] = new CFive( CurSide,CurDeep,CurBreadth,CurThreadDeep );
  574. postemp = DeepList.GetHeadPosition();
  575. while( postemp )
  576. {
  577. pFive[i] -> AddDeepList( DeepList.GetNext( postemp ));
  578. }
  579. pFive[i] -> AddDeepList( CountList.GetNext( pos ).step );
  580. pFive[i] -> CreateThread();  //Create thread
  581. i++;
  582. }
  583. for( i=0;i < num;i++ )
  584. {
  585. CSingleLock event( &pFive[i] -> EndEvent );
  586. event.Lock();
  587. event.Unlock();
  588. CurCount += pFive[i] -> GetStepCount();
  589. if( CurDeep == 1)
  590. {
  591. Count count_temp;
  592.     count_temp.step  = pFive[i] -> GetLastDeepList();
  593. count_temp.count = pFive[i] -> GetStepCount();
  594. TempDeepList.AddTail( count_temp );
  595. }
  596. delete pFive[i];
  597. }
  598. delete pFive;
  599. }
  600. else
  601. {
  602. int i,num;
  603. POSITION pos,postemp;
  604. CalRun( CurSide,COUNT_INC );
  605. num = CountList.GetCount();
  606. pos = CountList.GetHeadPosition();
  607. while( pos )
  608. {
  609. {
  610. postemp = DeepList.GetHeadPosition();
  611. CFive five( CurSide,CurDeep,CurBreadth,CurThreadDeep );
  612. while( postemp )
  613. {
  614. five.AddDeepList( DeepList.GetNext( postemp ));
  615. }
  616. five.AddDeepList( CountList.GetNext( pos ).step );
  617. i++;
  618. five.ThreadRun();
  619. CurCount += five.GetStepCount();
  620. if( CurDeep == 1)
  621. {
  622. Count count_temp;
  623.     count_temp.step = five.GetLastDeepList();
  624. count_temp.count = five.GetStepCount();
  625. TempDeepList.AddTail( count_temp );
  626. }
  627. }
  628. }
  629. }
  630. EndEvent.SetEvent();
  631. }
  632. BOOL CFive::InitInstance()
  633. {
  634. ThreadRun();
  635. return FALSE;
  636. }