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

📄 chessdlg.cpp

📁 对弈程序采用了多种搜索算法.以下是本程序主要的类说明: 1.CEveluation类:估值类,对给定的棋盘进行估值. 2.CMoveGenerator类:走法产生器,对给定的棋盘局面搜索出
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			return false;
		else
			return true;
	else
		if(nChessSort==B_KING || nChessSort==R_KING)
			if(uiCount<1)
				return false;
			else 
				return true;
		else
			if(uiCount<2)
				return false;
			else
				return true;
}

void CChessDlg::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_Status==Chessing)
	{
		CMenu menu;
		menu.LoadMenu(IDR_MENU_CHESSING);
		ClientToScreen(&point);
		menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this);

		return;
	}

	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::OnBtnbegin() 
//{
//	// TODO: Add your control notification handler code here
//	CString sNodeCount;
//	int timecount;
//
//	if(m_nUserChessColor==BLACKCHESS)
//	{
//		m_iBout++;
//		m_bIsThinking=true;
//		m_pSE->SearchAGoodMove(m_byChessBoard);//让电脑走下一步	
//		m_cmBestMove=m_pSE->GetBestMove();   //得到最佳走法
//		m_umUndoMove=m_pSE->GetUndoMove();
//		m_stackUndoMove.push(m_umUndoMove);  //将电脑走法压栈
//		this->AddChessRecord(m_cmBestMove.From.x+1,m_cmBestMove.From.y+1,m_cmBestMove.To.x+1,m_cmBestMove.To.y+1,m_nUserChessColor,m_cmBestMove.nChessID);		
//		m_bIsThinking=false;
//
//		sNodeCount.Format("共访问%d个节点,花费时间%.3fs",m_pEvel->GetAccessCount(),(GetTickCount()-timecount)/1000.0);
//		m_staticTip.SetWindowText(sNodeCount);
//
//		::FlashWindow(this->GetSafeHwnd(),TRUE);
//	}
//	else
//		m_staticTip.SetWindowText("老兄,你先请");
//
//	//重绘屏幕  
//	InvalidateRect(NULL,FALSE);
//	UpdateWindow();
//
//	m_bIsBegin=true;
//}

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);

	int nCount=m_lstChessRecord.GetCount();
	for(int i=0;i<nCount;i++)
		m_lstChessRecord.DeleteString(i);

	//刷新屏幕
	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);
}

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;

⌨️ 快捷键说明

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