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

📄 chess.cpp

📁 五子棋游戏
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////////
//	Chess.cpp
//	Date: 2004-8-5 21:16
//	A moving ball.
//
//	A five chess game, a 40 * 40 grid playboard has 192 winning status.
//	Compluter can detect the possible winning status and decide the next
//	step.
//
///////////////////////////////////////////////////////////////////////////////

#include <assert.h>
#include "Chess.h"

#define	ID_TIMER	1

///////////////////////////////////////////////////////////////////////////////

BOOL	bStart = TRUE,
	bOver = FALSE;

BOOL	bPlayerWin = FALSE,		// Do the player is a winner ?
	bComputerWin = FALSE,		// Do the computer is a winner ?
	bTie = FALSE;			// No winner.

BOOL	bPlayerDo = FALSE,		// It's time to player.
	bComputerDo = FALSE;		// It's time to computer.

enum	Ball { NoBall, PlayerBall, ComputerBall };
int	nArrBoard[ 10 ][ 10 ] = { NoBall };	// The play board status.

// Record the number of player's ball and computer's ball.
// If over than 50, no winner or the game is over. 

int	nCountPlayer = 0,
	nCountComputer = 0;

// Record the number of the player's ball and computer's ball
// In the winning combination, if the number is 5,
// The player or the computer is a winner.

const int nLostFlag = 7;

const int nPlayer = 0;
const int nComputer = 1;

int	nArrWinner[ 2 ][ 192 ] = { 0 }; 

///////////////////////////////////////////////////////////////////////////////

// Player and computer both have 192 winning status.
BOOL	bArrPlayerWin[ 10 ][ 10 ][ 192 ] = { FALSE };
BOOL	bArrComWin[ 10 ][ 10 ][ 192 ] = { FALSE };

void InitWinStatus();

///////////////////////////////////////////////////////////////////////////////

// Caculating the score of the user and the computer...
int	nArrPlayerGrades[ 10 ][ 10 ] = { 0 };
int	nArrComGrades[ 10 ][ 10 ] = { 0 };

// Record the highest score for player and computer
int	nPlayerGrade	= 0,
	nComGrade	= 0;

// Record the current position for the computer...
int	gnRow = 0,
	gnColumn = 0;

void TurnToComputer();

///////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, char* cmdParam, int cmdShow )
{
	srand( ::GetTickCount() );
	char className[] = "Chess";
	WinClass Window( WindowsProcedure, className, hInst );
	Window.Register();

	WinMaker win( "Chess", className, hInst );
	win.Show( cmdShow );

	MSG msg;
	int status;
	
	while( ( status = ::GetMessage( & msg, NULL, 0, 0 ) ) != 0 )
	{
		if ( status == -1 )
			return -1;
		::TranslateMessage( & msg );
		::DispatchMessage( & msg );
	}

	return msg.wParam;
}

///////////////////////////////////////////////////////////////////////////////

WinClass::WinClass( WNDPROC wndProc, const char* className, HINSTANCE hInstance )
{
	_class.style = 0;
	_class.lpfnWndProc = wndProc;		// Windows procedure: mandatory
	_class.cbClsExtra = 0;
	_class.cbWndExtra = 0;
	_class.hInstance = hInstance;
	_class.hIcon = 0;			// Owner of class: mandatory
	_class.hCursor = ::LoadCursor( 0, IDC_ARROW );
	_class.hbrBackground = (HBRUSH) ( COLOR_WINDOW + 1 );	// Optional
	_class.lpszMenuName = 0;
	_class.lpszClassName = className;	// Mandatory	
}

WinMaker::WinMaker( const char* szCaption, const char* className, HINSTANCE hInstance )
{
	DWORD	dwStyle = WS_OVERLAPPEDWINDOW;
	dwStyle &= ~WS_SIZEBOX;
	dwStyle &= ~WS_MAXIMIZEBOX;
	dwStyle &= ~WS_MINIMIZEBOX;

	_hWnd = ::CreateWindow(
			className,		// Name of a registered window class
			szCaption,		// Window caption
			dwStyle,		// Window style
			CW_USEDEFAULT,		// x position
			CW_USEDEFAULT,		// y position
			405,			// width
			460,			// height
			0,			// Handle to parent window
			0,			// Handle to menu
			hInstance,		// Application instance
			0 );			// Window creation data
}

///////////////////////////////////////////////////////////////////////////////

LRESULT CALLBACK WindowsProcedure( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
{
	static	int	cxClient, cyClient;

	static	HBITMAP	hbmpBground = NULL,
			hbmpGreen = NULL,
			hbmpPurple = NULL;

	HDC		hdc = NULL,
			hdcMem = NULL;
	HINSTANCE 	hInst = NULL;

	PAINTSTRUCT	ps;

	switch( uMessage )
	{
		case WM_CREATE:
			hInst = ( (LPCREATESTRUCT) lParam )->hInstance;
			assert( hInst );

			hbmpBground = ::LoadBitmap( hInst, TEXT( "bground" ) );
			assert( hbmpBground );
			hbmpGreen = ::LoadBitmap( hInst, TEXT( "green" ) );
			assert( hbmpGreen );
			hbmpPurple = ::LoadBitmap( hInst, TEXT( "purple" ) );
			assert( hbmpPurple );

			::SetTimer( hWnd, ID_TIMER, 80, NULL );
			return 0;

		case WM_SIZE:
			cxClient = LOWORD( lParam );
			cyClient = HIWORD( lParam );

			return 0;

		case WM_PAINT:
			hdc = ::BeginPaint( hWnd, & ps );
			assert( hdc );
			hdcMem = ::CreateCompatibleDC( hdc );
			assert( hdcMem );

			::SelectObject( hdcMem, hbmpBground );
			::BitBlt(
				hdc,
				0, 0,
				400, 400,
				hdcMem,
				0, 0,
				SRCCOPY );

			::DeleteDC( hdcMem );
			::EndPaint( hWnd, & ps );
			return 0;

		case WM_TIMER:
			hdc = ::GetDC( hWnd );
			assert( hdc );
			hdcMem = ::CreateCompatibleDC( hdc );
			assert( hdcMem );
			
			if ( bStart )
				InitWinStatus();
			
			if ( ! bOver )
			{
				if ( bComputerDo )
					TurnToComputer();

				for ( int i = 0; i <= 1; i++ )
					for ( int j = 0; j < 192; j++ )
					{
						if ( nArrWinner[ i ][ j ] == 5 )
							if ( i == nPlayer )
							{
								bPlayerWin	= TRUE;
								bOver		= TRUE;
								break;
							}
							else
							{
								bComputerWin	= TRUE;
								bOver		= TRUE;
								break;
							}
						if ( bOver )
							break;
					}
					
					if ( bPlayerWin )
						::MessageBox( NULL, "You win", "RESULT", MB_OK | MB_ICONINFORMATION );
					if ( bComputerWin )
						::MessageBox( NULL, "You lost", "RESULT", MB_OK | MB_ICONINFORMATION );
					if ( bTie )
						::MessageBox( NULL, "No winner", "RESULT", MB_OK | MB_ICONINFORMATION );
			}
			
			{
			for ( int i = 0; i < 10; i++ )
				for ( int j = 0; j < 10; j++ )
				{
					if ( nArrBoard[ i ][ j ] == PlayerBall )
					{
						::SelectObject( hdcMem, hbmpGreen );
						::BitBlt(
							hdc,
							j * 40 + 2,
							i * 40 + 2,
							36,
							36,
							hdcMem,
							0,
							0,
							SRCCOPY );
					}

					if ( nArrBoard[ i ][ j ] == ComputerBall )
					{
						::SelectObject( hdcMem, hbmpPurple );
						::BitBlt(
							hdc,
							j * 40 + 2,
							i * 40 + 2,
							36,
							36,
							hdcMem,
							0,
							0,
							SRCCOPY );
					}
				}
			}
			
			::ReleaseDC( hWnd, hdc );
			::DeleteDC( hdcMem );
			return 0;

		case WM_LBUTTONDOWN:
			if ( ! bOver )
			{
				if ( bPlayerDo )
				{
					// The mouse is in the valid client window
					if ( LOWORD( lParam ) < 400 && HIWORD( lParam ) < 400 )
					{
						int nRow = HIWORD( lParam ) / 40;
						int nColumn = LOWORD( lParam ) / 40;

						if ( nArrBoard[ nRow ][ nColumn ] == NoBall )
						{
							nArrBoard[ nRow ][ nColumn ] = PlayerBall;
							nCountPlayer++;

							if ( ( nCountPlayer == 50 ) && ( nCountComputer == 50 ) )
							{
								bTie = TRUE;
								bOver = TRUE;
							}

							for ( int i = 0; i < 192; i++ )
							{
								if ( bArrPlayerWin[ nRow ][ nColumn ][ i ] &&
										nArrWinner[ nPlayer ][ i ] != nLostFlag )
									nArrWinner[ nPlayer ][ i ]++;

								if ( bArrComWin[ nRow ][ nColumn ][ i ] )
								{
									// In these possible winning combination
									// computer can't win anymore in this position.
									bArrComWin[ nRow ][ nColumn ][ i ] = FALSE;
									nArrWinner[ nComputer ][ i ] = nLostFlag;
								}
							}
							bPlayerDo = FALSE;
							bComputerDo = TRUE;
						} // if ( nArrBoard[ nRow ][ nColumn ] == NoBall )
					}
				} // if ( bPlayerDo )
			} // if ( ! Over )
			return 0;
			
		case WM_DESTROY:
			::DeleteObject( hbmpBground);
			::DeleteObject( hbmpGreen );
			::DeleteObject( hbmpPurple );

			::KillTimer( hWnd, ID_TIMER );
			::PostQuitMessage( 0 );
			return 0;
	}

	return ::DefWindowProc( hWnd, uMessage, wParam, lParam );
}

///////////////////////////////////////////////////////////////////////////////
//	InitWinStatus
//	Result: none.
//	Parameters: None.
//	Effect:
//	To set all winnning status in the chess game.
//
///////////////////////////////////////////////////////////////////////////////

void InitWinStatus()
{
	int nCount = 0;

	// Set the vertical combinations winning status.
	for ( int i = 0; i < 10; i++ )
		for ( int j = 0; j < 6; j++ )
		{
			for ( int k = 0; k < 5; k++ )
			{
				bArrPlayerWin[ j + k ][ i ][ nCount ] = TRUE;
				bArrComWin[ j + k ][ i ][ nCount ] = TRUE;
			}

			nCount++;
		}

	// Vertical has 60 winning status.
	assert( nCount == 60 );

	// Set the horizontal combinations winning status.
	for ( i = 0; i < 10; i++ )
		for ( int j = 0; j < 6; j++ )
		{
			for ( int k = 0; k < 5; k++ )
			{
				bArrPlayerWin[ i ][ j + k ][ nCount ] = TRUE;
				bArrComWin[ i ][ j + k ][ nCount ] = TRUE;
			}

			nCount++;
		}

	// Horizontal has 60 winning status
	assert( nCount == 120 );

	// Set the positive diagonal winning status.
	for ( i = 0; i < 6; i++ )
		for ( int j = 0; j < 6; j++ )
		{
			for ( int k = 0; k < 5; k++ )
			{
				bArrPlayerWin[ j + k ][ i + k ][ nCount ] = TRUE;
				bArrComWin[ j + k ][ i + k ][ nCount ] = TRUE;
			}

			nCount++;
		}

	// Positive diagonal has 36 winning status.
	assert( nCount == 156 );

	// Set the negative diagonal winning status.
	for ( i = 0; i < 6; i++ )
		for ( int j = 9; j > 3; j-- )
		{
			for ( int k = 0; k < 5; k++ )
			{
				bArrPlayerWin[ j - k ][ i + k ][ nCount ] = TRUE;
				bArrComWin[ j - k ][ i + k ][ nCount ] = TRUE;
			}

			nCount++;
		}

	// Negative diagonal has 36 winning status.
	assert( nCount == 192 );

	// Who is the first ?
	if ( rand() % 2 == 0 )
		bPlayerDo = TRUE;
	else
		bComputerDo = TRUE;
}


///////////////////////////////////////////////////////////////////////////////
//	TurnToComputer
//	Parameters:
//		None.
//	Result: void
//	Effect:
//		Turn to the computer. caculating the score!
//
///////////////////////////////////////////////////////////////////////////////

void TurnToComputer()
{
	// Caculating the score for the player...
	for ( int i = 0; i < 10; i++ )
		for ( int j = 0; j < 10; j++ )
		{
			nArrPlayerGrades[ i ][ j ] = 0;

			if ( nArrBoard[ i ][ j ] == NoBall )
			{
				for ( int k = 0; k < 192; k++ )
				{
					if ( bArrPlayerWin[ i ][ j ][ k ] )
					{
						switch( nArrWinner[ nPlayer ][ k ] )
						{
							case 1:
								nArrPlayerGrades[ i ][ j ] += 5;
								break;
							case 2:
								nArrPlayerGrades[ i ][ j ] += 50;
								break;
							case 3:
								nArrPlayerGrades[ i ][ j ] += 100;
								break;
							case 4:
								nArrPlayerGrades[ i ][ j ] += 400;
								break;
						}
					}
				}
			} // end if ( nArrBoard[ i ][ j ] == NoBall )
		}

	// Caculating the score for the computer......
	for ( i = 0; i < 10; i++ )
		for ( int j = 0; j < 10; j++ )
		{
			nArrComGrades[ i ][ j ] = 0;

			if ( nArrBoard[ i ][ j ] == NoBall )
			{
				for ( int k = 0; k < 192; k++ )
				{
					if ( bArrComWin[ i ][ j ][ k ] )
					{
						switch ( nArrWinner[ nComputer ][ k ] )
						{
							case 1:
								nArrComGrades[ i ][ j ] += 5;
								break;
							case 2:
								nArrComGrades[ i ][ j ] += 50;
								break;
							case 3:
								nArrComGrades[ i ][ j ] += 100;
								break;
							case 4:
								nArrComGrades[ i ][ j ] += 400;
								break;
						}
					}
				}
			} // end if ( nArrBoard[ i ][ j ] == NoBall )
		}

	// Is the game start ?
	if ( bStart )
	{
		gnRow = rand() % 10;
		gnColumn = rand() % 10;	

		bStart = FALSE;
	}
	else
	{
		int	nComAtRow	= 0,
			nComAtCol	= 0;

		int	nPlayerAtRow	= 0,
			nPlayerAtCol	= 0;

		for ( i = 0; i < 10; i++ )
			for ( int j = 0; j < 10; j++ )
				if ( nArrBoard[ i ][ j ] == NoBall )
				{
					// What's the position the ball should put in...
					if ( nArrComGrades[ i ][ j ] >= nComGrade )
					{
						nComGrade = nArrComGrades[ i ][ j ];

						nComAtRow = i;
						nComAtCol = j;
					} // end if ( nArrComGrads[ i ][ j ] >= nComGrade )

					if ( nArrPlayerGrades[ i ][ j ] >= nPlayerGrade )
					{
						nPlayerGrade = nArrPlayerGrades[ i ][ j ];

						nPlayerAtRow = i;
						nPlayerAtCol = j;
					}
				} // end if ( nArrBoard[ i ][ j ] == NoBall )

		if ( nComGrade >= nPlayerGrade )			// Computer attack
		{
			gnRow = nComAtRow;
			gnColumn = nComAtCol;
		}
		else							// Computer defend
		{
			gnRow = nPlayerAtRow;
			gnColumn = nPlayerAtCol;
		}
	}
	
	nComGrade = 0;
	nPlayerGrade = 0;

	nArrBoard[ gnRow ][ gnColumn ] = ComputerBall;
	nCountComputer++;
	
	if ( ( nCountComputer == 50 ) && ( nCountPlayer == 50 ) )
	{
		bTie = TRUE;
		bOver = TRUE;
	}
	
	for ( i = 0; i < 192; i++ )
	{
		if ( bArrComWin[ gnRow ][ gnColumn ][ i ] &&
				nArrWinner[ nComputer ][ i ] != nLostFlag )
			nArrWinner[ nComputer ][ i ]++;

		if ( bArrPlayerWin[ gnRow ][ gnColumn ][ i ] )
		{
			bArrPlayerWin[ gnRow ][ gnColumn ][ i ] = FALSE;
			nArrWinner[ nPlayer ][ i ] = nLostFlag;
		}
	}

	bPlayerDo = TRUE;
	bComputerDo = FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -