Negamax с ошибкой альфа-бета обрезки на глубине 0

Я программирую негамакс с обрезкой альфа-бета. Однако это работает только в том случае, если «ПЛОХАЯ» ЛИНИЯ удалена, но я не знаю, почему. Я основывал свой код на этом псевдокоде. Это правильно? Большинство реализаций вызывают negamax внутри цикла (в отдельной функции для корневого узла), должен ли я это делать? Почему?

private static double AlphaBetaWithMemory(Board board, int player,
        int depth,
        int max_depth, double alpha, double beta) {


    double eval = Double.NEGATIVE_INFINITY;
    List<Integer> moves;
    if (depth == max_depth
            || board.gameOver()) {
        double h = board.heuristic(player);
        return h;
    } else {
        movs=board.getMoves();
        for (Integer m : moves) {
            if (depth == 1) {
                double val = -AlphaBetaWithMemory(
                        board.move(m), (player + 1) % 2,
                        depth + 1,
                        max_depth, -beta, -alpha);
                if (val > eval) {
                    best_mov = m;
                    eval = val;
                } else if (val == eval) {
                    if (Math.random() > 0.5) {
                        best_mov = m;
                    }
                }
                alpha = Math.max(alpha, val); //"BAD" LINE
            } else {
                double val = -AlphaBetaWithMemory(
                        board.mover(m), (player + 1) % 2,
                        depth + 1,
                        max_depth, -beta, -alpha);
                eval = Math.max(eval, val);
                alpha = Math.max(alpha, val);
                if (alpha >= beta) {
                    return beta;
                }
            }
        }
   }
   return eval;

person dv1729    schedule 02.12.2014    source источник
comment
Что происходит, сохраняя ПЛОХУЮ ЛИНИЮ? В первом вызове AlphaBetaWithMemory одним из аргументов является board.move(m), во втором вызове — board.mover(m). Это просто опечатка?   -  person manlio    schedule 04.12.2014


Ответы (1)


Проблема заключалась в следующем:

else if (val == eval) {
      if (Math.random() > 0.5) {
            best_mov = m;
      }
}

Чтобы решить эту проблему (и сохранить случайность), мне просто нужно было перетасовать «movs». Я знаю, что сортировка "movs" будет более эффективной.

person dv1729    schedule 04.12.2014