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

📄 chessdlg.cpp

📁 一个人工智能下象棋的小游戏 含电子书 包含了alph-beta 深度优先 极大极小值算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	return (HCURSOR) m_hIcon;
}

void CChessDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(!IsRedAi)
	{
		if (bGameOver)
			return ;
		int x,y;
		//将坐标换算成棋盘上的格子
		x=(point.x-15)/GRILLEWIDTH;
		y=(point.y-14)/GRILLEHEIGHT;
		//备份当前棋盘
		memcpy(m_BackupChessBoard, m_ChessBoard, 90);
		//判断鼠标是否在棋盘内,并且点中了红方(用户)棋子
		if (point.x > 0 && point.y > 0 &&point.x< m_nBoardWidth && point.y< m_nBoardHeight && IsRed(m_ChessBoard[y][x]))
		{
			memcpy(m_BackupChessBoard, m_ChessBoard, 90);//备份棋盘
			m_ptMoveChess.x = x;
			m_ptMoveChess.y = y;
			m_MoveChess.nChessID = m_ChessBoard[y][x];
			m_ChessBoard[m_ptMoveChess.y][m_ptMoveChess.x] = NOCHESS;//将该棋子原位置棋子去掉
			point.x -= 18;//让棋子中点坐标位于鼠标所在点
			point.y -= 18;
			m_MoveChess.ptMovePoint = point;
			InvalidateRect(NULL,FALSE);//重绘屏幕
			UpdateWindow();
			SetCapture();//独占鼠标焦点
		}
	}
	CDialog::OnLButtonDown(nFlags, point);
}

void CChessDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default	
	if(!IsRedAi)
	{
		if (bGameOver)
			return;
		BOOL bTurnSide = FALSE; 
		int timecount;
		int x=(point.x-15)/GRILLEWIDTH;
		int y=(point.y-14)/GRILLEHEIGHT;
		if (m_MoveChess.nChessID &&
			CMoveGenerator::IsValidMove(m_BackupChessBoard, m_ptMoveChess.x, m_ptMoveChess.y,x,y))
		{
			memcpy(m_BoardForBack[m_nForBackup], m_ChessBoard, 90);//用于悔棋
			m_BoardForBack[m_nForBackup][m_ptMoveChess.y][m_ptMoveChess.x] = m_MoveChess.nChessID;//用于悔棋
			m_nForBackup=(m_nForBackup+1)%3;//用于悔棋
			m_backcount++;//用于悔棋
			if(m_backcount>=3)m_backcount=3;//用于悔棋
			m_ChessBoard[y][x] = m_MoveChess.nChessID;
			bTurnSide = TRUE;
			m_OutputInfo.SetWindowText("电脑正在思考!");
		}
		else
		{
			memcpy(m_ChessBoard, m_BackupChessBoard, 90);
			m_OutputInfo.SetWindowText("你的下法不符合规则!");
		}

		m_MoveChess.nChessID = NOCHESS;
		InvalidateRect(NULL,FALSE);
		UpdateWindow();	
		ReleaseCapture();

		if (bTurnSide == TRUE)
		{
			timecount = GetTickCount();
			m_pSE->SearchAGoodMove(m_ChessBoard,0);	
			
			CString sNodeCount;
			sNodeCount.Format("电脑耗时  %d ms.\r 该您下了....", GetTickCount() - timecount);
			m_OutputInfo.SetWindowText(sNodeCount);
		}
		InvalidateRect(NULL, FALSE);
		UpdateWindow();
		if (IsGameOver(m_ChessBoard))
		{
			bGameOver = TRUE;
			if(m_whowin==TRUE)
				MessageBox("士别三日,当刮目相看,大侠继续努力!");
			else
				MessageBox("胜败乃兵家常事,请大侠重新来过!");
		}
	
	}
	CDialog::OnLButtonUp(nFlags, point);
}

void CChessDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (m_MoveChess.nChessID)
	{
		//防止将棋子拖出棋盘
		if( point.x < 15)
			point.x = 15;
		if( point.y < 15)
			point.y = 15;
		if( point.x > m_nBoardWidth - 15)
			point.x = m_nBoardWidth - 15;
		if( point.y > m_nBoardHeight - 15)
			point.y = m_nBoardHeight - 15;
		
		point.x -= 18;
		point.y -= 18;
		m_MoveChess.ptMovePoint = point;
		InvalidateRect(NULL,FALSE);//刷新窗口
		UpdateWindow();
	}

	CDialog::OnMouseMove(nFlags, point);
}

void CChessDlg::OnNewGame() 
{
	// TODO: Add your command handler code here
	CMoveGenerator * pMG;
	CEveluation *pEvel;
	
	CNewGame newGameDlg;
	if (  newGameDlg.DoModal() == IDOK)
	{
		if (m_pSE)
			delete m_pSE;
		switch(newGameDlg.GetSelectedEngine())
		{
		case 0:
			m_pSE = new CNegaMaxEngine;
			break;
		default:
			m_pSE = new CNegaMaxEngine;
			break;
		}
		m_pSE->SetSearchDepth(newGameDlg.GetSelectedPly());
		pEvel = new CEveluation;
	}
	else 
		return;
	
	memcpy(m_ChessBoard, InitChessBoard, 90);//初始化棋盘
	memcpy(m_BoardForBack[0], InitChessBoard, 90);//用于悔棋
	m_MoveChess.nChessID = NOCHESS;
	IsRedAi=FALSE;
	bGameOver=FALSE;
	m_nForBackup=0;
	m_backcount=0;
	GetMenu()->EnableMenuItem(ID_BACK,MF_ENABLED);
	GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_REDAI,MF_UNCHECKED);
	GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_UNREDAI,MF_CHECKED);

	pMG = new CMoveGenerator;
	m_pSE->SetMoveGenerator(pMG);
	m_pSE->SetEveluator(pEvel);

	//m_bGameOver = FALSE;//this code does not contents in books.
	
	InvalidateRect(NULL,FALSE);
	UpdateWindow();
}

void CChessDlg::OnAboutbox() 
{
	// TODO: Add your command handler code here
	CAboutDlg m_aboutdlg;
	m_aboutdlg.DoModal();

}

void CChessDlg::OnBack() 
{
	// TODO: Add your command handler code here
	if (m_backcount>0)
	{
		int n=--m_nForBackup;
		memcpy(m_ChessBoard, m_BoardForBack[n], 90);	
		m_MoveChess.nChessID = NOCHESS;
		InvalidateRect(NULL,FALSE);
		UpdateWindow();
		m_backcount--;
		if(m_nForBackup<0)m_nForBackup=2;
	}
	else
	{
		MessageBox("还悔?你小子别太过分啊!");
	}
}

void CChessDlg::OnRedai() 
{
	// TODO: Add your command handler code here
	if(!IsRedAi)
	{
		CMoveGenerator * pMG;
		CEveluation *pEvel;
		
		CNewGame newGameDlg;
		if (  newGameDlg.DoModal() == IDOK)
		{
			if (m_pSE_Red)
				delete m_pSE_Red;
			switch(newGameDlg.GetSelectedEngine())
			{
			case 0:
				m_pSE_Red = new CNegaMaxEngine;
				break;
			default:
				m_pSE_Red = new CNegaMaxEngine;
				break;
			}
			m_pSE_Red->SetSearchDepth(newGameDlg.GetSelectedPly());
			pEvel = new CEveluation;
			pMG = new CMoveGenerator;
			m_pSE_Red->SetMoveGenerator(pMG);
			m_pSE_Red->SetEveluator(pEvel);
			MessageBox("托管成功");
		}
		else 
		{
			MessageBox("托管失败!");
			return;
		}
		SetTimer(111,3000,NULL);
		IsRedAi=TRUE;
		GetMenu()->EnableMenuItem(ID_BACK,MF_GRAYED);
		GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_REDAI,MF_CHECKED);
		GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_UNREDAI,MF_UNCHECKED);
		m_nForBackup=0;
		m_backcount=0;
		m_OutputInfo.SetWindowText("AI曰...不下地域谁下地狱...托管中...");
	}
	else{MessageBox("已经托管");}
}

void CChessDlg::OnUnredai() 
{
	// TODO: Add your command handler code here
	if (IsRedAi)
	{	
		KillTimer(111);
		IsRedAi=FALSE;
		GetMenu()->EnableMenuItem(ID_BACK,MF_ENABLED);
		GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_REDAI,MF_UNCHECKED);
		GetMenu()->GetSubMenu(2)->CheckMenuItem(IDM_UNREDAI,MF_CHECKED);
		m_OutputInfo.SetWindowText("托管结束,请大侠自力更生...");
		memcpy(m_BoardForBack[0], m_ChessBoard, 90);//用于悔棋
		m_nForBackup=0;
		m_backcount=0;
		MessageBox("托管结束");
	}

}

void CChessDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(IsRedAi)
	{
		if (bGameOver)
		{
			KillTimer(111);
			return;
		}
		IsRedAi=FALSE;
		m_pSE_Red->SearchAGoodMove(m_ChessBoard,1);//红方下
		InvalidateRect(NULL,FALSE);
		UpdateWindow();	
		
		m_pSE->SearchAGoodMove(m_ChessBoard,0);	//黑方下
		InvalidateRect(NULL, FALSE);
		UpdateWindow();	
		
		if (IsGameOver(m_ChessBoard))
		{
			bGameOver = TRUE;
			IsRedAi=FALSE;
			if(m_whowin==TRUE)
				MessageBox("士别三日,当刮目相看,大侠继续努力!");
			else
				MessageBox("胜败乃兵家常事,请大侠重新来过!");
		}
		IsRedAi=TRUE;
	}
	CDialog::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

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