Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在基于时间的解决方案中,消除国际象棋中无趣/输线的最佳方法?_Java_Chess_Minimax - Fatal编程技术网

Java 在基于时间的解决方案中,消除国际象棋中无趣/输线的最佳方法?

Java 在基于时间的解决方案中,消除国际象棋中无趣/输线的最佳方法?,java,chess,minimax,Java,Chess,Minimax,我正在用Java创建一个国际象棋引擎作为练习,我知道由于速度问题,不建议使用它,但我只是为了练习 在使用alpha-beta修剪实现minimax后,我考虑实施一个时间限制来查找给定移动的分数 这是密码 private int minimax(MoveNode node, MoveNodeType nodeType, int alpha, int beta, Side side, int depth) throws Exception { // isInteresting

我正在用Java创建一个国际象棋引擎作为练习,我知道由于速度问题,不建议使用它,但我只是为了练习

在使用
alpha-beta修剪实现
minimax
后,我考虑实施一个时间限制来查找给定移动的分数

这是密码

    private int minimax(MoveNode node, MoveNodeType nodeType, int alpha, int beta, Side side, int depth) throws Exception {

//        isInterestingLine(prevscores, node, side);


        if (depth <= 0) {
            count++;
            return node.evaluateBoard(side);
        }
//         Generate Child nodes if we haven't.
        if (node.childNodes == null || node.childNodes.size() == 0) {
            node.createSingleChild();
        }

        if (nodeType == MoveNodeType.MAX) {
            int bestValue = -1000;
            for (int i = 0; i < node.childNodes.size(); i++) {
                if (node.childNodes.get(i) == null) continue;
                int value = minimax(node.childNodes.get(i), MoveNodeType.MIN, alpha, beta, side, depth - 1);
                bestValue = Math.max(bestValue, value);
                alpha = Math.max(alpha, bestValue);
                if (beta <= alpha) {
                    break;
                }
                node.createSingleChild();
            }
//            reCalculateScore();
            return bestValue;
        } else {
            int bestValue = 1000;
            for (int i = 0; i < node.childNodes.size(); i++) {
                if (node.childNodes.get(i) == null) continue;


                int value = minimax(node.childNodes.get(i), MoveNodeType.MAX, alpha, beta, side, depth - 1);
                bestValue = Math.min(bestValue, value);
                beta = Math.min(beta, bestValue);
                if (beta <= alpha) {
                    break;
                }
                node.createSingleChild();
            }
//            reCalculateScore();
            return bestValue;
        }
    } 
这就是我执行时间限制的方式

long time = System.currentTimeMillis();
moveEvaluator.evaluateMove(move, board.clone()); 
while((System.currentTimeMillis() - time) < secToCalculate*1000 && !moveEvaluator.minmaxThread.isAlive()) {
}
System.out.println("Time completed! score = " + moveEvaluator.bestMoveScore + " move  = " + move + " depth = " + moveEvaluator.searchDepth) ;
callback.callback(move, moveEvaluator.bestMoveScore);
但是,没有一个解决方案是完美和有效的,在第一个方案中,我们只是猜测,在第二个方案中,我们不止一次地计算一个节点


有更好的方法吗

每个国际象棋引擎使用的解决方案都是

不要搜索到一个固定的深度(在你的例子中是MAX_depth),你先搜索到一个深度,然后当这个搜索完成后,你再开始搜索两个深度,然后继续像这样增加深度,直到你没有时间为止。当您超时时,您可以播放上次完成搜索的移动

看起来很多时间都花在了较低深度的迭代上,这些迭代后来被更深入的搜索所取代,而且发送的时间完全丢失了,但实际上并非如此。由于搜索深度N比搜索深度N-1要长得多,因此,在较低深度搜索上花费的时间总是比在最后一次(较深)搜索上花费的时间少得多

如果您的引擎使用换位表,则来自上一次迭代的换位表中的数据将有助于后续迭代。alpha-beta算法的性能对搜索顺序非常敏感。当首先搜索最佳移动时,alpha-beta优于minimax节省的时间是最佳的。如果在搜索深度N之前搜索深度N-1,则换位表可能会包含对大多数位置的最佳移动的良好猜测,然后可以首先搜索这些位置


实际上,在使用换位表并基于上一次迭代在根位置排序移动的引擎中,使用迭代深化比不使用迭代深化更快。我的意思是,举例来说,先进行深度1搜索,然后进行深度2搜索,再进行深度3搜索,直到深度10搜索,比立即进行深度10搜索要快。此外,您还可以选择随时停止搜索,并且仍有移动游戏,=。

每个国际象棋引擎使用的解决方案都是

不要搜索到一个固定的深度(在你的例子中是MAX_depth),你先搜索到一个深度,然后当这个搜索完成后,你再开始搜索两个深度,然后继续像这样增加深度,直到你没有时间为止。当您超时时,您可以播放上次完成搜索的移动

看起来很多时间都花在了较低深度的迭代上,这些迭代后来被更深入的搜索所取代,而且发送的时间完全丢失了,但实际上并非如此。由于搜索深度N比搜索深度N-1要长得多,因此,在较低深度搜索上花费的时间总是比在最后一次(较深)搜索上花费的时间少得多

如果您的引擎使用换位表,则来自上一次迭代的换位表中的数据将有助于后续迭代。alpha-beta算法的性能对搜索顺序非常敏感。当首先搜索最佳移动时,alpha-beta优于minimax节省的时间是最佳的。如果在搜索深度N之前搜索深度N-1,则换位表可能会包含对大多数位置的最佳移动的良好猜测,然后可以首先搜索这些位置

实际上,在使用换位表并基于上一次迭代在根位置排序移动的引擎中,使用迭代深化比不使用迭代深化更快。我的意思是,举例来说,先进行深度1搜索,然后进行深度2搜索,再进行深度3搜索,直到深度10搜索,比立即进行深度10搜索要快。此外,您还可以选择随时停止搜索,并且仍有移动游戏,=

long time = System.currentTimeMillis();
moveEvaluator.evaluateMove(move, board.clone()); 
while((System.currentTimeMillis() - time) < secToCalculate*1000 && !moveEvaluator.minmaxThread.isAlive()) {
}
System.out.println("Time completed! score = " + moveEvaluator.bestMoveScore + " move  = " + move + " depth = " + moveEvaluator.searchDepth) ;
callback.callback(move, moveEvaluator.bestMoveScore);