www.gusucode.com > 经典游戏中国象棋VC++源代码-源码程序 > 经典游戏中国象棋VC++源代码-源码程序\code\主程序\BaseSearchEngine.cpp
//Download by http://www.NewXing.com // SearchEngine.cpp: implementation of the CBaseSearchEngine class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Chess.h" #include "BaseSearchEngine.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// const BYTE byInitChessBoard[10][9]= { {B_CAR,B_HORSE,B_ELEPHANT,B_BISHOP,B_KING,B_BISHOP,B_ELEPHANT,B_HORSE,B_CAR}, {NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS}, {NOCHESS,B_CANON,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,B_CANON,NOCHESS}, {B_PAWN,NOCHESS,B_PAWN,NOCHESS,B_PAWN,NOCHESS,B_PAWN,NOCHESS,B_PAWN}, {NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS}, //楚河 汉界// {NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS}, {R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN,NOCHESS,R_PAWN}, {NOCHESS,R_CANON,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,R_CANON,NOCHESS}, {NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS,NOCHESS}, {R_CAR,R_HORSE,R_ELEPHANT,R_BISHOP,R_KING,R_BISHOP,R_ELEPHANT,R_HORSE,R_CAR} }; CBaseSearchEngine::CBaseSearchEngine() { m_iEvel=0; m_iCanSearchDepth=0; m_byAteChess=NOCHESS; } CBaseSearchEngine::~CBaseSearchEngine() { delete m_pMG; delete m_pEval; } BYTE CBaseSearchEngine::MakeMove(CHESSMOVE* cm) { BYTE nChessID; BYTE bySrcChess; int nSize; nChessID=byCurChessBoard[cm->To.y][cm->To.x];//取目标位置棋子 bySrcChess=byCurChessBoard[cm->From.y][cm->From.x]; //--------------更新过河棋子数目-------------- if(nChessID!=NOCHESS) { if(IsRed(nChessID)) { if(cm->To.y<=4) { m_pEval->m_uiCurBigChessCnt[nChessID]--; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[nChessID]--; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[nChessID]--; } } else { if(cm->To.y>=5) { m_pEval->m_uiCurBigChessCnt[nChessID]--; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[nChessID]--; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[nChessID]--; } } } if(bySrcChess!=NOCHESS) { if(IsRed(bySrcChess)) { if(cm->From.y<=4) { m_pEval->m_uiCurBigChessCnt[bySrcChess]--; if(cm->From.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]--; if(cm->From.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]--; } if(cm->To.y<=4) { m_pEval->m_uiCurBigChessCnt[bySrcChess]++; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]++; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]++; } } else { if(cm->From.y>=5) { m_pEval->m_uiCurBigChessCnt[bySrcChess]--; if(cm->From.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]--; if(cm->From.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]--; } if(cm->To.y>=5) { m_pEval->m_uiCurBigChessCnt[bySrcChess]++; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]++; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]++; } } } //-------------------------------------------- //--------------更新当前各种棋子位置栈-------------- nSize=m_pEval->m_vectorCurChessPos[bySrcChess].size(); for(int i=0;i<nSize;i++) { if(m_pEval->m_vectorCurChessPos[bySrcChess][i].x==cm->From.x && m_pEval->m_vectorCurChessPos[bySrcChess][i].y==cm->From.y) { m_pEval->m_vectorCurChessPos[bySrcChess][i].x=cm->To.y; m_pEval->m_vectorCurChessPos[bySrcChess][i].y=cm->To.x; } } if(nChessID!=NOCHESS) m_pEval->m_vectorCurChessPos[nChessID].pop_back(); //-------------------------------------------------- byCurChessBoard[cm->To.y][cm->To.x]=bySrcChess; //把棋子移动到目标位置 byCurChessBoard[cm->From.y][cm->From.x]=NOCHESS;//将原位置清空 return nChessID;//返回被吃掉的棋子 } void CBaseSearchEngine::RedoChessMove(BYTE byChessBoard[][9],CHESSMOVE* cm) { byChessBoard[cm->To.y][cm->To.x]=byChessBoard[cm->From.y][cm->From.x]; byChessBoard[cm->From.y][cm->From.x]=NOCHESS; } void CBaseSearchEngine::UnMakeMove(CHESSMOVE* cm, BYTE nChessID) { BYTE bySrcChess=byCurChessBoard[cm->To.y][cm->To.x]; //更新过河棋子数目 if(bySrcChess!=NOCHESS) { if(IsRed(bySrcChess)) { if(cm->To.y<=4) { m_pEval->m_uiCurBigChessCnt[bySrcChess]--; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]--; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]--; } if(cm->From.y<=4) { m_pEval->m_uiCurBigChessCnt[bySrcChess]++; if(cm->From.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]++; if(cm->From.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]++; } } else { if(cm->To.y>=5) { m_pEval->m_uiCurBigChessCnt[bySrcChess]--; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]--; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]--; } if(cm->From.y>=5) { m_pEval->m_uiCurBigChessCnt[bySrcChess]++; if(cm->From.x<=4) m_pEval->m_uiCurLBigChessCnt[bySrcChess]++; if(cm->From.x>=4) m_pEval->m_uiCurRBigChessCnt[bySrcChess]++; } } } if(nChessID!=NOCHESS) { if(IsRed(nChessID)) { if(cm->To.y<=4) { m_pEval->m_uiCurBigChessCnt[nChessID]++; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[nChessID]++; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[nChessID]++; } } else { if(cm->To.y>=5) { m_pEval->m_uiCurBigChessCnt[nChessID]++; if(cm->To.x<=4) m_pEval->m_uiCurLBigChessCnt[nChessID]++; if(cm->To.x>=4) m_pEval->m_uiCurRBigChessCnt[nChessID]++; } } } //更新当前棋子位置信息 for(int i=0;i<m_pEval->m_vectorCurChessPos[bySrcChess].size();i++) { if(m_pEval->m_vectorCurChessPos[bySrcChess][i].x==cm->To.x && m_pEval->m_vectorCurChessPos[bySrcChess][i].y==cm->To.y) { m_pEval->m_vectorCurChessPos[bySrcChess][i].x=cm->From.y; m_pEval->m_vectorCurChessPos[bySrcChess][i].y=cm->From.x; } } if(nChessID!=NOCHESS) { CHESSMANPOS cmpTemp; cmpTemp.x=cm->To.y; cmpTemp.y=cm->To.x; m_pEval->m_vectorCurChessPos[nChessID].push_back(cmpTemp); } byCurChessBoard[cm->From.y][cm->From.x]=byCurChessBoard[cm->To.y][cm->To.x];//将目标位置棋子拷回原位 byCurChessBoard[cm->To.y][cm->To.x]=nChessID; //恢复目标位置的棋子 } void CBaseSearchEngine::UndoChessMove(BYTE byChessBoard[][9],CHESSMOVE* cm, BYTE nChessID) { byChessBoard[cm->From.y][cm->From.x]=byChessBoard[cm->To.y][cm->To.x];//将目标位置棋子拷回原位 byChessBoard[cm->To.y][cm->To.x]=nChessID; //恢复目标位置的棋子 } int CBaseSearchEngine::IsGameOver(BYTE byChessBoard[][9], int nDepth) { int i,j; bool bIsRedLive=0,bIsBlackLive=0; //检查红方九宫是否有帅 i=7; while(i<10 && !bIsRedLive && !bIsBlackLive) { j=3; while(j<6 && !bIsRedLive && !bIsBlackLive) { if(byChessBoard[i][j]==B_KING) { bIsBlackLive=1; break; } if(byChessBoard[i][j]==R_KING) { bIsRedLive=1; break; } j++; } i++; } //检查黑方九宫是否有将 i=0; while(i<3 && !bIsBlackLive) { j=3; while(j<6 && !bIsBlackLive) { if(byChessBoard[i][j]==B_KING) { bIsBlackLive=TRUE; break; } if(byChessBoard[i][j]==R_KING) { bIsRedLive=TRUE; break; } j++; } i++; } i=(m_iMaxDepth-nDepth+1)%2;//取当前奇偶标志,奇数层为电脑方,偶数层为用户方 //红方不在 if(!bIsRedLive) if(i) return 19990+nDepth; //奇数层返回极大值 else return -19990-nDepth;//偶数层返回极小值 //黑方不在 if(!bIsBlackLive) if(i) return -19990-nDepth;//奇数层返回极小值 else return 19990+nDepth; //偶数层返回极大值 return 0;//将帅都在,返回0 } int CBaseSearchEngine::IsObeyRule(BYTE byChessBoard[][9],int iDepth,CBANDMOVE cam,bool bIsRed) { int iSize; int iCount; int i; BYTE byChess,byChess2; if(!bIsRed) { //判断长将和长捉 iSize=m_vectorBlackCbAndMove.size(); for(i=0;i<iSize;i++) { if(!memcmp(&cam,&m_vectorBlackCbAndMove[i],sizeof(CBANDMOVE))) return CR_LONGGEN; } //判断送将 byChess2=MakeMove(&cam.cm); UnMakeMove(&cam.cm,byChess2); for(i=0;i<iCount;i++) { byChess=MakeMove(&m_pMG->m_MoveList[iDepth][i]); UnMakeMove(&m_pMG->m_MoveList[iDepth][i],byChess); if(byChess==B_KING) return CR_SENDGEN; } return CR_OBEY; } else { //判断长将和长捉 iSize=m_vectorRedCbAndMove.size(); for(i=0;i<iSize;i++) { if(!memcmp(&cam,&m_vectorRedCbAndMove[i],sizeof(CBANDMOVE))) return CR_LONGGEN; } //判断送将 iCount=m_pMG->CreatePossibleMove(byChessBoard,iDepth,1,m_nUserChessColor); for(i=0;i<iCount;i++) { byChess=MakeMove(&m_pMG->m_MoveList[iDepth][i]); UnMakeMove(&m_pMG->m_MoveList[iDepth][i],byChess); if(byChess==R_KING) return CR_SENDGEN; } return CR_OBEY; } } bool CBaseSearchEngine::IsFail(BYTE byChessBoard[][9], bool bIsRed) { int iCount=m_pMG->CreatePossibleMove(byChessBoard,0,bIsRed,m_nUserChessColor); BYTE byChess; CBANDMOVE cam; int i; // for(i=0;i<iCount;i++) // { // byChess=MakeMove(&m_pMG->m_MoveList[0][i]); // IsObeyRule(byChessBoard, // } return 1; } int CBaseSearchEngine::GetEvel() { int iTemp=m_iEvel; m_iEvel=0; return iTemp; } int CBaseSearchEngine::SelMove(vector<int> vectorScore,int iMaxScore) { int iPos=0; int iAllScore=0; vector<float> vectorSelProb;//选择概率 float fAllSelProb=0; float fRand; int iSize=vectorScore.size(); if(iMaxScore<0) { //求总得分 for(iPos=0;iPos<iSize;iPos++) { vectorScore[iPos]+=5-iMaxScore; iAllScore+=vectorScore[iPos]; } } else //求总得分 for(iPos=0;iPos<iSize;iPos++) iAllScore+=vectorScore[iPos]; //求各节点的选择概率 for(iPos=0;iPos<iSize;iPos++) vectorSelProb.push_back(vectorScore[iPos]*1.0/iAllScore); //根据轮盘法选择节点 iSize=vectorSelProb.size(); fRand=rand()*1.0/RAND_MAX; for(iPos=0;iPos<iSize;iPos++) { fAllSelProb+=vectorSelProb[iPos]; if(fRand<fAllSelProb) return iPos; } } bool CBaseSearchEngine::BadForMe(BYTE byChessBoard[][9],bool bIsRed) { // if(IsObeyRule) // return 1; return 0; } UINT CBaseSearchEngine::GetChessAge(BYTE byChessBoard[][9]) { int iCnt=0; int i,j; for(i=0;i<10;i++) { for(j=0;j<9;j++) if(byChessBoard[i][j]!=byInitChessBoard[i][j]) iCnt++; } if(iCnt<30) return CA_START; if(iCnt<90) return CA_MID; return CA_END; }