⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 五子棋源码,非常经典的游戏,也算是初学DELPHI的朋友必须了解的东西,可以加强逻辑思维,提高编程的严密性
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////////////
//	五子棋分析程序:
//			  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 + -