【问题标题】:How to improve performance of Minimax for Chess.js?如何提高 Chess.js 的 Minimax 的性能?
【发布时间】:2018-05-27 14:27:24
【问题描述】:


我正在尝试使用带有 alpha-beta 修剪的 Minimax 算法使用 Chess.js 和 Chessboard.js 编写国际象棋引擎。问题是算法需要很长时间才能执行所有评估并决定采取的行动,即使使用depth=3。如何加快性能?

以下是我的极小极大实现:

var minimax = function (depth, game, alpha, beta, isAIplaying) {

  // end branch: simply evaluate and return the current score of the board
  if (depth === 0) {
    return evaluateBoard(game);
  }

  // list of all the possible moves in current status
  var newGameMoves = game.moves();
  if (isAIplaying) {
      var bestMove = -9999;
      for (var i = 0; i < newGameMoves.length; i++) {
          game.move(newGameMoves[i]);
          bestMove = Math.max(bestMove, minimax(depth - 1, game, !isAIplaying));
          game.undo();
          alpha = Math.max(alpha, bestMove);
          if (beta <= alpha) {
            return bestMove;
          }
      }
      return bestMove;
  } else {
      var bestMove = 9999;
      for (var i = 0; i < newGameMoves.length; i++) {
          game.move(newGameMoves[i]);
          bestMove = Math.min(bestMove, minimax(depth - 1, game, !isAIplaying));
          game.undo();
          beta = Math.min(beta, bestMove);
          if (beta <= alpha) {
           return bestMove;
          }
      }
      return bestMove;
  }
};

该函数在以下代码和平中被调用,黑方必须决定采取哪一步:

var possibleMoves = game.moves(); 

// game over
if (possibleMoves.length === 0) 
  return;

var best_score = -9999;
var bestMoveFound;

for(var i=0; i<possibleMoves.length; ++i){
  game.move(possibleMoves[i]); // make one possible move

   // minimax: take the current status of the game
  // it is not Black's turn
  var score = minimax(3, game, -10000, 10000, false);

  // if I get a better score then I store it
  if(score >= best_score){
    best_score = score;
    bestMoveFound = i;
  }

  // undo move
  game.undo();
}

// make the best move (update both the game and the board on the screen)
game.move(possibleMoves[bestMoveFound]);
board.position(game.fen());

下面是评估函数:

var evaluateBoard = function(current_game) {
    var status = current_game.fen();

    var score = 0;

    // calculate score for the current situation
    var fen_idx = 0;
    var piece = status[fen_idx];
    while(piece != ' '){
      switch(piece){
        case 'p': score += pawn; break;
        case 'n': score += knight; break;
        case 'b': score += bishop; break;
        case 'r': score += tower; break;
        case 'q': score += queen; break;
        case 'k': score += king; break;
        case 'P': score -= pawn; break;
        case 'N': score -= knight; break;
        case 'B': score -= bishop; break;
        case 'R': score -= tower; break;
        case 'Q': score -= queen; break;
        case 'K': score -= king; break;
        default: break;
      }

      ++fen_idx;
      piece = status[fen_idx];
    }

    return score;
};

pawnbishop 和其他都是简单的常量,p 表示黑色棋子,P 表示白色棋子。你有什么提高性能的想法吗?

【问题讨论】:

    标签: javascript chess chessboard.js


    【解决方案1】:

    评估 FEN-String 的想法看起来很快,但是您的程序必须为博弈树的每个叶子计算一个 FEN-String。这真的很慢,因为它必须在 64 个方格上循环扫描棋盘上的每个图形以及棋盘的每个空方格。您不应该这样做,而是将板上的数字保存在一个列表中,以便计算源代码的模拟量。

    如果棋盘上的棋子被取走或替换,最好将所有的和解加起来,然后只加或减一个值。所以你的评估函数中没有计算,你的引擎会更快。根据我的经验,如果您的评估功能只是比较两侧的块值,您应该在

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 2021-10-13
      • 2018-03-01
      • 2020-04-28
      • 2014-09-22
      • 2010-11-04
      相关资源
      最近更新 更多