📄 chinesechessdlg.cpp
字号:
//判断鼠标是否在棋盘内,并且点中了用户棋子
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 + -