www.pudn.com > fivesource.zip > Game.cpp
/* ===================================================================== 五子棋分析程序: 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" #includeint 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 CFive::StepList; CList 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+13&&Fline[ j+k-4 ]==Nf)) { n++; Wf = 2; } if( n == 3 && Wf == 0 ) if((k+14&&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 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; }