Минимаксная логика алгоритма выдачи неожиданных результатов - PullRequest
1 голос
/ 07 апреля 2019

Я делаю минимаксный алгоритм для простого шахматного движка, но столкнулся с некоторыми трудностями. Я бегал по своему коду в течение нескольких часов и безрезультатно, он, похоже, все еще выдает неправильные результаты; когда я угрожаю одной из его фигур, и у нее есть верный ход, который спасет эту фигуру, он игнорирует этот ход.

Ниже я максимально упростил код метода минимаксного алгоритма, чтобы попытаться показать, чего я пытался достичь, и, надеюсь, сделать ошибку видимой. Первоначально вызывается с минимаксом (2, true);

public static int[] minimax(int depth, boolean max) {
    int piece = 0;
    int square = 0;
    int boardScore = 0;
    int bestScore = -9999;
    if (!max) {
        bestScore = 9999;
    }
    for (int a = 0; a < 64; a++) {
        for (int b = 0; b < 64; b++) {
            boardScore = 0;
            boolean valid = false;
            if (max) {
                valid = Board[a].validate(b, aiColor);
            } else {
                valid = Board[a].validate(b, playerColor);
            }

            if (valid) {
                storePosition(depth-1);
                if (max) {
                    Board[a].move(b,aiColor);
                } else {
                    Board[a].move(b,playerColor);
                }

                boardScore = calculateScore();
                if (depth != 1) {
                    if (max) {
                        int[] minimaxArray = minimax(depth-1, false);
                        boardScore = minimaxArray[2];
                    } else {
                        int[] minimaxArray = minimax(depth-1, true);
                        boardScore = minimaxArray[2];
                    }

                }
                if (boardScore > bestScore && max) {
                    piece = a;
                    square = b;
                    bestScore = boardScore;
                }
                if (boardScore < bestScore && !max) {
                    piece = a;
                    square = b;
                    bestScore = boardScore;
                }
                resetPosition(depth-1);
            }

        }
    }
    int[] returnVars = new int[3];
    returnVars[0] = piece;
    returnVars[1] = square;
    returnVars[2] = bestScore;
    return returnVars;
}

Я уверен, что другие методы работают отлично, так как move () просто меняет фигуру, validate () работает правильно, когда работает, когда отображает все ходы, которые может сделать игрок, возбуждаетScoreScore (), поскольку он просто подсчитывает количество экземпляров и суммирует баллы в зависимости от их цвета. (Если ai впереди коня, счет будет равен 3; если игрок впереди пешки, счет будет -1).

Программа, похоже, все еще не следует логике, которой я хотел бы ее придерживаться, и не отодвигает свои части под угрозой. Например, я переместил пешку, чтобы она могла забрать рыцаря бота, и он не смог отодвинуть коня.

Это один из примеров ее ошибок, и заставляет меня поверить, что в моей логике есть проблема с вычислением лучшего хода / его рекурсии, который выполняется неправильно, однако это может быть методScoreScore (), поэтому я добавлю и это.

public static int calculateScore() {
    int boardScore = 0;
    for (int c = 0; c < 64; c++) {
        if (Board[c].color.equals(aiColor)) {
            boardScore += Board[c].points;
        } else {
            boardScore -= Board[c].points;
        }
    }
    return boardScore;
}

1 Ответ

0 голосов
/ 08 апреля 2019

Оказывается, эта ошибка не была проблемой с логикой, а вместо этого была проблемой с моими методами, даже после того, как я сказал: «Я уверен, что другие методы работают отлично». Оказалось, что проблема была в проверке перемещения деталей.

В шахматах есть неясное правило «en passant», когда пешка, которая только что двинулась вперед, действует на два действия иначе, чем та, которая не была просто сдвинута вперед на две клетки. По этой причине у меня был класс для этих фигур и я заменил их экземпляры обычными пешками в конце обычного хода, однако, поскольку эти тестовые ходы не были обычными ходами, он не удалял MoveTwoPawn и думал, что он не может двигаться , как и в обычной игре, MoveTwoPawn никогда не может быть перемещен.

Чтобы исправить эту проблему, я добавил замену перемещенных двух пешек на обычные пешки, и она отлично работает.

...