Moves MoveGenerator::generateOpening(const Board& board) const { Moves result; if(board.getIdleCount() == 0) { QMessageBox::critical(0, "error", "idle == 0"); return result; } for(int i=0; i<23; ++i) { if(board.isEmpty(i)) { Board next = board.makeChild(); // a clone next.setManAt(i, board.getSelfColor()); if(next.closeMill(i)) { Moves removeMoves = generateRemove(next, board.getOpponentColor()); // remove 1 opponent chessman copy(removeMoves.begin(), removeMoves.end(), back_inserter(result)); } else result.push_back(next); } } return result; }
/*-----------------------------------------------------------------------------*/ void Notation::DeleteBranch(int no) { MoveKif* move = this->move_current_; // 一旦カレントに対する操作にしておく Moves* moves = this->current_moves_; int num = this->number(); if (no == -1) { int pos = num - (*moves)[0].number(); // 次の要素から最後までを削除 moves->erase(moves->begin() + pos + 1, moves->end()); if (move->branches().size() != 0) { // ブランチをずらす moves->insert(moves->end(), move->branches()[0]->begin(), move->branches()[0]->end()); move->DeleteBranch(0); } } else { move->DeleteBranch(no); } }
void ConsoleManager::showMoves() const { Moves moves; MoveGenerator::generate(record_.getBoard(), moves); for (auto ite = moves.begin(); ite != moves.end(); ite++) { if (record_.getBoard().isValidMoveStrict(*ite)) { std::cout << ite->toString() << ' '; } } std::cout << std::endl; }
Move bestMove(const Moves& moves) { if (!moves.empty()) { return *min_element(moves.begin(), moves.end()); } else { return Move(Cost::infinity()); } }
void build_path(ull_t v, const Searched & searched, Moves & steps) { Searched::const_iterator it = searched.find(v); while (it != searched.end()) { const State & s = it->second; steps.push_back(s.step); it = searched.find(s.parent); } //pop up the first step, which must be 0, rather than one of U,D,L,R steps.pop_back(); reverse(steps.begin(), steps.end()); }
/*-----------------------------------------------------------------------------*/ void Notation::AddBranch(const Moves& src_moves) { Moves* dest_moves = this->current_moves_; // 一旦カレントで作成 MoveKif* dest_move = this->move_current_; const MoveKif& last_move = dest_moves->back(); if (&last_move == dest_move) { // 追加先が末尾の場合 dest_moves->insert(dest_moves->end(), src_moves.begin(), src_moves.end()); } else { // 追加先が途中の場合 dest_move->AddBranch(dest_moves, src_moves); } }
Moves MoveGenerator::generateHopping(const Board& board) const { Moves result; for(int from=0; from<23; ++from) if(board.getManAt(from) == board.getSelfColor()) { for(int to=0; to<23; ++to) if(board.isEmpty(to)) { Board next = board.makeChild(); next.move(from, to); if(next.closeMill(to)) { Moves removeMoves = generateRemove(next, board.getOpponentColor()); copy(removeMoves.begin(), removeMoves.end(), back_inserter(result)); } else result.push_back(next); } } return result; }
Moves MoveGenerator::generateMove(const Board& board) const { Moves result; for(int from=0; from<23; ++from) if(board.getManAt(from) == board.getSelfColor()) { Neighbors neighbors = Board::getNeighbors(from); for(Neighbors::iterator it = neighbors.begin(); it != neighbors.end(); ++it) if(board.isEmpty(*it)) { Board next = board.makeChild(); next.move(from, *it); if(next.closeMill(*it)) { Moves removeMoves = generateRemove(next, board.getOpponentColor()); copy(removeMoves.begin(), removeMoves.end(), back_inserter(result)); } else result.push_back(next); } } return result; }
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; }