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

📄 chessdlg.cpp

📁 一个简单的象棋游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	int x,y;

	this->m_MousePoint=point;

	//将坐标换算成棋盘上的格子
	y=(m_MousePoint.y-14)/GRILLEHEIGHT;
	x=(m_MousePoint.x-15)/GRILLEWIDTH;
	
	memcpy(m_byBackupChessBoard,m_byChessBoard,90);//备份当前棋盘

	//判断鼠标是否在棋盘内,并且点中了棋子
	if(point.x>0 && point.y>0 && point.x<m_nBoardWidth && point.y<m_nBoardHeight)
	{
		CMenu menu;
		menu.LoadMenu(IDR_MENU_SETCHESSBOARDING);
		ClientToScreen(&point);
		menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this);	
	}

	CDialog::OnRButtonDown(nFlags, point);
}

void CChessDlg::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_Status==Chessing)
	{
		OnSet();
		return;
	}

	this->m_MousePoint=point;
	OnDelete();

	CDialog::OnLButtonDblClk(nFlags, point);
}

int CChessDlg::IsGameOver(BYTE position[][9])
{
	int i,j;
	BOOL RedLive=FALSE,BlackLive=FALSE;

	//检查红方九宫是否有帅
	for(i=7;i<10;i++)
		for(j=3;j<6;j++)
		{
			if(position[i][j]==B_KING)
				BlackLive=TRUE;
			if(position[i][j]==R_KING)
				RedLive=TRUE;
		}

	//检查黑方九宫是否有将
	for(i=0;i<3;i++)
		for(j=3;j<6;j++)
		{
			if(position[i][j]==B_KING)
				BlackLive=TRUE;
			if(position[i][j]==R_KING)
				RedLive=TRUE;
		}

	if(m_nUserChessColor==REDCHESS)
	{
		if(!RedLive)
			return 1;
		
		if(!BlackLive)
			return -1;
	}
	else
	{
		if(!RedLive)
			return -1;
		
		if(!BlackLive)
			return 1;
	}

	return 0;
}

void CChessDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	if(MessageBox("你确定要退出吗?","友情提醒",MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2)==IDNO)
		return;

	CDialog::OnClose();
}

void CChessDlg::OnClearcb() 
{
	// TODO: Add your command handler code here
	if(MessageBox("你确定要清空棋盘吗?","友情提醒",MB_ICONQUESTION | MB_DEFBUTTON2 | MB_YESNO)==IDNO)
		return;

	int i,j;

	for(i=0;i<10;i++)
		for(j=0;j<9;j++)
			m_byChessBoard[i][j]=NOCHESS;

	//刷新屏幕
	InvalidateRect(NULL,FALSE);
	UpdateWindow();
}

void CChessDlg::InvertChessBoard(BYTE cb[][9])
{
	int i,j;
	BYTE btTemp;

	for(i=0;i<5;i++)
		for(j=0;j<9;j++)
		{
			btTemp=cb[i][j];
			cb[i][j]=cb[9-i][8-j];
			cb[9-i][8-j]=btTemp;
		}

	//刷新屏幕
	InvalidateRect(NULL,FALSE);
	UpdateWindow();
}

void CChessDlg::AddChessRecord(int nFromX,int nFromY,int nToX,int nToY,int nUserChessColor,int nSourceID)
{
	CString strChess;
	CString str;

	if(nUserChessColor==REDCHESS)//用户执红棋
		str=this->GetMoveStr(nFromX,nFromY,nToX,nToY,nSourceID);
	else
	{
		InvertChessBoard(m_byChessBoard);
		str=this->GetMoveStr(10-nFromX,11-nFromY,10-nToX,11-nToY,nSourceID);
		InvertChessBoard(m_byChessBoard);
	}
	str.Format("%d--"+str,m_iBout);

	m_lstChessRecord.AddString(str);
	m_lstChessRecord.PostMessage(WM_VSCROLL,SB_BOTTOM,0);
}

CString CChessDlg::ConvertDigit2Chinese(int nNum)
{
	switch(nNum)
	{
	case 1:
		return "一";
		
	case 2:
		return "二";
		
	case 3:
		return "三";
		
	case 4:
		return "四";
		
	case 5:
		return "五";
		
	case 6:
		return "六";
		
	case 7:
		return "七";
		
	case 8:
		return "八";
		
	case 9:
		return "九";

	default:
		return "";
	}
}

void CChessDlg::OnNewgame() 
{
	// TODO: Add your command handler code here
	if(MessageBox("你确定要重新来一局吗?","友情提醒",MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2)==IDNO)
		return;

	memcpy(m_byChessBoard,InitChessBoard,90);    //初始化棋盘
	memcpy(m_byShowChessBoard,InitChessBoard,90);
	memcpy(m_byBackupChessBoard,InitChessBoard,90);
	m_MoveChess.nChessID=NOCHESS;                //清除移动棋子
	m_bIsGameOver=false;

	if(m_nUserChessColor==BLACKCHESS)
		this->InvertChessBoard(m_byChessBoard);

	m_lstChessRecord.ResetContent();

	//刷新屏幕
	InvalidateRect(NULL,FALSE);
	UpdateWindow();

	m_bIsBegin=false;

	//清空栈
	while(!m_stackUndoMove.empty())
		m_stackUndoMove.pop();
	while(!m_stackRedoMove.empty())
		m_stackRedoMove.pop();

	m_staticTip.SetWindowText(m_strWelcome);
	m_btnUndo.EnableWindow(0);
	m_btnRedo.EnableWindow(0);
	m_btnStop.EnableWindow(0);

	//释放旧的搜索引擎
	if(m_pSE)
		delete m_pSE;
	switch(m_SetDlg.GetSelectedEngine())
	{
	case 0:
		m_pSE=new CNegaMaxEngine;
		break;
		
	case 1:
		m_pSE=new CAlphaBetaEngine;//创建alpha-beta搜索引擎
		break;
		
	case 2:
		m_pSE=new CFAlphaBetaEngine;
		break;
		
	case 3:
		m_pSE=new CAspirationSearch;
		break;
		
	case 4:
		m_pSE=new CPVS_Engine;
		break;
		
	case 5:
		m_pSE=new CIDAlphabetaEngine;
		break;
		
	case 6:
		m_pSE=new CAlphaBeta_TTEngine;
		break;
		
	case 7:
		m_pSE=new CAlphabeta_HHEngine;
		break;
		
	case 8:
		m_pSE=new CMTD_fEngine;
		break;
		
	default:
		m_pSE=new CNegaMaxEngine;
		break;
	}
	m_pMG=new CMoveGenerator;//创建走法产生器
	m_pEvel=new CEveluation; //创建估值核心

	m_pSE->SetSearchDepth(m_SetDlg.GetSelectedPly());
	m_pSE->SetUserChessColor(m_nUserChessColor);
	m_pSE->SetMoveGenerator(m_pMG);//将走法产生器传给搜索引擎
	m_pSE->SetEveluator(m_pEvel);  //将估值核心传给搜索引擎
	m_pSE->SetThinkProgress(&m_progressThink);
								   //设定进度条

	m_pEvel->ClearAccessCount();
}

void CChessDlg::OnBtncomputer() 
{
	// TODO: Add your control notification handler code here
	m_iWhoChess=m_iWhoChess%2+1;
	m_btnStop.EnableWindow(1);
	m_hHandle=::CreateThread(0,0,ThinkProc,this,0,&m_dwThreadID);
}

void CChessDlg::OnBtnundo() 
{
	// TODO: Add your control notification handler code here
	if(m_stackUndoMove.empty())
		return;

	m_btnRedo.EnableWindow(1);//激活悔棋按钮
	m_bIsGameOver=false;

	for(int i=0;i<2;i++)
	{
		m_umUndoMove=m_stackUndoMove.top();
		m_stackRedoMove.push(m_umUndoMove);
		m_pSE->UndoChessMove(m_byChessBoard,&m_umUndoMove.cmChessMove,m_umUndoMove.nChessID);
		memcpy(m_byShowChessBoard,m_byChessBoard,90);
		memcpy(m_byBackupChessBoard,m_byChessBoard,90);
		m_stackUndoMove.pop();
		m_lstChessRecord.DeleteString(m_lstChessRecord.GetCount()-1);
		
		//重绘屏幕  
		InvalidateRect(NULL,FALSE);
		UpdateWindow();
	}
	m_iBout--;

	if(m_stackUndoMove.empty())
	{
		m_staticTip.SetWindowText("棋已悔完,无棋可悔了");
		m_btnUndo.EnableWindow(0);//冻结悔棋按钮
	}
}

void CChessDlg::OnBtnredo() 
{
	// TODO: Add your control notification handler code here
	if(m_stackRedoMove.empty())
		return;

	UNDOMOVE umTemp;
	
	m_iBout++;
	m_btnUndo.EnableWindow(1);//激活悔棋按钮
	for(int i=0;i<2;i++)
	{
		umTemp=m_stackRedoMove.top();
		m_pSE->RedoChessMove(m_byChessBoard,&umTemp.cmChessMove);
		memcpy(m_byShowChessBoard,m_byChessBoard,90);
		memcpy(m_byBackupChessBoard,m_byChessBoard,90);
		m_stackUndoMove.push(umTemp);
		m_stackRedoMove.pop();
		this->AddChessRecord(umTemp.cmChessMove.From.x+1,umTemp.cmChessMove.From.y+1,umTemp.cmChessMove.To.x+1,umTemp.cmChessMove.To.y+1,m_nUserChessColor,umTemp.cmChessMove.nChessID);

		//重绘屏幕  
		InvalidateRect(NULL,FALSE);
		UpdateWindow();
	}

	if(m_stackRedoMove.empty())
	{
		m_staticTip.SetWindowText("棋已还原完,无棋可还原了");
		m_btnRedo.EnableWindow(0);//冻结还原按钮
	}

	switch(IsGameOver(m_byChessBoard))
	{
	case -1:
		m_staticTip.SetWindowText("老兄,你好强哦");
		break;

	case 1:
		m_staticTip.SetWindowText("老兄,看来你不是我的对手啊");
		break;

	default:
		return;
	}
	
	m_bIsGameOver=true;
}

CString CChessDlg::GetMoveStr(int nFromX,int nFromY,int nToX,int nToY,int nSourceID)
{
	CString str;
	bool bIsAgain;
	int i;
	int nCount;
	int nPos[5];
	int j=0;

	switch(nSourceID)
	{
	case B_KING://黑将
		if(nFromY==nToY)
		{
			str.Format("黑:将%d平%d",nFromX,nToX);
			break;
		}
		
		if(nFromY>nToY)
			str.Format("黑:将%d退%d",nFromX,nFromY-nToY);
		else
			str.Format("黑:将%d进%d",nFromX,nToY-nFromY);
		
		break;
		
	case B_CAR://黑车
		bIsAgain=false;
		for(i=0;i<10;i++)
			if(m_byChessBoard[i][nFromX-1]==B_CAR && i!=nFromY-1 && i!=nToY-1)
			{
				bIsAgain=true;
				break;
			}
			
			if(nFromY>nToY)
			{
				if(bIsAgain)
				{
					if(i>nFromY-1)
						str.Format("黑:后车进%d",nFromY-nToY);
					else
						str.Format("黑:前车进%d",nFromY-nToY);
				}
				else
					str.Format("黑:车%d退%d",nFromX,nFromY-nToY);
			}
			else
				if(nFromY<nToY)
				{						
					if(bIsAgain)
					{
						if(i>nFromY-1)
							str.Format("黑:后车进%d",nToY-nFromY);
						else
							str.Format("黑:前车进%d",nToY-nFromY);
					}
					else
						str.Format("黑:车%d进%d",nFromX,nToY-nFromY);
				}
				else
				{
					if(bIsAgain)
					{
						if(i>nFromY-1)
							str.Format("黑:后车平%d",nToX);
						else
							str.Format("黑:前车平%d",nToX);
					}
					else
						str.Format("黑:车%d平%d",nFromX,nToX);
					
					break;
				}
				
				break;
				
	case B_HORSE://黑马
		bIsAgain=false;
		for(i=0;i<10;i++)
			if(m_byChessBoard[i][nFromX-1]==B_HORSE && i!=nFromY-1 && i!=nToY-1)
			{
				bIsAgain=true;
				break;
			}
			
			if(bIsAgain)
			{
				if(i>nFromY-1)
				{
					if(nFromY>nToY)
						str.Format("黑:后马退%d",nToX);
					else
						str.Format("黑:后马进%d",nToX);
				}
				else
				{
					if(nFromY>nToY)
						str.Format("黑:前马退%d",nToX);
					else
						str.Format("黑:前马进%d",nToX);
				}
			}
			else
			{
				if(nFromY>nToY)
					str.Format("黑:马%d退%d",nFromX,nToX);
				else
					str.Format("黑:马%d进%d",nFromX,nToX);
			}
			
			break;
			
	case B_CANON://黑炮	
		bIsAgain=false;
		for(i=0;i<10;i++)
			if(m_byChessBoard[i][nFromX-1]==B_CANON && i!=nFromY-1 && i!=nToY-1)
			{
				bIsAgain=true;
				break;
			}
			
			if(nFromY>nToY)
			{
				if(bIsAgain)
				{
					if(i>nFromY-1)
						str.Format("黑:后炮进%d",nFromY-nToY);
					else
						str.Format("黑:前炮进%d",nFromY-nToY);
				}
				else
					str.Format("黑:炮%d退%d",nFromX,nFromY-nToY);
			}
			else
				if(nFromY<nToY)
				{
					bIsAgain=false;
					for(i=0;i<10;i++)
						if(m_byChessBoard[i][nFromX-1]==B_CANON && i!=nFromY-1 && i!=nToY-1)
						{
							bIsAgain=true;
							break;
						}
						
						if(bIsAgain)
						{
							if(i>nFromY-1)
								str.Format("黑:后炮进%d",nToY-nFromY);
							else
								str.Format("黑:前炮进%d",nToY-nFromY);
						}
						else
							str.Format("黑:炮%d进%d",nFromX,nToY-nFromY);
				}
				else
				{
					if(bIsAgain)
					{
						if(i>nFromY-1)
							str.Format("黑:后炮平%d",nToX);
						else
							str.Format("黑:前炮平%d",nToX);
					}
					else
						str.Format("黑:炮%d平%d",nFromX,nToX);
					break;
				}
				
				break;
				
	case B_BISHOP://黑士
		if(nFromY>nToY)
			str.Format("黑:士%d退%d",nFromX,nToX);
		else
			str.Format("黑:士%d进%d",nFromX,nToX);
		
		break;
		
	case B_ELEPHANT://黑象
		bIsAgain=false;
		for(i=0;i<5;i++)
			if(m_byChessBoard[i][nFromX-1]==B_ELEPHANT && i!=nFromY-1 && i!=nToY-1)
			{
				bIsAgain=true;
				break;
			}
			
			if(bIsAgain)
			{
				if(i>nFromY-1)
				{
					if(nFromY>nToY)
						str.Format("黑:后象退%d",nToX);
					else
						str.Format("黑:后象进%d",nToX);
				}
				else
				{
					if(nFromY>nToY)
						str.Format("黑:前象退%d",nToX);
					else
						str.Format("黑:前象进%d",nToX);
				}
			}
			else
			{
				if(nFromY>nToY)
					str.Format("黑:象%d退%d",nFromX,nToX);
				else
					str.Format("黑:象%d进%d",nFromX,nToX);
			}

⌨️ 快捷键说明

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