📄 game.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////////
// 五子棋分析程序:
// 1996.4-1997.11 刘国辉
/////////////////////////////////////////////////////////////////////////////////////
// 说明:
// ~~~~~~~
// 约定:
// ~~~~~~~
// ‘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> // For rand()
/////////////////////////////////////////////////////////////////////////////////////
// 静态成员初始化
// ~~~~~~~~~~~~~~~
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::Side;
BOOL CFive::PlayStateFlags;
int CFive::PlayIndex;
char CFive::FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
CList<Step,Step> CFive::StepList;
CList<Count,Count> CFive::OneCountList;
CArray<int,int> CFive::ImpList;
CEvent CFive::KillWzqRun(FALSE,TRUE);
CStatusBar* CFive::pInfo;
long CFive::MemoryCount;
int CFive::ThreadCount;
long CFive::JingDuCount;
Count CFive::PiShen;
/////////////////////////////////////////////////////////////////////////////////////
// 顺序化
// ~~~~~~
IMPLEMENT_SERIAL( CFive, CWinThread, 1 )
/////////////////////////////////////////////////////////////////////////////////////
// 构造与析构
// ~~~~~~~~~~~
CFive::CFive():EndEvent( FALSE,TRUE )
{
m_bAutoDelete = FALSE; // 不自动删除CWinThread对象
CurDeep = DeepMax;
CurBreadth = BreadthMax;
CurThreadDeep = ThreadDeepMax;
CurSide = Side;
CurCount = 0;
PlayStateFlags= FALSE;
}
CFive::CFive( char side,int deep,int breadth,int threaddeep ):EndEvent( FALSE,TRUE )
{
m_bAutoDelete = FALSE; // 不自动删除CWinThread对象
CurSide = (side == 'B'?'W':'B');
CurDeep = deep - 1;
if( CurDeep < 0 )
CurDeep = -1;
CurThreadDeep = threaddeep - 1;
if( CurThreadDeep < 0 )
CurThreadDeep = -1;
if( CurSide == Side )
CurBreadth = BreadthMax - (DeepMax-CurDeep)*Delta;
else
CurBreadth = 1;
if( CurBreadth < 0 )
CurBreadth = -1;
if( CurThreadDeep < 0 )
CurThreadDeep = -1;
CurCount = 0;
}
CFive::~CFive()
{
}
////////////////////////////////////////////////////////////////////////////////////
// 初始化
// ~~~~~~
void CFive::WzqInit( char side,BOOL flags )
{
int i,j;
Side = side;
CurSide = side;
CurDeep = DeepMax;
CurBreadth = BreadthMax;
CurThreadDeep = ThreadDeepMax;
PlayStateFlags= FALSE;
PiShen.count = WZQ_YOU;
StepList.RemoveAll();
for( i = 0;i < FIVE_MAX_LINE;i++ )
for( j = 0;j < FIVE_MAX_LINE;j++ )
FiveArea[i][j] = 'N';
if( flags == FALSE )
{
Step temp;
int mx,my;
mx = FIVE_MAX_LINE/2 -2;
my = mx;
mx += rand()%4;
my += rand()%4;
FiveArea[mx][my] = Side;
temp.side = Side;
temp.m = mx;
temp.n = my;
StepList.AddTail(temp);
}
}
void CFive::SetInfo( CStatusBar*p)
{
pInfo = p;
}
void CFive::SetParam( int breadth,int deep,int thread,int delta )
{
BreadthMax = breadth;
DeepMax = deep;
ThreadDeepMax = thread;
Delta = delta;
}
void CFive::GetParam( int& breadth,int& deep,int& thread,int& delta )
{
breadth = BreadthMax;
deep = DeepMax;
thread = ThreadDeepMax;
delta = Delta;
}
char CFive::GetSide()
{
return Side;
}
char CFive::GetSubPosition( int m,int n )
{
if( m >=0&&n>=0&&m<FIVE_MAX_LINE&&n<FIVE_MAX_LINE )
return FiveArea[m][n];
else
return 'E';
}
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 == 0 )
{
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 == 1 )
{
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;
}
}
void CFive::KillWzqThread()
{
Step step;
KillWzqRun.SetEvent();
EndEvent.Lock();
WaitForSingleObject( m_hThread,INFINITE );
KillWzqRun.ResetEvent();
step = StepList.GetTail();
StepList.RemoveTail();
FiveArea[step.m][step.n] = 'N';
}
void CFive::NoKillThread()
{
KillWzqRun.ResetEvent();
}
BOOL CFive::HuiOneStep()
{
Step step0,step1;
if( StepList.IsEmpty() )
return FALSE;
step0 = StepList.RemoveTail();
if( StepList.IsEmpty() )
{
StepList.AddTail( step0 );
return FALSE;
}
step1 = StepList.RemoveTail();
FiveArea[step0.m][step0.n] = 'N';
FiveArea[step1.m][step1.n] = 'N';
return TRUE;
}
BOOL CFive::BackEndStep()
{
PlayStateFlags = TRUE;
if( PlayIndex == 0 )
return FALSE;
PlayIndex = 0;
UpdatePlay();
return TRUE;
}
BOOL CFive::OneStep()
{
PlayStateFlags = TRUE;
if( PlayIndex >= StepList.GetCount() )
return FALSE;
PlayIndex = StepList.GetCount();
UpdatePlay();
return TRUE;
}
BOOL CFive::BackOneStep()
{
PlayStateFlags = TRUE;
if( PlayIndex > 0 )
{
PlayIndex--;
UpdatePlay();
return TRUE;
}
return FALSE;
}
BOOL CFive::FowardOneStep()
{
PlayStateFlags = TRUE;
if( PlayIndex < StepList.GetCount() )
{
PlayIndex++;
UpdatePlay();
return TRUE;
}
return FALSE;
}
void CFive::UpdatePlay()
{
int i,j;
POSITION pos;
Step step;
for( i = 0;i<FIVE_MAX_LINE;i++ )
for( j = 0;j<FIVE_MAX_LINE;j++ )
FiveArea[i][j] = 'N';
pos = StepList.GetHeadPosition();
i = 0;
while( pos )
{
if( PlayIndex == i )
break;
step = StepList.GetNext(pos);
FiveArea[step.m][step.n] = step.side;
i++;
}
}
void CFive::InListBox( CComboBox& box )
{
POSITION pos;
Step step;
int i;
TCHAR Info[50];
TCHAR *format = _TEXT("%d.%s (%d,%d)");
TCHAR *b = _TEXT("黑");
TCHAR *w = _TEXT("白");
pos = StepList.GetHeadPosition();
box.ResetContent();
i = 0;
while( pos )
{
step = StepList.GetNext(pos);
i++;
if( step.side == 'W' )
wsprintf(Info,format,i,w,step.m,step.n );
else
wsprintf(Info,format,i,b,step.m,step.n );
box.AddString( Info );
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// 平分机制
// ~~~~~~~~~
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;
}
////////////////////////////////////////////////////////////////////////////////////////////
// 在Call WzqRun前Call WzqTest以测试当前情况
int CFive::WzqTest( int m,int n )
{
char Nf,Mf;
int i,j;
Step step_temp;
Nf = Side;
MemoryCount = 0;
ThreadCount = 0;
JingDuCount = 0;
if( PlayStateFlags == TRUE )
{
PlayStateFlags= FALSE;
ResumePlayState();
return WZQ_HAVE;
}
if( Nf == 'B' )
Mf = 'W';
else if( Nf == 'W' )
Mf = 'B';
else
return WZQ_ERROR;
for( i = 0;i<FIVE_MAX_LINE;i++ )
for( j = 0;j<FIVE_MAX_LINE;j++ )
if( FiveArea[i][j] == 'N' )
goto NO_PING;
return WZQ_PING;
NO_PING:
if( m < 0||m >= FIVE_MAX_LINE||n < 0||n >= FIVE_MAX_LINE )
return WZQ_HAVE;
if( FiveArea[m][n] != 'N' )
return WZQ_HAVE;
if( SreachArea( FiveArea,Nf ) == -1 )
return WZQ_I;
if( SreachArea( FiveArea,Mf ) == -1 )
return WZQ_YOU;
FiveArea[m][n] = (Side == 'W'?'B':'W');
step_temp.side = (Side == 'W'?'B':'W');
step_temp.m = m;
step_temp.n = n;
StepList.AddTail( step_temp );
PlayIndex = StepList.GetCount();
if( SreachArea( FiveArea,Nf ) == -1 )
return WZQ_I;
if( SreachArea( FiveArea,Mf ) == -1 )
return WZQ_YOU;
return WZQ_RUN;
}
int CFive::WzqEndTest()
{
char Nf,Mf;
int i,j;
Nf = Side;
MemoryCount = 0;
ThreadCount = 0;
JingDuCount = 0;
if( Nf == 'B' )
Mf = 'W';
else if( Nf == 'W' )
Mf = 'B';
else
return WZQ_ERROR;
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 NO_PING;
return WZQ_PING;
NO_PING:
return WZQ_RUN;
}
BOOL CFive::BiTest( int& mm,int& nn )
{
int i,j;
char Mf;
Mf = (Side =='B'?'W':'B');
for( i=0;i<FIVE_MAX_LINE;i++ )
for( j=0;j<FIVE_MAX_LINE;j++ )
{
if( FiveArea[i][j] == 'N' )
{
FiveArea[i][j] = Side;
if( SreachArea( FiveArea,Side ) == -1 )
{
Step step;
mm = i;
nn = j;
step.m = mm;
step.n = nn;
step.side = Side;
StepList.AddTail( step );
return TRUE;
}
FiveArea[i][j] = 'N';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -