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

📄 cfivechess.cpp

📁 MFC(Microsoft Foundation Class)指的是Microsoft基础类
💻 CPP
字号:
// FiveChess1.cpp : implementation file
//

#include "stdafx.h"
#include "Chess.h"
#include "CFiveChess.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFiveChess

CFiveChess::CFiveChess() : 	m_ChessBoard_TopLeft_x(21), m_ChessBoard_TopLeft_y(22),
						m_ChessBoardPane_Distance(35), 	m_ChessBoardPane_Number(15),
						m_ChessPicture_Size(33)
{

	m_CountChess = 0;
	IS_BLACK_CHESS = false;
	m_Previous_Point.x = 0;
	m_Previous_Point.y = 0;
	m_Count_Adacency_Chess = 1;
}


//此方法用于创建该类的一个窗口实例,并对窗口实例进行初始化
void CFiveChess::create_window(DWORD style, CWnd *pCwnd, CRect rect, UINT id)
{
	//创建窗口
	CreateEx(WS_EX_CLIENTEDGE,NULL, "CFiveChess",
		style,rect,pCwnd, id);
		set_Window_Size();
	pCurrent_DC = GetDC();								//得到当前窗口的DC指针
	GetClientRect(&m_current_Wnd_Rect);					//得到本窗口的客户区

	//将图片绑定到相应的CBitmap对象上
	m_ChessBoard_Bitmap.LoadBitmap(IDB_BITMAP_ChessBoard);
	m_BlackChess_Bitmap.LoadBitmap(IDB_BITMAP_BlackChess);
	m_WhiteChess_Bitmap.LoadBitmap(IDB_BITMAP_WhiteChess);
	m_Complex_Bitmap.LoadBitmap(IDB_BITMAP_Complex);
	m_Mask_Bitmap.LoadBitmap(IDB_BITMAP_Mask);

	//将CBitmap对象的属性赋予BITMAP结构体实例
	m_ChessBoard_Bitmap.GetBitmap(&m_ChessBoard_BITMAP);					
	m_BlackChess_Bitmap.GetBitmap(&m_BlackChess_BITMAP);
	
	//为黑棋子DC申请一定的资源并绑定相应的棋子CBitmap对象
	m_BlackChess_DC.CreateCompatibleDC(pCurrent_DC);
	m_BlackChess_DC.SelectObject(&m_BlackChess_Bitmap);

	//为白棋子DC申请一定的资源并绑定相应的棋子CBitmap对象
	m_WhiteChess_DC.CreateCompatibleDC(pCurrent_DC);
	m_WhiteChess_DC.SelectObject(&m_WhiteChess_Bitmap);

	//为棋盘DC申请一定的资源并绑定相应的棋子CBitmap对象
	m_ChessBoard_DC.CreateCompatibleDC(pCurrent_DC);
	m_ChessBoard_DC.SelectObject(&m_ChessBoard_Bitmap);

	//为复合DC申请一定的资源并初始绑定相应的CBitmap对象
	m_Complex_DC.CreateCompatibleDC(pCurrent_DC);
	m_Complex_DC.SelectObject(&m_Complex_Bitmap);

	//为掩码DC申请一定的资源并初始绑定相应的CBitmap对象
	m_Mask_DC.CreateCompatibleDC(pCurrent_DC);
	m_Mask_DC.SelectObject(&m_Mask_Bitmap);

	//m_Null_DC.CreateCompatibleDC(pCurrent_DC);

	


	//设置圆形的棋子
	set_Round_Chess();


	//初始化记录棋盘上棋子的状态的数组
	for(int i = 0; i < m_ChessBoardPane_Number; i++)
	{
		for(int j = 0; j < m_ChessBoardPane_Number; j++)
		{
			m_ChessBoard_state[i][j] = 0;
		}
	}

}

//重新开始游戏(即将棋盘上的棋子全部清空)
void CFiveChess::restart_Game()
{
	m_Complex_DC.DeleteDC();
	m_Complex_DC.CreateCompatibleDC(pCurrent_DC);
	m_Complex_Bitmap.DeleteObject();
	m_Complex_Bitmap.LoadBitmap(IDB_BITMAP_Complex);
	m_Complex_DC.SelectObject(&m_Complex_Bitmap);	

	for(int i = 0; i < m_ChessBoardPane_Number; i++)
	{
		for(int j = 0; j < m_ChessBoardPane_Number; j++)
		{
			m_ChessBoard_state[i][j] = 0;
		}
	}
	m_CountChess = 1;
	Invalidate();
}

//设置父窗口与子窗口的大小及位置
void CFiveChess::set_Window_Size()
{
	int Screen_Width = GetSystemMetrics(SM_CXSCREEN);   //获得屏幕的宽度
	int Screen_Height = GetSystemMetrics(SM_CYSCREEN);  //获得屏幕的高度
	int pointX = (Screen_Width-541)/2;					//计算窗口的初始左上角点的横坐标
	int pointY = (Screen_Height-580)/2;					//计算窗口的初始左上角点的纵坐标
	(this->GetParent())->MoveWindow(pointX,pointY,541,585,true);//设置父窗口的大小及位置
	this->MoveWindow(0,0,535,540,true);                 //设置当前窗口的初始位置及大小
}

//判断是否有某一方获胜,或者两者平局(必须要判断四个方向的输赢)
void CFiveChess::Anyone_Success(int row, int column)
{

	int t_Chess_State = 0;
	int temp_Row = row;
	int temp_Column = column;

	if(IS_BLACK_CHESS)
		t_Chess_State = 1;
	else
		t_Chess_State = 2;


	//先判断横向
	for( ; --temp_Column > 0; ) {
		if(m_ChessBoard_state[row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else 
			break;
	}
	temp_Column = column;

	for( ; ++temp_Column < m_ChessBoardPane_Number; ) {
		if(m_ChessBoard_state[row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else
			break;		
	}
	temp_Column = column;
	is_Success();

	//判断纵向
	for( ; --temp_Row > 0; ) {
		if(m_ChessBoard_state[temp_Row][column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else 
			break;
	}
	temp_Row = row;

	for( ; ++temp_Row < m_ChessBoardPane_Number; ) {
		if(m_ChessBoard_state[temp_Row][column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else 
			break;
	}
	temp_Row = row;
	is_Success();

	//判断对角线方向
	for( ; --temp_Column > 0 && --temp_Row > 0; ) {
		if(m_ChessBoard_state[temp_Row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else
			break;
	}
	temp_Column = column;
	temp_Row = row;

	for( ; ++temp_Column < m_ChessBoardPane_Number && ++temp_Row < m_ChessBoardPane_Number; ) {
		if(m_ChessBoard_state[temp_Row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else
			break;		
	}
	temp_Column = column;
	temp_Row = row;
	is_Success();

	//判断反向对角线方向
	for( ; --temp_Column > 0 && ++temp_Row < m_ChessBoardPane_Number; ) {
		if(m_ChessBoard_state[temp_Row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else
			break;
	}
	temp_Column = column;
	temp_Row = row;

	for( ; ++temp_Column < m_ChessBoardPane_Number && --temp_Row > 0; ) {
		if(m_ChessBoard_state[temp_Row][temp_Column] == t_Chess_State)
			m_Count_Adacency_Chess++;
		else
			break;		
	}
	temp_Column = column;
	temp_Row = row;
	is_Success();
}

//判断棋子是否获胜(通过使用私有变量m_Count_Adacency_Chess来记录相邻的相同棋子的数目)
void CFiveChess::is_Success()
{
	if(m_Count_Adacency_Chess >= 5) {
		if(IS_BLACK_CHESS)
			MessageBox(TEXT("黑棋赢!"), TEXT("CFiveChess"), MB_OK);
		else 
			MessageBox(TEXT("白棋赢!"), TEXT("CFiveChess"), MB_OK);

		this->restart_Game();
	}
	m_Count_Adacency_Chess = 1;
}

//通过输入一个坐标,然后计算出修正后的坐标值
CPoint CFiveChess::get_Modified_Position(int x, int y)
{
	int pointX = x;	//坐标的横坐标
	int pointY = y;   //坐标的纵坐标

	if(pointX < m_ChessBoard_TopLeft_x) {
	//当坐标点的横坐标小于最左坐标值时,将坐标值修改为最左横坐标。
	
		x = m_ChessBoard_TopLeft_x; 
	} 

	if(pointX >= (m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * (m_ChessBoardPane_Number - 1))) {
	//当坐标点的横坐标大于最右坐标值时,将坐标值修改为最右横坐标。
	
		x = m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * (m_ChessBoardPane_Number - 1);
	}

	if(pointY < m_ChessBoard_TopLeft_y){
	//当坐标点的纵坐标小于最上坐标值时,将坐标值修改为最上纵坐标。
	
		y = m_ChessBoard_TopLeft_y;
	}

	if(pointY >= (m_ChessBoard_TopLeft_y + m_ChessBoardPane_Distance * (m_ChessBoardPane_Number - 1))) {
	//当坐标点的纵坐标大于最下坐标值时,将坐标值修改为最下纵坐标。
	
		y = m_ChessBoard_TopLeft_y + m_ChessBoardPane_Distance * (m_ChessBoardPane_Number - 1);
	}


	for(int i = 0; i < (m_ChessBoardPane_Number - 1); i++) {

		if(pointX >= m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * i){
		//当坐标点的横坐标值大于或者等于第(i+1)列的棋格的横坐标值时

			if((pointX - m_ChessBoard_TopLeft_x - m_ChessBoardPane_Distance * i) > 
					(m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * (i + 1) - pointX)){
			//如果坐标的横坐标的值更靠近第(i+2)列棋格时,将此横坐标值修改为第(i+2)列棋格的左边界的横坐标,
			//反之修改为第(i+1)列的左边界的横坐标
			
				x = m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * (i + 1);
			} else {
			
				x = m_ChessBoard_TopLeft_x + m_ChessBoardPane_Distance * i;
			}
		}
	}

	for(i = 0; i < (m_ChessBoardPane_Number - 1); i++){

		if(pointY >= m_ChessBoard_TopLeft_y + m_ChessBoardPane_Distance * i){
		//当坐标点的纵坐标值大于或者等于第(i+1)行的棋格的纵坐标值时
			
			if((pointY - m_ChessBoard_TopLeft_y - m_ChessBoardPane_Distance * i) > 
					(m_ChessBoard_TopLeft_y + m_ChessBoardPane_Distance * (i + 1) - pointY)){
			//如果坐标的纵坐标的值更靠近第(i+2)行棋格时,将此纵坐标值修改为第(i+2)行棋格的上边界的纵坐标,
			//反之修改为第(i+1)行的上边界的纵坐标

				y = m_ChessBoard_TopLeft_y+m_ChessBoardPane_Distance * (i + 1);
			}else{

				y = m_ChessBoard_TopLeft_y + m_ChessBoardPane_Distance * i;
			}
		}
	}

	return CPoint(x, y);
}

//通过获得坐标点确定棋子应该放置的范围,这里返回的是棋子应该放的位置的左上角的坐标
bool CFiveChess::paste_Chess(CPoint point)
{

	//判断如果用户点击的位置已经有棋子放置,那么就将不能将棋子放置到该位置上
	if(m_ChessBoard_state[point.y / m_ChessBoardPane_Distance][point.x / m_ChessBoardPane_Distance] != 0)
	{
		return false;
	} else{
	
		//假如当前棋盘上的棋子为偶数时
		if(m_CountChess % 2 == 0) {

			//粘贴黑棋,并且将该位置的状态设置为黑棋的状态
			IS_BLACK_CHESS = true;
			get_Chess(point.x, point.y);
			m_ChessBoard_state[point.y / m_ChessBoardPane_Distance][point.x / m_ChessBoardPane_Distance] = 1;

		} else {

			IS_BLACK_CHESS = false;
			get_Chess(point.x, point.y);
			m_ChessBoard_state[point.y / m_ChessBoardPane_Distance][point.x / m_ChessBoardPane_Distance] = 2;
		}
	}

	Invalidate();
				
	//是否有人获胜了
	Anyone_Success(point.y / m_ChessBoardPane_Distance, point.x / m_ChessBoardPane_Distance);
	return true;
}

//以特定的点特定的长度来画正方形框
void CFiveChess::m_Draw_Rectangle(CPoint point)
{
	CBrush brush (RGB (0,255,0));
	CRect rect(point.x - m_ChessBoardPane_Distance / 2 + 1, point.y - m_ChessBoardPane_Distance / 2 + 1,
				point.x + m_ChessBoardPane_Distance / 2 - 1, point.y + m_ChessBoardPane_Distance / 2 - 1); 
	pCurrent_DC->FrameRect(&rect,&brush);  

}

//为将方形的棋子处理成圆形的棋子而将棋子图片与掩码图片进行混合操作
void CFiveChess::set_Round_Chess()
{
	m_BlackChess_DC.BitBlt(0, 0, m_BlackChess_BITMAP.bmWidth, m_BlackChess_BITMAP.bmHeight,
							&m_Mask_DC, 0, 0, SRCPAINT);
	m_WhiteChess_DC.BitBlt(0, 0, m_BlackChess_BITMAP.bmWidth, m_BlackChess_BITMAP.bmHeight,
							&m_Mask_DC, 0, 0, SRCPAINT);
}

//获得圆形的相应的棋子
void CFiveChess::get_Chess(int Current_X, int Current_Y)
{
	if(IS_BLACK_CHESS)
	{
		//在相应的位置取得黑色圆形棋子
		m_Complex_DC.BitBlt(Current_X - m_ChessPicture_Size/2, Current_Y - m_ChessPicture_Size/2, m_ChessPicture_Size, 
										m_ChessPicture_Size, &m_Mask_DC, 0, 0, MERGEPAINT);
		m_Complex_DC.BitBlt(Current_X - m_ChessPicture_Size/2, Current_Y - m_ChessPicture_Size/2, m_ChessPicture_Size, 
										m_ChessPicture_Size, &m_BlackChess_DC, 0, 0, SRCAND);
	  } else {
	
		m_Complex_DC.BitBlt(Current_X - m_ChessPicture_Size/2, Current_Y - m_ChessPicture_Size/2, m_ChessPicture_Size,
										m_ChessPicture_Size, &m_Mask_DC, 0, 0, MERGEPAINT);
		m_Complex_DC.BitBlt(Current_X - m_ChessPicture_Size/2, Current_Y - m_ChessPicture_Size/2, m_ChessPicture_Size,
										m_ChessPicture_Size, &m_WhiteChess_DC, 0, 0, SRCAND);
	}

}	

BEGIN_MESSAGE_MAP(CFiveChess, CWnd)
	//{{AFX_MSG_MAP(CFiveChess)
	ON_WM_PAINT()
	ON_WM_CLOSE()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CFiveChess::OnPaint() 
{
	CPaintDC dc(this); // device context for painting	
	// TODO: Add your message handler code here
	//paste_chessBoard();

	//粘贴复合DC到该窗口上。
	dc.BitBlt(0, 0, m_current_Wnd_Rect.Width(), m_current_Wnd_Rect.Height(),
								&m_Complex_DC, 0, 0,  SRCCOPY);

}

void CFiveChess::OnClose() 
{
	// TODO: Add your message handler code here and/or call default

	ReleaseDC(pCurrent_DC); //释放申请的DC资源

	CWnd::OnClose();
}

void CFiveChess::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CPoint cPoint = get_Modified_Position(point.x, point.y);
	
	if(paste_Chess(cPoint)) {    //如果粘贴棋子到复合DC上成功的话,就将计数器里的值增加
	
		m_CountChess++;
	}

	CWnd::OnLButtonDown(nFlags, point);
}


//析构函数
CFiveChess::~CFiveChess()
{
	//释放申请的资源。
	DeleteDC(m_BlackChess_DC);
	DeleteDC(m_WhiteChess_DC);
	DeleteDC(m_ChessBoard_DC);
	DeleteDC(m_Complex_DC);
	DeleteDC(m_Mask_DC);

}

void CFiveChess::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CPoint cPoint = get_Modified_Position(point.x, point.y);
	if(cPoint.x == m_Previous_Point.x && cPoint.y == m_Previous_Point.y)
	{
		m_Draw_Rectangle(cPoint);
	} else {
	
		Invalidate();
		m_Draw_Rectangle(cPoint);
	}
	
	m_Previous_Point.x = cPoint.x;
	m_Previous_Point.y = cPoint.y;
	CWnd::OnMouseMove(nFlags, point);
}

⌨️ 快捷键说明

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