找不到NegaMax实现java国际象棋游戏的bug

时间:2014-12-15 23:49:54

标签: java tree chess

我无法识别我的negamax(alpha-beta)实现中的错误。

我可以使简单的negamax版本工作正常,但我无法将其转换为其alpha-beta版本的negaMax。

首先是正在运行的简单的negaMax版本......

public class NegaMax {

    static Node bestNode = null;
    public static final Node getMove(Node root, boolean maximizingPlayer) {
        bestNode = null;
        int score = maximizingPlayer 
                  ? negaMax(root, 4, maximizingPlayer)
                  : negaMax(root, 4, !maximizingPlayer);

        if(bestNode != null) {
            bestNode.score = score;
        }
        return bestNode;
    }

    private static final int evaluate(Node node, boolean maximizingPlayer) {
        return Integer.parseInt(node.value) * (maximizingPlayer ? 1 : -1);
    }

    private static final int negaMax(Node node, int depthLeft, boolean maximizingPlayer) {
        if(depthLeft == 0) { 
            return evaluate(node, maximizingPlayer);
        }

        int max = Integer.MIN_VALUE;
        Node bestChildSoFar = null;
        List<Node> children = node.getChildren();

        for(Node child : children) {
            int score = -negaMax(child, depthLeft - 1, !maximizingPlayer);
            if(score > max) {
                bestChildSoFar = child;
                max = score;
            }
        }
        bestNode = bestChildSoFar;
        return max;
    }    

...这里的版本不是......(返回-INFINITY) - (来自chessprogrammingwiki的源代码创意)......

public class AlphaBetaNegaMax {

    public static final Node getMove(Node root, boolean maximizingPlayer) {
        int score = maximizingPlayer
                  ? alphaBeta(root, Integer.MIN_VALUE, Integer.MAX_VALUE, 4, maximizingPlayer)
                  : alphaBeta(root, Integer.MIN_VALUE, Integer.MAX_VALUE, 4, !maximizingPlayer);

        System.out.println(score);

        return null;  // score is wrong ... fix this first
    }

    private static final int evaluate(Node node, boolean isMaximizingPlayer) {
        return Integer.parseInt(node.value) * (isMaximizingPlayer ? 1 : -1);
    }

    private static final int alphaBeta(Node node, int alpha, int beta, int depthleft, boolean maximizingPlayer) {
        if(depthleft == 0) {
            return evaluate(node, maximizingPlayer);
        }

        List<Node> children = node.getChildren();
        for(Node child : children) {
            int score = -alphaBeta(child, -beta, -alpha, depthleft - 1, !maximizingPlayer);
            if(score >= beta) {
                return beta;
            }
            if(score > alpha) {
                alpha = score;
            }
        }
        return alpha;
    }
}

2 个答案:

答案 0 :(得分:1)

编辑:

问题是你没有抓住移动设置,整个4个深度移动设置,即最低移动设置为板上的每个部分深4个然后决定哪个用于最低成本的第一个移动设置,你只能找到最低的移动,在某些情况下可以是第二,第三或第四移动。如果返回该移动,则没有可能的方法来实际完成移动,因为您没有捕获到前面的移动板。

private static final int INF = Integer.MAX_VALUE;
private static final int DEPTH = 4;
private Move[] best4depthmove = new Move[DEPTH];
private int[] score4deep = new int[DEPTH];

public static final Move getMove(Move previous) {
    for(int x = 0; x < DEPTH; x++)
    {
        best4depthmove[x] = null;
        score4deep[x] = 0;
    }

    negamax(previous, 0);

    return best4depthmove[0];
}

private static final negamax(Move move, int depth) 
{
     int newscore = 0;

    if(depth < DEPTH) 
    {
        List<Move> moves = Engine.getMoves(move);
        for(Move m : moves) 
        {
             newscore = MoveEvaluators.evaluate(m);
             if(newscore > score4deep[depth])
             {
                 score4deep[depth] = newscore;
                 best4depthmove[depth] = m;
             }
             negamax(m, depth+1);

        }
    }
}

这是我能想到的全部,它应该递归地完成每一个可能的动作。只要你有足够的内存容量来处理递归调用,这就可能适用于任何深度。

答案 1 :(得分:0)

我发现了这个错误,这个很微妙......问题是我假设Math.MIN_VALUE和Math.MAX_VALUE的绝对值都相同,忘记了java如何用2表示整数称赞

我刚刚将INFINITY定义为9999999,并将阳性和负无穷大都称为对称值,并且它起作用(alpha和beta的交换是这些值必须对称或我们看到这个错误的地方)

我认为网络上的这个小程序有一个类似的问题:http://ksquared.de/gamevisual/launch.php(我通知了作者,他回复说。他确实他有完全相同的错误!)