迭代加深搜索和5秒钟的alpha-beta修剪停止时间的minimax

时间:2018-10-23 19:14:36

标签: java artificial-intelligence

我必须制作一个kalaha AI,它使用带有迭代加深的Alpha beta修剪,并且时间限制为5秒。不能正常工作... 当它完成时,depthCount会非常​​深,但不应(例如15000)。...我在末尾添加了一个图像来显示此问题

sonmeone可以帮我吗?

public int minimaxIDAlphaBeta(GameState currentBoard, int maxPlayer, boolean isMax, boolean isMin, int alpha, int beta) {
    int bestMove = 0;
    int depthCount = 1;
    int value = 0;
    Integer maxValue = Integer.MIN_VALUE;
    start_time = 0;
    time_exceeded = false;
    elapsed_time = 0;

    if (!currentBoard.gameEnded()) {
        start_time = System.currentTimeMillis();

        while (!time_exceeded) {
            elapsed_time = System.currentTimeMillis() - start_time;
//                GameState newBoard = currentBoard.clone();

            if (elapsed_time > timeLimit) {
                //System.out.println("time out: " + elapsedTime / 1000F + ", and depth count: " + depthCount);
                time_exceeded = true;
                break;
            } else {
//                    if (newBoard.gameEnded()) {
//                        return bestMove;
//                    }

                for (int i = 2; i <= 25 ; i++) //for (int i = 1; elapsed_time < timeLimit ; i++)
                {
                    value = MinimaxIterativeDeepeningAlphaBeta(currentBoard, 1, maxPlayer, isMax, isMin, i, alpha, beta, start_time, time_exceeded);
                    if (value > maxValue) {
                        bestMove = value;
                    }
                    if (elapsed_time >= timeLimit) {
                        System.out.println("depth count: " + i);
                        System.out.println("best move: " + bestMove + ", elapsed time: " + elapsed_time / 1000F);
                        break;
                    }
                }
            }
        }
    }
    return bestMove;
}

[![enter image description here][1]][1]
public int MinimaxIterativeDeepeningAlphaBeta(GameState currentBoard, int currentDepth, int maxPlayer, boolean isMax, boolean isMin, int maxDepth, int alpha, int beta,long start_time,boolean exceeded_time) {
    int depth = maxDepth;
    int value = 0;
    Integer maxValue = Integer.MIN_VALUE;
    Integer minValue = Integer.MAX_VALUE;
    int bestMove = 0;

    //get elapsed time in milliseconds
    elapsed_time = System.currentTimeMillis() - start_time;

    //if elapsed time is larger than maximum time limit, then stop searching
    if (elapsed_time > timeLimit) {
        time_exceeded = true;
    }

    //if time is not exceeded 5 sec
    if (!time_exceeded) {

        //if the game is ended or we hit a terminal node, return the maxPlayer score
        if (currentBoard.gameEnded() || currentDepth == depth || time_exceeded == true) {
            if (maxPlayer == 1) {
                return currentBoard.getScore(1) - currentBoard.getScore(2);
            } else {
                return currentBoard.getScore(2) - currentBoard.getScore(1);
            }
        }

        //check to see if it's max turn
        if (isMax) {
            for (int i = 1; i < 7; i++) {

                //check to see if move is possible or not
                if (currentBoard.moveIsPossible(i)) {

                    //copy the current board in each iteration
                    GameState newBoard = currentBoard.clone();
                    newBoard.makeMove(i);

                    //check to see if the next player is max again or not...if it's next turn is max again set isMax true and isMin false...
                    if (newBoard.getNextPlayer() == maxPlayer) {
                        isMax = true;
                        isMin = false;
                    } else {
                        isMax = false;
                        isMin = true;
                    }

                    if (isMax) {
                        //if it's max turn it will excute this recursive function 
                        value = MinimaxIterativeDeepeningAlphaBeta(newBoard, currentDepth + 1, maxPlayer, isMax, isMin, maxDepth, alpha, beta,start_time,exceeded_time);
                    } else {
                        //if it's min turn it will excute this recursive function
                        value = MinimaxIterativeDeepeningAlphaBeta(newBoard, currentDepth + 1, maxPlayer, isMax, isMin, maxDepth, alpha, beta,start_time,exceeded_time);
                    }

                    //if the value is greater than the max value, it will store the value in max value and the i as the best move
                    if (value > maxValue) {
                        maxValue = value;
                        bestMove = i;
                    }

                    //if maximum value is larger than alpha value, then store maximum value as alpha value
                    if (maxValue > alpha) {
                        alpha = maxValue;
                    }

                    //if the alpha value is larger than beta value, then stop the iteration
                    if (beta <= alpha) {
                        break;
                    }
                }
            }

            //as long as the depth is greater than 1 we want to calculate the best value and return, but when the current depth is 1 we want to return the best move instead of best value
            if (currentDepth != 1) {
                bestMove = maxValue;
            }
        } else {    //if it is min turn it will go through the else 
            for (int i = 1; i < 7; i++) {
                if (currentBoard.moveIsPossible(i)) {

                    //copy the current board in each iteration
                    GameState newBoard = currentBoard.clone();
                    newBoard.makeMove(i);

                    //check to see if the next player is min again or not...if it's next turn is min again set isMin true and isMax false...
                    if (newBoard.getNextPlayer() != maxPlayer) {
                        isMax = false;
                        isMin = true;
                    } else {
                        isMax = true;
                        isMin = false;
                    }

                    if (isMin) {
                        //if it's min turn it will excute this recursive function
                        value = MinimaxIterativeDeepeningAlphaBeta(newBoard, currentDepth + 1, maxPlayer, isMax, isMin, maxDepth, alpha, beta,start_time,exceeded_time);
                    } else {
                        //if it's max turn it will excute this recursive function
                        value = MinimaxIterativeDeepeningAlphaBeta(newBoard, currentDepth + 1, maxPlayer, isMax, isMin, maxDepth, alpha, beta,start_time,exceeded_time);
                    }

                    //if the value is less than the min value, it will store the value in min value and the i as the best move
                    if (value < minValue) {
                        minValue = value;
                        bestMove = i;
                    }

                    //if minimum value is smaller than beta value, then store minimum value as beta value
                    if (minValue < beta) {
                        beta = minValue;
                    }

                    //if the beta value is smaller than alpha value, then stop the iteration
                    if (beta <= alpha) {
                        break;
                    }
                }
            }

            //as long as the depth is greater than 1 we want to calculate the best value and return, but when the current depth is 1 we want to return the best move instead of best value
            if (currentDepth != 1) {
                bestMove = minValue;
            }
        }
    }


    //when the current depth equals to 1 it will return the best move 
    return bestMove;
}

depthCount of the last 3 moves

enter image description here

1 个答案:

答案 0 :(得分:0)

问题

考虑第一个函数minimaxIDAlphaBeta中的迭代加深循环:

if (currentBoard.getWinner() > -1) {
    return bestMove;
}

for (int i = 1; currentBoard.getWinner() == -1; i++) //for (int i = 1; elapsed_time < timeLimit ; i++)
{
    value = MinimaxIterativeDeepeningAlphaBeta(currentBoard, 1, maxPlayer, isMax, isMin, i, alpha, beta, start_time, time_exceeded);
    // code omitted for clarity
    if (elapsed_time >= 4999) {
        // code omitted for clarity
        break;
    }
}

并考虑第二个功能的alpha beta搜索:

public int MinimaxIterativeDeepeningAlphaBeta(GameState currentBoard, int currentDepth, int maxPlayer, boolean isMax, boolean isMin, int maxDepth, int alpha, int beta,long start_time,boolean exceeded_time) {
    // code omitted for clarity

            for (int i = 1; i < 7; i++) {

                //check to see if move is possible or not
                if (currentBoard.moveIsPossible(i)) {

                    //copy the current board in each iteration
                    GameState newBoard = currentBoard.clone();
                    newBoard.makeMove(i);

                    // code omitted for clarity
                }
            }

    // code omitted for clarity
}

每个动作都是在游戏状态的克隆上进行的,这是正确的,因为在退出alpha-beta功能之前必须将动作反向。 但是,在迭代加深循环中,仅询问原始游戏状态游戏是否结束(并且对于原始游戏状态,游戏永不结束!)。 因此,循环将一直运行,直到达到时间限制为止。

可能的解决方案

通常,两个中止条件用于迭代加深:

  • 达到最大深度(此深度缺失)和
  • 超时

一旦找到终端状态,立即终止搜索是错误的,因为您可能会发现更好的举动,并具有更大的搜索深度限制。