📄 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"
#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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -