📄 chessdlg.cpp
字号:
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 + -