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

📄 game.cpp

📁 五子棋源码,非常经典的游戏,也算是初学DELPHI的朋友必须了解的东西,可以加强逻辑思维,提高编程的严密性
💻 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 + -