Шахматная альфа-бета возвращает неверный ход на доске

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

Например, может произойти следующее.

Белые (пользователь) для хода, позиция белого короля - a1 / Черные (компьютер), позиция черного короля - h1

Белые ходят королем с a1 - a2, затем черные возвращают ход g2 - g1???

Пример

Похоже, что компьютер возвращает ход для неверного узла (представления на доске), как будто наилучшая оценка данной позиции на доске не распространяется на весь обратный путь вверх по дереву. Таким образом, в одной из исследованных смоделированных позиций компьютер «воображает», что его король движется на g2, а затем возвращает ход, который нужно сделать из этой позиции, не понимая, что эта позиция является смоделированной позицией, а не представлением реальной доски (т. корневой узел?).

Как мне исправить код, чтобы компьютер возвращал ход для фактического представления доски, а не для одной из симуляций по ошибке?

Спасибо.

Первоначальный звонок alphaBeta(3, ChessEngine.invertBoard(ChessEngine.board), -10000, 10000, true);

private static int alphaBetaEvaluate = 0;
private static int alphaBetaSelectedSquare = 0;
private static int alphaBetaMoveToSquare = 0;
public static int alphaBeta(int depth, char[] board, int alpha, int beta, boolean maxPlayer) {

    //create a copy of the board
    char[] boardCopy = board.clone();

    //if terminal state has not been met, keep searching
    if (maxPlayer == true && depth > 0) {

        //for all of the moves that max can make
        for (int i = 0; i < board.length; i++) {
            for (int move : ChessEngine.getValidMoves(i, boardCopy)) {

                //make the move
                boardCopy[move] = boardCopy[i];
                boardCopy[i] = '.';

                alphaBetaEvaluate = rating(board, boardCopy, i, move);

                //store the best move to make
                int temp = alphaBeta(--depth, ChessEngine.invertBoard(boardCopy), -10000, 10000, false);
                if (temp > alpha) {
                    alphaBetaSelectedSquare = i;
                    alphaBetaMoveToSquare = move;           
                    alpha = temp;
                }

                //reset the board for the next simulated move
                boardCopy = board.clone();

                if (beta <= alpha) {
                    break;
                }
            }
        }
        return alpha;
    } else if (maxPlayer == false && depth > 0) {

        //for all of the moves that min can make
        for (int i = 0; i < board.length; i++) {
            for (int move : ChessEngine.getValidMoves(i, boardCopy)) {

                //make the move
                boardCopy[move] = boardCopy[i];
                boardCopy[i] = '.';
                beta = Math.min(beta, alphaBeta(--depth, ChessEngine.invertBoard(boardCopy), -10000, 10000, true));

                //reset the board for the next simulated move
                boardCopy = board.clone();

                if (beta <= alpha) {
                    break;
                }
            }
        }
        return beta;
    }
    return alphaBetaEvaluate;
}

person user1334130    schedule 13.02.2015    source источник
comment
Вы проверили, правильно ли работает ваш алгоритм рейтинга? Было бы целесообразно вручную проверить значение, которое он возвращает для каждой из возможных позиций в ситуации с двумя королями. Я полагаю, что алгоритму будет сложно различать позиции (учитывая, что нет выигрышной стратегии с двумя королями на доске).   -  person sprinter    schedule 13.02.2015
comment
Еще одно предложение по отладке, которое у меня есть, - изменить алгоритм оценки на что-то искусственное и простое, например, расстояние от края. Это способ исключить возможность ошибки рейтинга - если короли все еще повторяют ходы, вы знаете, что альфа-бета должна быть ошибкой.   -  person sprinter    schedule 13.02.2015
comment
Привет, спринтер, я только что скорректировал рейтинг, чтобы учитывать только позицию, в которую движется король, но он все равно вернул g2 - g1. Я уверен, что это альфа-бета-проблема, но я до сих пор не уверен, в чем проблема...   -  person user1334130    schedule 14.02.2015


Ответы (1)


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

Таким образом, переворачивание доски не кажется мне столь разумным, если вы не знаете, что оценка, которую вы делаете в отношении ситуации, корректна.

Еще одна серьезная проблема для меня заключается в том, что вы всегда называете минимум/максимум для следующего хода с -10k и 10k в качестве границ для альфы и беты. Таким образом, ваш алгоритм не «учится» на предыдущих ходах.

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

Я не эксперт в этом. несколько десятилетий назад, когда я написал свою реализацию, я использовал что-то другое.

Другая идея состоит в том, чтобы не использовать min и max в одном и том же методе, а вместо этого использовать методы min и max. Это повышает вероятность того, что вы обнаружите другие дефекты.

Также не используйте двух королей для оценки. В этом нет цели. Два короля случайны, победить невозможно. Одно дело может быть два коня или четыре ферзя и тому подобное. Это не так случайно, и вы можете видеть, как королевы танцуют, но не могут поймать друг друга. Или используйте трех рыцарей против одного ферзя.

И попробуйте создать несколько модульных тестов для других ваших частей. Просто чтобы убедиться, что части работают правильно независимо друг от друга. И почему вы используете символы? Почему бы не использовать перечисления или объекты. Вы можете повторно использовать объекты для каждого поля (это больше похоже на цифры).

Но в любом случае это стиль, а не корректность алгоритма.

person Martin Kersten    schedule 21.02.2015
comment
Ура, ответ :) Изменение вызова функции alphabeta для использования значений альфа-бета вместо +/-10000, похоже, устранило проблему. Большая ошибка с моей стороны, которую я просто не заметил. Что касается двух королей, я знаю, что это было не идеально, но это более последовательно приводило к ошибке по сравнению с другими настройками платы. Я буду продолжать тестирование, чтобы увидеть, все ли работает сейчас, так как я изменил значения альфа-бета. Если это так, то вы выиграли награду! – который я приму через несколько дней. - person user1334130; 22.02.2015