【问题标题】:How to get actual move rather than move value from mini max algorithm如何从最小最大算法中获得实际移动而不是移动值
【发布时间】:2014-09-10 06:29:13
【问题描述】:

我目前正在为 Chess 编写一个带有 alpha beta 剪枝的 minimax 算法。

从我看到的所有示例中,minimax 算法将返回一个 int 值,该值表示最佳得分或最佳棋局将产生的棋盘状态。

我的问题是我们如何返回与得分返回值相关的最佳移动?

例如,我在伪下面的alphabeta() ...

public int alphabeta(int depth, Board b, int alpha, int beta, boolean maxPlayer) {
    if(depth == 0)
        return evaluateBoard(b);
    if(maxPlayer) {
        for(each of max player's moves) {
            // make move on a tempBoard
            int eval = alphabeta(depth - 1, tempBoard, alpha, beta, false);
            alpha = Math.max(alpha, eval);
            if(beta <= alpha) 
                break;
        }
        return alpha;
    }
    else {
        for(each of min's moves) {
            // make move on a tempBoard
            int eval = alphabeta(depth - 1, tempBoard, alpha, beta, true);
            beta = Math.min(beta, eval);
            if(beta <= alpha)
                break; 
        }
        return beta;
    }
}

在我的 minimax/alphabeta 实现中,我有一个 Board 对象,它代表棋盘,棋子可以在其上移动以代表不同的棋盘纹理/游戏状态。

我的函数evaluateBoard(Board b) 接收一个Board 并计算参数Board 的board state 值。

从本质上来说,evaluateBoard() 为我提供了作为最佳移动值的 alphabeta() 的最终 int 结果值。但是,我看不到 evaluateBoard() 返回导致最终得分的移动的方法。即使我要返回一些包含分数值和片段信息的对象,我也不确定如何在树的顶部获得给我最终最佳分数的片段的信息。

有谁知道我如何访问/返回给出最佳得分值的最佳动作的信息? 我是否遗漏了 mini max 算法中的一个关键元素和/或我是否必须以不同的方式实现 alphabeta()?

编辑:

例如,假设 minimax 从以下移动中返回最佳分数: e4、e5、nf3、nc6。我所拥有的将返回棋盘情况的数值。我怎样才能返回“e4”? E4 是导致最高值的移动。

谢谢。

【问题讨论】:

    标签: algorithm chess minimax alpha-beta-pruning


    【解决方案1】:

    极小极大算法通过探索可能移动的树来工作,即使您没有明确使用树。因此,除了它的值之外,您的函数所需要的只是返回最佳移动。

    你可以这样做:

    ScoredMove alphabeta(Board board, String player, Move move) {
      board.applyMove(move);
      if (board.gameOver())
      {
        score = board.scoreForPlayer(player);
        return ScoredMove(score, move);
      }
    
      if (player == "player1") {
        next_player = "player2";
      } else {
        next_player = "player1";
      }
    
      ScoredMove best_move = null;
      for (next_move in board.movesForPlayer(next_player)) {
        ScoredMove scored = alphabeta(board, next_player, next_move)
        if (best_move == null || best_move.score < scored.score) {
          best_move = scored;
        }
      }
      board.removeMove(move);
      return best_move;
    }
    

    【讨论】:

    • 我的实现在技术上并不使用树。例如,如果我将深度设置为 2:我查看最大的每一步,在临时板上播放该移动并将该板传递给下一个字母表调用。下一次对alphabeta的调用将根据max在通过的棋盘上的移动来查看min的每一个移动。基本上,对于每个对字母表的调用,我都会在板上进行移动并向前移动。我不确定你想用 ScoredMove(evaluateBoard(board), last_move) 传达什么。假设从极小值产生的最佳值是:e4、e5、nf3、nc6。如何返回e4?
    • 树是游戏的不同方式。因此,假设您通过了棋盘并且有 2 个动作:e3、e4。因此,您将移动 e3 应用于您的棋盘并在其上调用字母表。 Alphabeta 返回一个包含分数和一些后续移动的对象。因此,您跟踪 e3 和分数,然后尝试使用 e4。您会看到 e4 “更好”。因此,您丢弃 e3 和分数,然后返回 e4 及其分数,因为 e4 是最好的移动。这有意义吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多