Game.cpp
上传用户:kkzhu_0
上传日期:2007-01-05
资源大小:214k
文件大小:14k
- /* =====================================================================
- 五子棋分析程序:
- 1996.4 刘国辉
- 说明:
- 约定:
- ‘W' 代表白棋
- 'B' 代表黑棋
- 'N' 代表空地
- (1)平分函数:
- int Dump( int x,int Wf )
- X 在一条线上的子数
- WF = 1 两边都没有被堵住 例如 NNWWWNB..
- = 0 一边被堵住 BWWWNNW..
- = 2 跨越式的 WWWNW..
- 返回一个分数
- (2)线扫描函数:
- int SreachLine( char *FLine,int M,int MF )
- FLine 线指针,指向一个字符串 NNNWWWBWWWN...
- M 字符个数
- WF ='W'或'B'表示对黑或白进行平分
- 返回一个分数
- (3)面扫描函数:
- long SreachArea( char *Area[15],int M,char WF )
- ....
- ===================================================================== */
- #include "game.h"
- #include <stdlib.h>
- int CFive::WF1_1;
- int CFive::WF1_2;
- int CFive::WF1_3;
- int CFive::WF1_4;
- int CFive::WF0_1;
- int CFive::WF0_2;
- int CFive::WF0_3;
- int CFive::WF0_4;
- int CFive::WF2_3;
- int CFive::WF2_4;
- int CFive::WF5;
- int CFive::DeepMax;
- int CFive::BreadthMax;
- int CFive::Delta;
- int CFive::ThreadDeepMax;
- char CFive::FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
- CList<Step,Step> CFive::StepList;
- CList<Count,Count> CFive::TempDeepList;
- IMPLEMENT_SERIAL( CFive, CWinThread, 1 )
- CFive::CFive( char side ):EndEvent( FALSE,TRUE )
- {
- int i,j;
- WF0_1 = 2;
- WF0_2 = 10;
- WF0_3 = 500;
- WF0_4 = 5000;
- WF1_1 = 1;
- WF1_2 = 20;
- WF1_3 = 21;
- WF1_4 = 500;
- WF2_3 = 400;
- WF2_4 = 450;
- WF5 = 30000;
- CurDeep = DeepMax = 1;
- CurBreadth = BreadthMax = 1;
- CurThreadDeep = ThreadDeepMax = 0;
- Delta = 0;
- CurSide = side;
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- FiveArea[i][j] = 'N';
- }
- CFive::CFive( char side,int deep,int breadth,int threaddeep ):EndEvent( FALSE,TRUE )
- {
- CurDeep = deep-1;
- CurThreadDeep = threaddeep-1;
- CurBreadth = breadth-Delta;
- CurSide = (side == 'B'?'W':'B');
- }
- CFive::~CFive()
- {
- DeepList.RemoveAll();
- CountList.RemoveAll();
- }
- void CFive::WzqInit( char side,BOOL flags )
- {
- int i,j;
- CurSide = side;
- CurDeep = DeepMax;
- CurBreadth = BreadthMax;
- CurThreadDeep = ThreadDeepMax;
- StepList.RemoveAll();
- TempDeepList.RemoveAll();
- CountList.RemoveAll();
- DeepList.RemoveAll();
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- FiveArea[i][j] = 'N';
- if( flags == FALSE )
- {
- int mx,my;
- mx = FIVE_MAX_LINE/2 -2;
- my = mx;
- mx += rand()%4;
- my += rand()%4;
- FiveArea[mx][my] = CurSide;
- }
- }
- void CFive::SetParam( int breadth,int deep,int thread,int delta )
- {
- BreadthMax = breadth;
- DeepMax = deep;
- ThreadDeepMax = thread;
- Delta = delta;
- CurBreadth = breadth;
- CurThreadDeep = deep;
- CurDeep = deep;
- }
- void CFive::GetParam( int& breadth,int& deep,int& thread,int& delta )
- {
- breadth = BreadthMax;
- deep = DeepMax;
- thread = ThreadDeepMax;
- delta = Delta;
- }
- int CFive::Dump( int x ,int Wf )
- {
- if( Wf == 1 )
- {
- switch(x)
- {
- case 1:return WF0_1;
- case 2:return WF0_2;
- case 3:return WF0_3;
- case 4:return WF0_4;
- }
- }
- else if( Wf == 0 )
- {
- switch(x)
- {
- case 1:return WF1_1;
- case 2:return WF1_2;
- case 3:return WF1_3;
- case 4:return WF1_4;
- }
- }
- else if( Wf == 2 )
- {
- if( x == 4 )
- return WF2_4;
- if( x == 3 )
- return WF2_3;
- }
- if( x == 5 )
- {
- return WF5;
- }
- return -1;
- }
- int CFive::GetDump( int x,int Wf )
- {
- return Dump( x,Wf );
- }
- void CFive::SetDump( int x ,int Wf,int c )
- {
- if( Wf == 1 )
- {
- switch(x)
- {
- case 1:
- WF1_1 = c;
- return;
- case 2:
- WF1_2 = c;
- return;
- case 3:
- WF1_3 = c;
- return;
- case 4:
- WF1_4 = c;
- return;
- }
- }
- else if( Wf == 0 )
- {
- switch(x)
- {
- case 1:
- WF0_1 = c;
- return;
- case 2:
- WF0_2 = c;
- return;
- case 3:
- WF0_3 = c;
- return;
- case 4:
- WF0_4 = c;
- return;
- }
- }
- else if( Wf == 2 )
- {
- if( x == 4 )
- {WF2_4 = c;
- return;
- }
- if( x == 3 )
- {
- WF2_3 = c;
- return;
- }
- }
- if( x == 5 )
- {
- WF5 = c;
- return;
- }
- }
- long CFive::SreachLine( char *Fline,int M,char Nf )
- {
- char Wf;
- int i = 0;
- int j = 0;
- int n = 0;
- int k = 0;
- long count = 0;
- if( Nf == 'B' )
- Wf = 'W';
- else
- Wf = 'B';
- while( M - j >= 5 )
- {
- while( Fline[ i+j ] != Wf && i+j < M )
- i++;
- if( i > 4 )
- {
- for( k = 0; k < i; k++ )
- {
- n = 0;
- while( Fline[ j+k ] == Nf && k < i )
- {
- n++;
- k++;
- }
- if( n )
- {
- if( n > 4 )
- return -1; //发现5子
- if( n == k || k == i )
- Wf = 0;
- else
- Wf = 1;
- if( n == 2 && Wf == 1 )
- if((k+1<i&&Fline[ j+k+1 ] == Nf)||( k>3&&Fline[ j+k-4 ]==Nf))
- {
- n++;
- Wf = 2;
- }
- if( n == 3 && Wf == 0 )
- if((k+1<i&&Fline[ j+k+1 ] == Nf)||( k>4&&Fline[ j+k-5 ]==Nf))
- {
- n++;
- Wf = 2;
- }
- count = count + Dump( n , Wf );
- }
- }
- }
- j = j + i + 1;
- i = 0;
- }
- return count;
- }
- long CFive::SreachArea( char Area[][FIVE_MAX_LINE],char Nf )
- {
- int i,j,cbak;
- long count = 0;
- char Fline[FIVE_MAX_LINE];
-
- for( i = 0; i < FIVE_MAX_LINE; i++ )
- {
- for( j = 0; j < FIVE_MAX_LINE; j++ )
- Fline[j] = Area[i][j];
- cbak = SreachLine( Fline,FIVE_MAX_LINE,Nf );
- if( cbak == -1 )
- return -1;
- else
- count = count + (long)cbak;
- }
- for( i = 0; i < FIVE_MAX_LINE; i++ )
- {
- for( j = 0; j < FIVE_MAX_LINE; j++ )
- Fline[j] = Area[j][i];
- cbak = SreachLine( Fline,FIVE_MAX_LINE,Nf );
- if( cbak == -1 )
- return -1;
- else
- count = count + (long)cbak;
- }
- for( i = 0; i < FIVE_MAX_LINE - 4; i++ )
- {
- for( j = 0; j < FIVE_MAX_LINE - i; j++ )
- Fline[j] = Area[i+j][j];
- cbak = SreachLine( Fline, FIVE_MAX_LINE-i, Nf );
- if( cbak == -1 )
- return -1;
- else count = count + (long)cbak;
- }
- for( i = FIVE_MAX_LINE-1; i > 3; i-- )
- {
- for( j = 0; j < i+1; j++ )
- Fline[j] = Area[i-j][j];
- cbak = SreachLine( Fline, i+1, Nf );
- if( cbak == -1 )
- return -1;
- else
- count = count + (long)cbak;
- }
- for( i = 0; i < FIVE_MAX_LINE - 5; i++ )
- {
- for( j = 0; j < FIVE_MAX_LINE - i; j++ )
- Fline[j] = Area[i+j][FIVE_MAX_LINE-j];
- cbak = SreachLine( Fline, FIVE_MAX_LINE-i, Nf );
- if( cbak == -1 )
- return -1;
- else
- count = count + (long)cbak;
- }
- for( i = FIVE_MAX_LINE-1; i > 4; i-- )
- {
- for( j = 0; j < i+1; j++ )
- Fline[j] = Area[i-j][FIVE_MAX_LINE-j];
- cbak = SreachLine( Fline, i+1, Nf );
- if( cbak == -1 )
- return -1;
- else
- count = count + (long)cbak;
- }
- return count;
- }
- int CFive::WzqRun( int &mm, int &nn )
- {
- char Mf,Nf;
- int i,j;
- double max;
- POSITION pos;
- Count tempcount,temp_count;
- Nf = CurSide;
- for( i = 0;i<FIVE_MAX_LINE;i++ )
- for( j = 0;j<FIVE_MAX_LINE;j++ )
- if( FiveArea[i][j] == 'N' )
- goto START_RUN_FIVE_0;
- return WZQ_PING;
- START_RUN_FIVE_0:
- if( FiveArea[mm][nn] != 'N' )
- return WZQ_ERROR;
- Mf = (Nf == 'B'?'W':'B');
- if( SreachArea( FiveArea,Nf ) == -1 )
- return WZQ_I;
- if( SreachArea( FiveArea,Mf ) == -1 )
- return WZQ_YOU;
- FiveArea[mm][nn] = Nf;
- if( SreachArea( FiveArea,Nf ) == -1 )
- return WZQ_I;
- if( SreachArea( FiveArea,Mf ) == -1 )
- return WZQ_YOU;
- for( i = 0;i<FIVE_MAX_LINE;i++ )
- for( j = 0;j<FIVE_MAX_LINE;j++ )
- if( FiveArea[i][j] == 'N' )
- goto START_RUN_FIVE_1;
- return WZQ_PING;
- START_RUN_FIVE_1:
- TempDeepList.RemoveAll();
- DeepList.RemoveAll();
- CountList.RemoveAll();
- CreateThread();
- CSingleLock event( &EndEvent );
- event.Lock(); //Wait for this thread exit
- event.Unlock();
- max = -999999999;
- pos = TempDeepList.GetHeadPosition();
- while( pos )
- {
- tempcount = TempDeepList.GetNext(pos);
- if( max < tempcount.count )
- {
- temp_count = tempcount;
- max = tempcount.count;
- mm = tempcount.step.m;
- nn = tempcount.step.n;
- }
- }
- StepList.AddTail( temp_count.step );
- TempDeepList.RemoveAll();
- DeepList.RemoveAll();
- CountList.RemoveAll();
- EndEvent.ResetEvent();
- return WZQ_RUN;
- }
- void CFive::Serialize( CArchive& ar )
- {
- if (ar.IsStoring())
- {
- // TODO: add storing code here
- }
- else
- {
- // TODO: add loading code here
- }
- }
- void CFive::CalRun( char Nf,LEVE leve )
- {
- if( CurBreadth <= 0 )
- {
- char Mf;
- int i,j,num;
- double Ncount,Mcount,TempCount,TempCount1,wf5temp;
- Count *pCount,temp;
- char Area[FIVE_MAX_LINE][FIVE_MAX_LINE];
- POSITION pos;
- Step steptemp;
- Mf = ( Nf == 'B'?'W':'B');
- pCount = new Count[CurBreadth];
- for( i = 0;i < CurBreadth;i++ )
- {
- pCount[i].count = -9999;
- pCount[i].step.side = 'E';
- }
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- Area[i][j] = FiveArea[i][j];
- pos = DeepList.GetHeadPosition( );
- while(pos != NULL)
- {
- steptemp = DeepList.GetNext(pos);
- Area[steptemp.m][steptemp.n] = steptemp.side;
- }
- switch( leve )
- {
- case COUNT_INC:
- Ncount = SreachArea( Area,Nf );
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- {
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- {
- if( Area[i][j] == 'N' )
- {
- Area[i][j] = Nf;
- wf5temp = SreachArea( Area,Nf );
- if( wf5temp == -1 )
- wf5temp = 2*Dump( 5,10 ) + Ncount;
- TempCount = wf5temp - Ncount;
- if( TempCount > pCount[0].count )
- {
- pCount[0].count = TempCount;
- pCount[0].step.side = Nf;
- pCount[0].step.m = i;
- pCount[0].step.n = j;
- for( num = 1;num < CurBreadth;num++ )
- if( pCount[0].count > pCount[num].count )
- {
- temp = pCount[num];
- pCount[num] = pCount[0];
- pCount[0] = temp;
- }
- }
- Area[i][j] = 'N';
- }
- }
- }
- break;
- case COUNT_SUB:
- Mcount = SreachArea( Area,Mf );
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- {
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- {
- if( Area[i][j] == 'N' )
- {
- Area[i][j] = Nf;
- TempCount = Mcount - SreachArea( Area,Mf );
- if( TempCount > pCount[0].count )
- {
- pCount[0].count = TempCount;
- pCount[0].step.side = Nf;
- pCount[0].step.m = i;
- pCount[0].step.n = j;
- for( num = 1;num < CurBreadth;num++ )
- if( pCount[0].count > pCount[num].count )
- {
- temp = pCount[num];
- pCount[num] = pCount[0];
- pCount[0] = temp;
- }
- }
- Area[i][j] = 'N';
- }
- }
- }
- break;
- case COUNT_MID:
- Mcount = SreachArea( Area,Mf );
- Ncount = SreachArea( Area,Nf );
- for( i = 0;i < FIVE_MAX_LINE;i++ )
- {
- for( j = 0;j < FIVE_MAX_LINE;j++ )
- {
- if( Area[i][j] == 'N' )
- {
- Area[i][j] = Nf;
- wf5temp = SreachArea( Area,Nf );
- if( wf5temp == -1 )
- wf5temp = Ncount + 2*Dump( 5,10 );
- TempCount1 = wf5temp - Ncount;
- TempCount = Mcount - SreachArea( Area,Mf );
- TempCount = TempCount + TempCount1;
- if( TempCount > pCount[0].count )
- {
- pCount[0].count = TempCount;
- pCount[0].step.side = Nf;
- pCount[0].step.m = i;
- pCount[0].step.n = j;
- for( num = 1;num < CurBreadth;num++ )
- if( pCount[0].count > pCount[num].count )
- {
- temp = pCount[num];
- pCount[num] = pCount[0];
- pCount[0] = temp;
- }
- }
- Area[i][j] = 'N';
- }
- }
- }
- break;
- }
- for( num = 0;num < CurBreadth;num++ )
- if( pCount[num].step.side != 'E' )
- CountList.AddHead( pCount[num] );
- delete pCount;
- }//end if( CurBreadth <= 0 )
- }
- void CFive::AddDeepList( Step step )
- {
- DeepList.AddTail( step );
- }
- Step CFive::GetLastDeepList()
- {
- return DeepList.GetTail();
- }
- double CFive::GetStepCount()
- {
- POSITION pos;
- double temp;
- Count steptemp;
- temp = 0;
- pos = DeepList.GetHeadPosition();
- while(pos != NULL)
- {
- steptemp = CountList.GetNext(pos);
- temp = steptemp.count + temp;
- }
- return (temp+CurCount);
- }
- void CFive::ThreadRun()
- {
- if( CurDeep <=0&&CurBreadth <= 0 )
- {
- EndEvent.SetEvent();
- return;
- }
- if( CurThreadDeep < 0 )
- {
- POSITION pos,postemp;
- CFive **pFive;
- int i,num;
- i = 0;
- CalRun( CurSide, COUNT_INC );
- num = CountList.GetCount();
- pFive = (CFive**)new BYTE[sizeof(CFive*)*num];
- pos = CountList.GetHeadPosition();
- while(pos)
- {
- pFive[i] = new CFive( CurSide,CurDeep,CurBreadth,CurThreadDeep );
- postemp = DeepList.GetHeadPosition();
- while( postemp )
- {
- pFive[i] -> AddDeepList( DeepList.GetNext( postemp ));
- }
- pFive[i] -> AddDeepList( CountList.GetNext( pos ).step );
- pFive[i] -> CreateThread(); //Create thread
- i++;
- }
- for( i=0;i < num;i++ )
- {
- CSingleLock event( &pFive[i] -> EndEvent );
- event.Lock();
- event.Unlock();
- CurCount += pFive[i] -> GetStepCount();
- if( CurDeep == 1)
- {
- Count count_temp;
- count_temp.step = pFive[i] -> GetLastDeepList();
- count_temp.count = pFive[i] -> GetStepCount();
- TempDeepList.AddTail( count_temp );
- }
- delete pFive[i];
- }
- delete pFive;
- }
- else
- {
- int i,num;
- POSITION pos,postemp;
- CalRun( CurSide,COUNT_INC );
- num = CountList.GetCount();
- pos = CountList.GetHeadPosition();
- while( pos )
- {
- {
- postemp = DeepList.GetHeadPosition();
- CFive five( CurSide,CurDeep,CurBreadth,CurThreadDeep );
- while( postemp )
- {
- five.AddDeepList( DeepList.GetNext( postemp ));
- }
- five.AddDeepList( CountList.GetNext( pos ).step );
- i++;
- five.ThreadRun();
- CurCount += five.GetStepCount();
- if( CurDeep == 1)
- {
- Count count_temp;
- count_temp.step = five.GetLastDeepList();
- count_temp.count = five.GetStepCount();
- TempDeepList.AddTail( count_temp );
- }
- }
- }
- }
- EndEvent.SetEvent();
- }
- BOOL CFive::InitInstance()
- {
- ThreadRun();
- return FALSE;
- }