bool ChessBoard::isLegalMove(int mv) { int sqSrc, sqDst, pcSrc, pcDst; sqSrc = SRC(mv); sqDst = DST(mv); if (sqSrc==sqDst) { return false; } pcSrc = m_data[sqSrc]; pcDst = m_data[sqDst]; if (side(pcSrc)==side(pcDst)) { return false; } Moves mvs; generateMoves(sqSrc, mvs); for(int i=0; i<mvs.count(); i++) { if (mvs[i]==mv) { return true; } } return false; }
int ChessBoard::test1_max(int depth, int& mv) { if (depth==0) { mv = 0; return m_vlBlack - m_vlRed; } Moves mvs; //int selfSide = m_sdPlayer; int best = -999999; generateMoves(mvs); for(int i=0; i<mvs.count(); i++) { int oldVal = m_vlBlack - m_vlRed; int pcCapture; if (makeMove(mvs[i], pcCapture)) { int temp_mv; int val = test1_min(depth-1, temp_mv); if (val>best) { best = val; mv = mvs[i]; } undoMakeMove(mvs[i], pcCapture); } int newVal = m_vlBlack - m_vlRed; Q_ASSERT(oldVal==newVal); } return best; }
bool ChessBoard::IsMate() { //qDebug()<<"check isMate side="<<m_sdPlayer; //int selfSide = m_sdPlayer; Moves mvs; generateMoves(mvs); for(int i=0; i<mvs.count(); i++) { //qDebug()<<"尝试解招:"<< mvString(mvs[i]); int pcCaptured = _movePiece(mvs[i]); if (!isChecked()) { _undoMovePiece(mvs[i], pcCaptured); //qDebug()<<"!!!解招:"<< mvString(mvs[i]); return false; } else{ _undoMovePiece(mvs[i], pcCaptured); } } return true; }
int ChessBoard::negaMax(int depth, int& mv) { if (depth==0) { return m_sdPlayer?m_vlBlack - m_vlRed:m_vlRed - m_vlBlack; } m_searchCallTimes++; int best = INT_MIN; Moves mvs; generateMoves(mvs); for(int i=0; i<mvs.count(); i++) { int oldVal = m_vlBlack - m_vlRed; int pcCapture; //qDebug()<<mvString(mvs[i]); if (makeMove(mvs[i], pcCapture)) { int temp_mv; int val = -1 * negaMax(depth-1, temp_mv); if (temp_mv) { //qDebug()<<mvString(temp_mv)<<" 评分"<<val; } if (val>best) { best = val; mv = mvs[i]; } undoMakeMove(mvs[i], pcCapture); //qDebug()<<"UndoMakeMove"; } int newVal = m_vlBlack - m_vlRed; Q_ASSERT(oldVal==newVal); } return best; }
int ChessBoard::alphaBetaSearch(int depth, int alpha, int beta) { //1.到达水平线返回 if (depth==0) { return evaluate(); } m_searchCallTimes++; //2.初使化最佳值,最佳走法 int vlBest = -MATE_VALUE; int mvBest = 0; //3.生成走法,根据历史表排序 Moves mvs; generateMoves(mvs); //PrintMoves(mvs); qSort(mvs.begin(), mvs.end(), compareLessTan); //PrintMoves(mvs); //qDebug()<<"----------------------"; // 4. 逐一走这些走法,并进行递归 for(int i=0; i<mvs.count(); i++) { //列出走法 int pcCaptured; if (makeMove(mvs[i], pcCaptured)) { int vl = -alphaBetaSearch(depth - 1, -beta, -alpha); undoMakeMove(mvs[i], pcCaptured); //qDebug()<<mvString(mvs[i])<<" vl="<<vl; //进行Alpha-Beta大小判断和截断 if (vl > vlBest) { // 找到最佳值(但不能确定是Alpha、PV还是Beta走法) vlBest = vl; // "vlBest"就是目前要返回的最佳值,可能超出Alpha-Beta边界 if (vl >= beta) { // 找到一个Beta走法 mvBest = mvs[i]; // Beta走法要保存到历史表 break; // Beta截断 } if (vl > alpha) { // 找到一个PV走法 mvBest = mvs[i]; // PV走法要保存到历史表 alpha = vl; // 缩小Alpha-Beta边界 } } } } // 5. 所有走法都搜索完了,把最佳走法(不能是Alpha走法)保存到历史表,返回最佳值 if (vlBest == -MATE_VALUE) { // 如果是杀棋,就根据杀棋步数给出评价 return m_distance - MATE_VALUE; } //qDebug()<<"mvBest="<<mvBest<<" distance="<<m_distance; if (mvBest != 0) { // 如果不是Alpha走法,就将最佳走法保存到历史表 m_historyTable[mvBest] += depth * depth; if (m_distance==0) { // 搜索根节点时,总是有一个最佳走法(因为全窗口搜索不会超出边界),将这个走法保存下来 m_mvComputer = mvBest; } } return vlBest; }