Java 中的井字棋 AI 极小极大函数

问题描述

在这里有我的极小极大算法代码。它似乎正在做出明智的决定,但并非总是如此,这不应该发生,我需要帮助,因为我似乎无法找到哪里出错了。

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

我似乎还没有使用“分数”,正在考虑增加深度,但我想不出这会有什么帮助。

解决方法

我修好了。只需更改 minimax 函数中的布尔值即可。

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;
}