Минимаксная функция искусственного интеллекта в Java

#java #tic-tac-toe #minimax

#java #крестики-нолики #минимакс

Вопрос:

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

 private char level2Move() {
  try {
    NBoard game_copy = (NBoard) game.clone();

    int bestScore = Integer.MIN_VALUE;
    char bestMove = '-';

    for (char move: game_copy.getValidMoves()) {
      game_copy.enterMove(move);
      int score = minimax(game_copy, true);
      game_copy.undoMove();
      if (score > bestScore) {
        bestScore = score;
        bestMove = move;
      }
    }

    return bestMove;
  } catch(CloneNotSupportedException e) {
    e.printStackTrace();
  }

  return '-';
}
 
 public int minimax(NBoard game, boolean isMaximizing) {
  int bestScore;

  switch (game.getGameState()) {
  case NBoard.X_WIN:
    return - 10;
  case NBoard.O_WIN:
    return 10;
  case NBoard.DRAW:
    return 0;
  }

  if (isMaximizing) {
    bestScore = Integer.MIN_VALUE;
    for (char move: game.getValidMoves()) {
      if (game.getGameState() == NBoard.ONGOING) {
        game.enterMove(move);
        int score = minimax(game, false);
        game.undoMove();
        bestScore = Math.max(score, bestScore);
      }
    }
  } else {
    bestScore = Integer.MAX_VALUE;
    for (char move: game.getValidMoves()) {
      if (game.getGameState() == NBoard.ONGOING) {
        game.enterMove(move);
        int score = minimax(game, true);
        game.undoMove();
        bestScore = Math.min(score, bestScore);
      }
    }
  }
  return bestScore;
}
 

Ввод платы (перемещение) — это буквы A-I, вот так…

 A|B|C
D|E|F
G|H|I
 

Кажется, я еще не использовал «score» и подумываю о добавлении глубины, но я не могу придумать, как это поможет.

Комментарии:

1. Вы уверены, что правильно рассчитали WDL? Если иногда он делает хорошие ходы, кажется, что он делает случайные ходы или всегда выбирает первый ход, который он пытается.

Ответ №1:

Я исправил это. Просто изменил логические значения в минимаксной функции.

 private char level2Move() {
  try {
    NBoard game_copy = (NBoard) game.clone();

    int bestScore = Integer.MIN_VALUE;
    char bestMove = '-';

    for (char move: game_copy.getValidMoves()) {
      game_copy.enterMove(move);
      int score = minimax(game_copy, false);       // here
      game_copy.undoMove();
      if (score > bestScore) {
        bestScore = score;
        bestMove = move;
      }
    }

    return bestMove;
  } catch(CloneNotSupportedException e) {
    e.printStackTrace();
  }

  return '-';
}
 
 public int minimax(NBoard game, boolean isMaximizing) {
  int bestScore;

  switch (game.getGameState()) {
  case NBoard.X_WIN:
    return - 10;
  case NBoard.O_WIN:
    return 10;
  case NBoard.DRAW:
    return 0;
  }

  if (isMaximizing) {
    bestScore = Integer.MIN_VALUE;
    for (char move: game.getValidMoves()) {
      if (game.getGameState() == NBoard.ONGOING) {
        game.enterMove(move);
        int score = minimax(game, false);          // here
        game.undoMove();
        bestScore = Math.max(score, bestScore);
      }
    }
  } else {
    bestScore = Integer.MAX_VALUE;
    for (char move: game.getValidMoves()) {
      if (game.getGameState() == NBoard.ONGOING) {
        game.enterMove(move);
        int score = minimax(game, true);           // here
        game.undoMove();
        bestScore = Math.min(score, bestScore);
      }
    }
  }
  return bestScore;
}