2

我正在尝试为井字游戏应用程序实现 negamax 搜索功能,但它不会返回最佳值,而是似乎是半随机猜测的。这是我的代码的相关部分:

public int negamax(Result result, Token token) {
    if (result == Result.WIN) {
        return 1;
    } else if (result == Result.DRAW) {
        return 0;
    }

    int best = -1;

    for (Coordinate move : Board.getAvailableMoves()) {
        Token other = token.getOther();
        Result r = Board.makeMove(move, other);
        int eval = -negamax(r, other);
        Board.unmakeMove(move);

        if (eval > best) {
            best = eval;
        }
    }

    return best;
}

public Coordinate getNegamaxMove(Token token) {
    int score = -1;
    Coordinate bestMove = null;

    for (Coordinate move : Board.getAvailableMoves()) {
        Result result = Board.makeMove(move, token);
        int newScore = negamax(result, token);
        Board.unmakeMove(move);

        if (newScore >= score) {
            score = newScore;
            bestMove = move;
        }
    }

    return bestMove;
}

需要注意的是,我没有将棋盘作为参数传递,而是将棋局的结果作为参数传递,可以是 WIN、DRAW、VALID 或 OCCUPIED(最后 2 个与当前讨论无关),这些都是不言自明。Coordinate 类只保存移动的行和列值。

非常感谢 :)

4

1 回答 1

2

我已经设法让它工作了,negamax 方法有两个问题。首先,令牌应该在循环所有可用动作之前更改,而不是在循环内部。其次,由于我在 getNegamaxMove 方法中检查最佳移动,在 negamax 方法中,我必须跟踪最差移动而不是最佳移动。这是旧部分注释掉以进行比较的工作实现:

public int negamax(Result result, Token token) {
    if (result == Result.WIN) {
        return 1;
    } else if (result == Result.DRAW) {
        return 0;
    }

    int worst = 1;
    // int best = -1

    Token other = token.getOther();
    for (Coordinate move : Board.getAvailableMoves()) {
        // Token other = token.getOther();
        Result r = Board.makeMove(move, other);
        int eval = -negamax(r, other);
        Board.unmakeMove(move);

        // if (eval > best) {
        //     best = eval;
        // }

        if (eval < worst) {
            worst = eval;
        }
    }

    // return best
    return worst;
}
于 2015-05-17T12:29:01.283 回答