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

📄 chinesechessdlg.cpp

📁 用c++ 开发的中国象棋
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		
		
		//判断鼠标是否在棋盘内,并且点中了用户棋子
		if(y>=0 && y<10 && x>=0 && x<9&& (m_bIsClient?   //客户端为红棋
			IsRed(m_byChessBoard[y][x]):IsBlack(m_byChessBoard[y][x])))
		{
			//将当前棋子的信息装入,记录移动棋子的结构中
			m_ptMoveChess.x=x;
			m_ptMoveChess.y=y;
			m_MoveChess.nChessID=m_byChessBoard[y][x];
			
			//将该棋子原位置棋子去掉
			m_byChessBoard[y][x]=NoChessMan;
			m_byShowChessBoard[y][x]=NoChessMan;
			
			//让棋子中点坐标位于鼠标所在点
			point.x-=20;
			point.y-=20;
			m_MoveChess.ptMovePoint=point;
			//重绘屏幕
			
			CRect r(point.x-10, point.y-10,
				point.x+GridWidth+10,point.y + GridHeight+10);	
			InvalidateRect(&r,TRUE);//刷新窗口
			UpdateWindow();
			SetCapture();//独占鼠标焦点
		}
	}
	else//人机对弈
	{
		m_Think.SetPos(0);//清空进度条
		if(m_bIsThinking)
		{
			m_EditOutputInfo.SetWindowText("我在思考哦!别打扰我!");
			return;
		}
		//判断鼠标是否在棋盘内,并且点中了用户棋子
		if(y>=0 && y<10 && x>=0 && x<9&& IsBlack(m_byChessBoard[y][x]))
		{
			//将当前棋子的信息装入,记录移动棋子的结构中
			m_ptMoveChess.x=x;
			m_ptMoveChess.y=y;
			m_MoveChess.nChessID=m_byChessBoard[y][x];
			
			//将该棋子原位置棋子去掉
			m_byChessBoard[y][x]=NoChessMan;
			m_byShowChessBoard[y][x]=NoChessMan;
			
			//让棋子中点坐标位于鼠标所在点
			point.x-=20;
			point.y-=20;
			m_MoveChess.ptMovePoint=point;
			//重绘屏幕
			CRect r(point.x-10, point.y-10,
				point.x+GridWidth+10,point.y + GridHeight+10);	
			InvalidateRect(&r,TRUE);//刷新窗口
			UpdateWindow();
			SetCapture();//独占鼠标焦点
			
			
		}
	}
	
	CDialog::OnLButtonDown(nFlags, point);
}

void CChineseChessDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	
    //将坐标换算成棋盘上的格子 
	int y=(point.y-BoarderHeight)/GridHeight;
	int x=(point.x-BoarderWidth)/GridWidth;
	BOOL bTurnSide=FALSE;
	//判断是否有移动棋子,并且该棋子的移动是一个合法走法
	if( m_MoveChess.nChessID && m_pMG->IsValidMove(m_byBackupChessBoard,\
		m_ptMoveChess.x,m_ptMoveChess.y,x,y,m_nUserChessColor))
	{
			//将走法压栈
		m_cmBestMove.pFrom.x=m_ptMoveChess.x;
		m_cmBestMove.pFrom.y=m_ptMoveChess.y;
		m_cmBestMove.pTo.x=x;
		m_cmBestMove.pTo.y=y;
		m_cmBestMove.ChessID=m_MoveChess.nChessID;
		m_umUndoMove.cmChessMove=m_cmBestMove;
		m_umUndoMove.nChessID=m_byChessBoard[y][x];
		m_stackUndoMove.push(m_umUndoMove);
	
		m_byChessBoard[y][x]=m_MoveChess.nChessID;
		m_byShowChessBoard[y][x]=m_MoveChess.nChessID;
		
		if(IsNetBattle)//网络队战
		{
			CMyMessage temp;
			temp.iFlag=0;
			temp.m_ChessID=m_MoveChess.nChessID;
			temp.m_FromX=m_ptMoveChess.y;
			temp.m_FromY=m_ptMoveChess.x;
			temp.m_ToX=y;
			temp.m_ToY=x;		
			m_iWhoChess=temp.m_turn=m_bIsClient?BLACKCHESS:REDCHESS;//该对方走了
			m_ClientSocket.SendMessage(&temp);
			m_EditOutputInfo.SetWindowText(_T(""));
			//悔棋
		}
		else
		{
			bTurnSide=TRUE;
			
		}
		
		if(!m_stackUndoMove.empty())
		{
			m_BtnUnDo.EnableWindow(TRUE);
		}
		
	}
	else//否则恢复移动前的棋盘状态
	{
		memcpy(m_byShowChessBoard,m_byBackupChessBoard,90);
		memcpy(m_byChessBoard,m_byBackupChessBoard,90);
	}
    
	m_MoveChess.nChessID=NoChessMan;//将移动的棋子清空
	
	//重绘屏幕  
	InvalidateRect(NULL,FALSE);
	UpdateWindow();	
	ReleaseCapture();//释放鼠标焦点
	
	if (bTurnSide)
	{
		m_hHandle=::CreateThread(0,0,ThinkProc,this,0,&m_dwThreadID);
		if(!m_hHandle)
		{
			CString str;
			str.Format("%d",GetLastError());
			AfxMessageBox(str);
		}
	}
	
	CDialog::OnLButtonUp(nFlags, point);
}

void CChineseChessDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	
	if(m_MoveChess.nChessID)//如果选中的有棋子
	{
		//让棋子中心位于鼠标所在处
		point.x-=20;
		point.y-=20;
		
		m_MoveChess.ptMovePoint=point;//保存移动棋子的坐标	
		//棋子拖出棋盘时将该棋子删掉
		if(point.x<BoarderWidth || point.y<BoarderWidth || \
			point.x>BoarderWidth+9*GridWidth || point.y>BoarderWidth+10*GridHeight)
			m_byChessBoard[m_ptMoveChess.y][m_ptMoveChess.x]=NoChessMan;
		CRect r(point.x-10, point.y-10,
			point.x+GridWidth+10,point.y + GridHeight+10);	
		InvalidateRect(&r,TRUE);//刷新窗口
		UpdateWindow();//立即执行刷新
	}
	
	
	CDialog::OnMouseMove(nFlags, point);
}//发送聊天信息
void CChineseChessDlg::OnBtnSend() 
{
	CString strTemp;
	m_EditSendMsg.GetWindowText(strTemp);
	CMyMessage *strMsg=new CMyMessage();
	strMsg->m_strText=strTemp;
	CString hostname;
	CClientSock::GetLocalHostName(hostname);
	strMsg->m_hostname=hostname;
	
	m_MsgList.AddString(hostname+"说: "+strTemp);
	m_ClientSocket.SendMessage(strMsg);
	m_EditSendMsg.SetWindowText(_T(""));
	delete strMsg;
	
}


void CAboutDlg::OnOK() 
{
	
	CDialog::OnOK();
}

//控制各种控件和对话框的颜色
HBRUSH CChineseChessDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	if(nCtlColor==CTLCOLOR_STATIC)
	{
		pDC->SetBkMode(TRANSPARENT);
		hbr=(HBRUSH)GetStockObject(NULL_BRUSH);

	}
	return hbr;	
}



void CChineseChessDlg::OnSetExit() 
{
	AfxGetMainWnd()->PostMessage(WM_CLOSE); //退出程序
}

void CChineseChessDlg::OnSetGametype() 
{
	// TODO: Add your command handler code here
	if (setdlg.DoModal()==IDOK)
	{

		m_RedName.SetWindowText(setdlg.m_PlayerName);
		
	}
	m_BtnReDo.EnableWindow(FALSE);
	m_BtnUnDo.EnableWindow(FALSE);	
}



int CChineseChessDlg::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]==BlackKing)
				BlackLive=TRUE;
			if(position[i][j]==RedKing)
				RedLive=TRUE;
		}
		
		//检查黑方九宫是否有将
		for(i=0;i<3;i++)
			for(j=3;j<6;j++)
			{
				if(position[i][j]==BlackKing)
					BlackLive=TRUE;
				if(position[i][j]==RedKing)
					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 CChineseChessDlg::ProcessPendingAccept()
{
	if(m_ListenSocket.Accept(m_ClientSocket)==FALSE)
	{
		AfxMessageBox("Server Listen Socket Error");
		return;
	}
	else
	{
		m_ClientSocket.Init();
		m_MsgList.SetWindowText("有人进来了");
		AfxMessageBox("有人进来了");
	}
}
void CChineseChessDlg::GetLocalIP()
{
	static BOOL first=TRUE;
	if(first==TRUE)
	{
		CClientSock::GetLocalHostName(m_sLocalName);
		CClientSock::GetIpAddress(LPCSTR(m_sLocalName),m_bIP[0],m_bIP[1],m_bIP[2],m_bIP[3]);
		m_ip.Format("%d.%d.%d.%d",m_bIP[0],m_bIP[1],m_bIP[2],m_bIP[3]);
		first=FALSE;
	}
}


void CChineseChessDlg::OnChangeEditMsg() 
{	
	if(!m_bIsInit)
	{
		AfxMessageBox("没有连接,不能发送消息 ");
		return;
	}
	
}
void CChineseChessDlg::OnNetCreate() 
{
	IsNetBattle=TRUE;		
	m_bIsClient=FALSE;
	m_bIsInit=TRUE;
	if(m_ListenSocket.Init(SERVER_PORT))
		m_MsgList.AddString("成功的创建游戏...正在等待其他玩家...");	
}

void CChineseChessDlg::OnNetJoin() 
{
	IsNetBattle=TRUE;		
	m_bIsClient=TRUE;
	
	m_ClientSocket.Create();
	if(m_ClientSocket.Connect(m_ServIP,SERVER_PORT))
	{
		m_bIsInit=TRUE;
		m_ClientSocket.Init();
		m_MsgList.AddString("成功的连接到了服务器,可以开始游戏了");
		AfxMessageBox("成功的连接到了服务器,可以开始游戏了");
		memcpy(ChessBoardMap,RChessBoardMap,90);//棋盘逆过来
	}
	else
	{
		m_ClientSocket.Close();
		AfxMessageBox("连接失败!");
	}
}
void CChineseChessDlg::OnNewGame()
{
	if(MessageBox("你确定要重新来一局吗?","友情提醒",MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2)==IDNO)
		return;
	if(IsNetBattle&&m_bIsClient)
		memcpy(ChessBoardMap,RChessBoardMap,90);//客户端得将棋盘倒过来
	
	memcpy(m_byChessBoard,ChessBoardMap,90);    //初始化棋盘
	memcpy(m_byShowChessBoard,ChessBoardMap,90);
	memcpy(m_byBackupChessBoard,ChessBoardMap,90);
	m_MoveChess.nChessID=NoChessMan;                //清除移动棋子
	
	//刷新屏幕
	InvalidateRect(NULL,TRUE);
	UpdateWindow();
	InvalidateRect(NULL,FALSE);
	UpdateWindow();
	
	//清空栈
	while(!m_stackUndoMove.empty())
		m_stackUndoMove.pop();
	while(!m_stackRedoMove.empty())
		m_stackRedoMove.pop();
}

BOOL CChineseChessDlg::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	
	if(m_hBitmap!=NULL)
	{
		HBITMAP OldBitMap;
		CDC MemDC;
		MemDC.CreateCompatibleDC(pDC);
		CRect rect;
		GetClientRect(&rect);
		OldBitMap=(HBITMAP)MemDC.SelectObject(m_hBitmap);
		pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
		MemDC.SelectObject(OldBitMap);
		DrawChessBoard(pDC);
	}
	else
	{
		CBitmap bitmap;
		bitmap.LoadBitmap(IDB_BITMAP1);
		CDC  MemDC;
		MemDC.CreateCompatibleDC(pDC);
		CBitmap *pOldBitMap=MemDC.SelectObject(&bitmap);
		BITMAP bm;
		bitmap.GetBitmap(&bm);
		pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&MemDC,0,0,SRCCOPY);
		MemDC.SelectObject(pOldBitMap);
		DrawChessBoard(pDC);		
	}
	
	return TRUE;
	
	//	return CDialog::OnEraseBkgnd(pDC);
}

void CChineseChessDlg::OnBtnGiveup() 
{
	// TODO: Add your control notification handler code here
	OnNewGame();	
}

void CChineseChessDlg::OnBtnReundo() 
{
	
	/////
	if(m_stackRedoMove.empty())
	{
		m_BtnReDo.EnableWindow(FALSE);
		return;
	}
	
	UnDoMove umTemp;	
	m_iBout++;
	m_BtnUnDo.EnableWindow(TRUE);
	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();
	}
			//重绘屏幕  
		InvalidateRect(NULL,TRUE);
		UpdateWindow();
		InvalidateRect(NULL,FALSE);
		UpdateWindow();

	if(m_stackRedoMove.empty())
	{
		m_EditOutputInfo.SetWindowText("棋已还原完,无棋可还原了");
		m_BtnReDo.EnableWindow(0);//冻结还原按钮
	}
	
	switch(IsGameOver(m_byChessBoard))
	{
	case -1:
		m_EditOutputInfo.SetWindowText("厉害呀,我服了");
		break;
		
	case 1:
		m_EditOutputInfo.SetWindowText("得好好练练哦!");
		break;
		
	default:
		return;
	}
	
	m_bIsGameOver=true;
	
}

void CChineseChessDlg::OnBtnUndo() 
{
	if(m_stackUndoMove.empty())
	{
		return;
	}
	m_BtnReDo.EnableWindow(TRUE);//激活悔棋按钮
	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();
		

//		CRect rFrom(m_umUndoMove.cmChessMove.pFrom.x
		CRect rect(0,0,1000,1000);	
		InvalidateRect(rect,TRUE);
		UpdateWindow();
		InvalidateRect(NULL,FALSE);
		UpdateWindow();
		
	}
	m_iBout--;
	
	if(m_stackUndoMove.empty())
	{
		m_EditOutputInfo.SetWindowText("棋已悔完,无棋可悔了");
		m_BtnUnDo.EnableWindow(FALSE);
	}
	
}

void CChineseChessDlg::OnOpen() 
{
	
	CFileDialog OpenDlg(TRUE,NULL,"",0,"棋谱(*.cm)|*.cm||");	
	if(OpenDlg.DoModal()==IDCANCEL) 
		return;
	FILE* fp;
	int i,j;
	int nUserChessColor;
	
	fp=fopen(OpenDlg.GetPathName(),"r");
	if(fp==NULL)
	{
		MessageBox("打开文件出错","错误提示",MB_ICONWARNING);
		return;
	}
	
	if(MessageBox("是否覆盖当前棋局?","友情提醒",MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2)==IDNO)
		return;
	

⌨️ 快捷键说明

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