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

📄 cchessuidlg.cpp

📁 中国象棋人机对弈
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_K0],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_S.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Sl],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Sr],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_X.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Xl],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Xr],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_M.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Ml],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Mr],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_J.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Jl],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Jr],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_P.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Pl],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_Pr],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			loadbmp(qzidir+"BLACK_B.bmp");			
			SelectObject(MemDC,bit);
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_B1],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_B2],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_B3],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_B4],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));
			TransparentBlt2(dc.m_hDC,ptChess[BLACK_B5],ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

			
		}
		else
		{
			//显示当前为盲棋模式
			loadbmp("Pic/Blind.bmp");			
			SelectObject(MemDC,bit);
			POINT ptBlind = {205,290};
			TransparentBlt2(dc.m_hDC,ptBlind,ww,hh,MemDC,0,0,ww,hh,RGB(255,255,255));

		}
		
		CDialog::OnPaint();


		//::ReleaseMutex(HMutex);

	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CCChessUIDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


////////////////// Programmer-Defined Function ///////////////////////////
inline BOOL loadbmp(CString cc)
{	
	DeleteObject(bit);	
	bit=(HBITMAP)LoadImage	
	(	AfxGetInstanceHandle(),
		cc,
		IMAGE_BITMAP,	
		0,	
		0,	
		LR_LOADFROMFILE|LR_CREATEDIBSECTION
	);
	if(bit==NULL) return FALSE;	
	DIBSECTION ds;
	BITMAPINFOHEADER &bm = ds.dsBmih;
	GetObject(bit,sizeof(ds),&ds);	
	ww = bm.biWidth;	
	hh = bm.biHeight;
	return TRUE;
}


inline void TransparentBlt2( HDC hdc0,	
					 POINT point0,
					 int nW0,int nH0,
					 HDC hdc1,
					 int nX1,int nY1,
					 int nW1,int nH1,
					 UINT Tcol
					 )
{	
	int nX0	=point0.x;
	int nY0	=point0.y;
	HBITMAP hBMP   =CreateCompatibleBitmap(hdc0,nW0, nH0);
	HBITMAP mBMP   =CreateBitmap(nW0,nH0,1,1,NULL);	
	HDC		hDC    =CreateCompatibleDC(hdc0);
	HDC		mDC    =CreateCompatibleDC(hdc0);
	HBITMAP oldBMP =(HBITMAP)SelectObject(hDC, hBMP);
	HBITMAP oldmBMP=(HBITMAP)SelectObject(mDC, mBMP);
	if (nW0==nW1&&nH0==nH1)
		BitBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,SRCCOPY);
	else
		StretchBlt(hDC,0,0,nW0,nH0,hdc1,nX1,nY1,nW1,nH1,SRCCOPY);

	SetBkColor(hDC, Tcol);
	BitBlt(mDC,0,0,nW0,nH0,hDC,0,0,SRCCOPY);
	SetBkColor(hDC, RGB(0,0,0));
	SetTextColor(hDC, RGB(255,255,255));
	BitBlt(hDC,0,0,nW0,nH0,mDC,0,0,SRCAND);
	SetBkColor(hdc0,RGB(255,255,255));
	SetTextColor(hdc0,RGB(0,0,0));

	BitBlt(hdc0,nX0,nY0,nW0,nH0,mDC,0,0,SRCAND);
	BitBlt(hdc0,nX0,nY0,nW0,nH0,hDC,0,0,SRCPAINT);

	SelectObject(hDC, oldBMP);				
	DeleteDC(hDC);
	SelectObject(mDC, oldmBMP);
	DeleteDC(mDC);
	DeleteObject(hBMP);
	DeleteObject(mBMP);
}

void CCChessUIDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if( WhoseTurn != RED )//还没轮到红方走棋
	{
		return;
	}

	if( point.x>=5 && point.x<=545 && point.y>=5 && point.y<=605 )
	{

		SetTimer(1,100,NULL);

		if( fGameover == true )
		{
			MessageBox("这盘棋下完了。","游戏结束",MB_OK);
		}
		else 
		{
			//获得标准特定像素
			stPoint = GetThePoint( point );

			//取得当前要更新区
			/*
			RECT rctCur	={	stPoint.x,
				stPoint.y,
				stPoint.x+60,
				stPoint.y+60 };

			rctPreR.left	=	stPoint.x;
			rctPreR.top	=	stPoint.y;
			rctPreR.right	=stPoint.x+60;
			rctPreR.bottom	=stPoint.y+60 ;
*/
			

			//if( nHaveSelected != NOCHESS )//已经选了棋子
			if( nHaveSelected <= 15 )//只能选红子//已经选了棋子
			{
				
				nObject =NOCHESS;
				nObject = JudgeThePoint( stPoint );

				if( IsTheSameSide(nHaveSelected,nObject) )//又选了同一方的棋子
				{
					nHaveSelected = nObject;
					ptPreKuang = ptCurKuang = stPoint;

					rctPreR = rctCurR;

					rctCurR.left	=	stPoint.x;
					rctCurR.top		=	stPoint.y;
					rctCurR.right	=stPoint.x+60;
					rctCurR.bottom	=stPoint.y+60 ;

					//重绘屏幕
					InvalidateRect(&rctCurR,FALSE);
					InvalidateRect(&rctPreR,FALSE);
					//InvalidateRect(&rctCurB,FALSE);
					//InvalidateRect(&rctPreB,FALSE);
					//UpdateWindow();
				}
				else 
				{
					ptCFrom = PointToCChessBoard(ptChess[nHaveSelected]);
					ptCTo = PointToCChessBoard(stPoint);

					if( CanMOVE( ptCFrom, ptCTo ) == true )//着法合法
					{
						rctPreR = rctCurR;

						rctCurR.left	=	stPoint.x;
						rctCurR.top		=	stPoint.y;
						rctCurR.right	=stPoint.x+60;
						rctCurR.bottom	=stPoint.y+60 ;

						for (int i = 0; i<9; i++)
						{
							for (int j = 0; j<10;j++)
							{
								temp.CChessBoard[i][j] = CChessBoard[i][j];
							} 
						}

						for (int i=0; i<32;i++)
						{
							temp.ptChess[i] = ptChess[i];
						}
						//temp.ptCurKuang = ptCurKuang;
						//temp.ptPreKuang = ptPreKuang;

						vBackQueue.push_back(temp);

						cb1.EnableWindow(!vBackQueue.empty());
						//cb2.EnableWindow(!vForwardQueue.empty());



						//取得上一个更新区
						/*
						RECT rctPre	={	ptChess[nHaveSelected].x,
							ptChess[nHaveSelected].y,
							ptChess[nHaveSelected].x+60,
							ptChess[nHaveSelected].y+60 };

						rctPreR.left	=	ptChess[nHaveSelected].x;
						rctPreR.top	=	ptChess[nHaveSelected].y;
						rctPreR.right	=ptChess[nHaveSelected].x+60;
						rctPreR.bottom	=ptChess[nHaveSelected].y+60 ;
						*/

						if( nObject != NOCHESS )
						{//要吃子
							ptChess[nObject].x = -100;
							ptChess[nObject].y = -100;

							//播放吃子声
							if(nHaveSelected == RED_Pl
								|| nHaveSelected == RED_Pr
								|| nHaveSelected == BLACK_Pl
								|| nHaveSelected == BLACK_Pr)
							{
								//炮吃子
								sndPlaySound("wav/ceat.wav",SND_SYNC);
							}
							else
							{
								//其它子吃子
								sndPlaySound("wav/eat.wav",SND_SYNC);
							}
						}
						else
						{
							//播放落子声
							sndPlaySound("wav/put.wav",SND_SYNC);
						}

						ptChess[nHaveSelected] = stPoint;

						//CChessBoard[ptCTo.x][ptCTo.y]=CChessBoard[ptCFrom.x][ptCFrom.y];
						//CChessBoard[ptCFrom.x][ptCFrom.y] = 0;

						///////////// GO ///////////////////////
						cmMove.ptFrom = ptCFrom;
						cmMove.ptTo = ptCTo;

						DoMove( & cmMove );

						///////// 将着法保存以检测重复 /////////////

						nNumOfStep++;
						////////////////////////////////////

						
						str.Format( "%d - %s", nNumOfStep,
							GetMoveStr(ptCFrom.x,ptCFrom.y,ptCTo.x,ptCTo.y,nHaveSelected));


						//AfxMessageBox(str);
						//lstChessRecord.AddString(str);//    ->AddString(str);
						//lstChessRecord.PostMessage(WM_VSCROLL,SB_BOTTOM,0);
						//lstChessRecord.SetCurSel(1);


						//CListBox *pLB = (CListBox*)GetDlgItem(IDC_LISTCCHESS);
						//pLB ->InsertString(-1,str);
						pLB->AddString(str);
						pLB->PostMessage(WM_VSCROLL,SB_BOTTOM,0);


						if( ! vForwardQueue.empty() )
						{
							vForwardQueue.clear();
						}

						ptCurKuang =stPoint;

						nHaveSelected = NOCHESS;

						//重绘屏幕
						InvalidateRect(&rctPreR,FALSE);
						InvalidateRect(&rctCurR,FALSE);
						InvalidateRect(&rctPreB,FALSE);
						InvalidateRect(&rctCurB,FALSE);
						//UpdateWindow();

						//再刷一遍,解决“刷新不完全”的错误
						//InvalidateRect(&rctPreR,FALSE);

						if( nObject != NOCHESS )
						{
							if(IsGameOverUI() == REDWIN)
							{
								MessageBox("大侠果真厉害,小弟甘拜下风!","游戏结束",MB_OK);
								GameOver();
							}
							if(IsGameOverUI() == BLACKWIN)
							{
								MessageBox("老兄,看来你不行嘛。","游戏结束",MB_OK);
								GameOver();
							}
						}
						
						//PushMoveStack(ptCFrom,ptCTo,)

						WhoseTurn = BLACK ;


						KillTimer(1);
						SetTimer(2,100,NULL);
						

						if( fGameover == false )
						{
							//电脑走棋
							nMaxSearchDepth = m_SetDlg.GetDepth();

							bThreadOver = false;
							CThinkingThread = AfxBeginThread(ThinkingThread,&m_hWnd,0,0,0,NULL);

							//Sleep( 8000);
							

							//清空还原队列,并禁用还原按钮
							vForwardQueue.clear();
							cb2.EnableWindow(!vForwardQueue.empty());
							
						}

					}
					else	//着法不合法
					{
						//rctPreR = rctCurR;

						//rctCurR.left	=	stPoint.x;
						//rctCurR.top		=	stPoint.y;
						//rctCurR.right	=stPoint.x+60;
						//rctCurR.bottom	=stPoint.y+60 ;

						//重绘屏幕
						//InvalidateRect(&rctCurR,FALSE);
						InvalidateRect(&rctPreR,FALSE);
						//InvalidateRect(&rctCurB,FALSE);
						//InvalidateRect(&rctPreB,FALSE);
						//UpdateWindow();

					}

				}

			}
			else //尚未选棋子
			{
				if( (nHaveSelected = JudgeThePoint( stPoint )) != NOCHESS )
				{
					if( nHaveSelected <= 15 )//只能选红子
					{
						//置框的位置
						ptPreKuang = ptCurKuang = stPoint;

						rctCurR.left	=	stPoint.x;
						rctCurR.top		=	stPoint.y;
						rctCurR.right	=stPoint.x+60;
						rctCurR.bottom	=stPoint.y+60;

						//重绘屏幕
						InvalidateRect(&rctCurR,FALSE);
						InvalidateRect(&rctCurB,FALSE);
						InvalidateRect(&rctPreB,FALSE);
						//UpdateWindow();
					}

				}

			}
		}
		
	}

	CDialog::OnLButtonDown(nFlags, point);
}

/////////// 思考线程 //////////////////////////////////////////
UINT ThinkingThread(LPVOID pParam)
{
	//SetTimer((HWND)hhWnd,2,1000,NULL);
	/*
	CString str;
	str.Format("%x",hhWnd);
	AfxMessageBox(str);*/
	//::WaitForSingleObject(HMutex,INFINITE);
	//////////////////////////////////////////////////////

	if( nNumOfStep == 1 )
	{//第一步查开局库
		cmMove =UseLibrary();
		if( cmMove.ptFrom.x != -1 )
		{
			DoMove( &cmMove );
		}
		else
		{
			cmMove = SearchAGoodMove();
		}
	}
	else
	{
		cmMove = SearchAGoodMove();
	}

	////////// 将着法保存以检测重复。。。 ///////////

	ptCFrom = CChessBoardToPoint( cmMove.ptFrom );
	ptCTo = CChessBoardToPoint( cmMove.ptTo );


	rctPreB.left	=	ptCFrom.x;
	rctPreB.top		=	ptCFrom.y;
	rctPreB.right	=	ptCFrom.x+60;
	rctPreB.bottom	=	ptCFrom.y+60 ;

	rctCurB.left	=	ptCTo.x;
	rctCurB.top		=	ptCTo.y;
	rctCurB.right	=	ptCTo.x+60;
	rctCurB.bottom	=	ptCTo.y+60 ;

	/*
	RECT rctB;
	
	if( rctPreB.left < rctCurB.left )
	{
		rctB.left	= rctPreB.left;
		rctB.right	= rctCurB.right;
	}
	else
	{
		rctB.left	= rctCurB.left;
		rctB.right	= rctPreB.right;
	}

	if( rctPreB.top < rctCurB.top )
	{
		rctB.top	= rctPreB.top;
		rctB.bottom	= rctCurB.bottom;
	}
	else
	{
		rctB.top	= rctCurB.top;
		rctB.bottom	= rctPreB.bottom;
	}
	*/

	nHaveSelected = JudgeThePoint( ptCFrom );
	nObject = JudgeThePoint( ptCTo );

	ptChess[nHaveSelected] = ptCTo;
	
	ptPreKuang	= ptCFrom; 
	ptCurKuang	= ptCTo;

	/*
	CString ssstr;
	ssstr.Format("%d---%d",ptChess[nHaveSelected].x,ptChess[nHaveSelected].y);
	
	if(MessageBox((HWND)hhWnd,ssstr,"OO",MB_OKCANCEL)==IDOK)
	{
		InvalidateRect((HWND)hhWnd,&rctPreR,FALSE);
		InvalidateRect((HWND)hhWnd,&rctCurR,FALSE);
		InvalidateRect((HWND)hhWnd,&rctPreB,FALSE);
		InvalidateRect((HWND)hhWnd,&rctCurB,FALSE);
	}
	*/

	////////////////////////////////////////////////////////
	//::ReleaseMutex(HMutex);

	str.Format( "%d - %s", nNumOfStep, 
		GetMoveStr(cmMove.ptFrom.x,cmMove.ptFrom.y,cmMove.ptTo.x,cmMove.ptTo.y,nHaveSelected));

	pLB->AddString(str);
	pLB->PostMessage(WM_VSCROLL,SB_BOTTOM,0);


	if( nObject != NOCHESS )
	{//要吃子
		ptChess[nObject].x = -100;
		ptChess[nObject].y = -100;

		//播放吃子声
		if(nHaveSelected == RED_Pl
			|| nHaveSelected == RED_Pr
			|| nHaveSelected == BLACK_Pl
			|| nHaveSelected == BLACK_Pr)
		{
			//炮吃子
			sndPlaySound("wav/ceat.wav",SND_ASYNC);
		}
		else
		{
			//其它子吃子
			sndPlaySound("wav/eat.wav",SND_ASYNC);
		}
	}
	else
	{
		//播放落子声
		sndPlaySound("wav/put.wav",SND_ASYNC);
	}

	
	nHaveSelected = NOCHESS;

	//Sleep(500);	//试验!!!!!!!!!!解决“刷新不完全”的错误
	//该方法已被证明无效

	//RECT rctB1 = rctCurB;
	//RECT rctB2 = rctPreB;

	//重绘屏幕
	//InvalidateRect((HWND)hhWnd,&rctPreR,FALSE);
	//InvalidateRect((HWND)hhWnd,&rctCurR,FALSE);

	//InvalidateRect((HWND)hhWnd,&rctB1,FALSE);
	//InvalidateRect((HWND)hhWnd,&rctB2,FALSE);

	//InvalidateRect((HWND)hhWnd,&rctPreB,FALSE);
	//InvalidateRect((HWND)hhWnd,&rctCurB,FALSE);
	//InvalidateRect((HWND)hhWnd,&rctB,FALSE);	//两个合成一个刷

	
	//再刷一遍,解决“刷新不完全”的错误
	//InvalidateRect((HWND)hhWnd,&rctPreB,FALSE);

	//InvalidateRect((HWND)hhWnd,NULL,FALSE);
	//UpdateWindow((HWND)hhWnd);


	WhoseTurn = RED ;
	//	KillTimer((HWND)hhWnd,2);
	SetTimer((HWND)hhWnd,1,100,NULL);
	
	bThreadOver = true;

	return 0;
}
/////////////////////////////////////////////////////////////////////

//游戏结束

⌨️ 快捷键说明

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