negaMax算法产生一些奇怪的结果

时间:2015-12-03 02:33:03

标签: groovy artificial-intelligence 2d-games minimax negamax

我目前正在实施一个跳棋游戏,唯一让我回头的是我的AI状态不佳。它是用Groovy编写的。

我有以下(尝试过)使用alpha修正的negaMax算法。我已经跟踪了几个伪指南,但我显然在某个地方失败了,因为结果是相当荒谬的。

该方法调用如下:negaMax(3, Integer.MIN_VALUE, Integer.MAX_VALUE, 1)

我决定1将成为电脑玩家;其他任何东西都是用户。

def negaMax(int depth, int alpha, int beta, int player) {
    int score
    int bestScore = Integer.MIN_VALUE
    def moves = getMoves(player)                                        // this function returns a hashmap as I felt I needed not just the move but the checker
    // loop through all moves
    for (move in moves) {
        Position origin = move.key.location                             // save original position to allow undo
        move.key.location = move.value                                  // move piece
        if (depth == 0) {
            score = evaluateGameState(player)
        } else {
            score = -negaMax(depth - 1, -beta, -alpha, -player)         //  move score = - opponents best move
        }
        move.key.location = origin                                      // undo move
        if (player == 1) {                                              // save successor evaluations for the computer to search
            evaluations.put((move.key) , new PositionAndScore(score, move.value))
        }
        bestScore = Math.max(bestScore, score)
        alpha = Math.max(alpha, bestScore)
        if (alpha >= beta) {
            break                                                       // prune
        }
    }
    return bestScore
}

我选择了一个移动的哈希图,一个关键字作为检查器(Piece对象),值作为实际移动。我没有看到存储动作的任何意义,因为我需要跟踪实际上可以实现的动作。

我利用另一个哈希映射来存储后继评估,再次将检查器存储为密钥,但这次我存储了值的位置和位置分数(我为此创建了一个Class PositionAndScore)。 p>

evaluateGameState函数会初始化一个分数,表示该玩家可以移动多少个分数,为任何国王添加一个分数,并缩回任何一个分数位置的分数。

在玩的时候,前两个动作让电脑看起来很聪明,从那时起,它就会走下坡路。很多时候,计算机试图进行无效的移动,因此他们不会执行。

我非常感谢任何人给我的时间只是为了看看我到目前为止所做的事情并评论是否有任何突出的错误。

非常感谢。

编辑:好的我已经取得了一些进展。正如我可能没有提到的那样,evaluations hashmap用于计算最佳移动计算机。它获得了最高分。

这导致的问题是为玩家为1的每个循环添加了评估hashmap,因此添加了不合法的移动(即他们未来的移动)。

为了解决这个问题,我决定添加一个名为callSearch()的前体方法,该方法使用所有相同的参数调用而不是negaMax,但它也将rootDepth设置为depth的方法。 {1}}。

然后我对算法进行了这个小改动

if (player == 1 && depth == rootDepth) {

}

我的想法是,我只想在搜索返回到根目录后添加后续评估。

无论如何,完成所有这些后,计算机不再试图进行非法移动,但它仍然没有做出有效的动作。这可能是我的评价功能虽然有点简陋。

0 个答案:

没有答案