Javascript Tic Tac Toe AI - 未选择最佳 space

Javascript Tic Tac Toe AI - not selecting optimum space

我一直在努力为 Tic Tac Toe 项目创建无与伦比的 AI。

我一直在谷歌搜索和使用编码火车教程 - 然而,AI 似乎仍在选择一个随机方块。 虽然选择哪个方块背后一定有逻辑,但我想不通这是什么逻辑!

这是我的代码笔 - https://codepen.io/kath-ldn/pen/oNLZqrp ,我已经复制了下面的相关代码。

如果有人能看一看,我将不胜感激。卡了好几天了,一直搞不明白是什么问题

//functions to assess winning combos
function equals3(a, b, c) {
    return a === b && b === c && a !== "";
}

function checkWinner(){
    let winner = null;

    if (equals3(gameBoard[0], gameBoard[1], gameBoard[2])) {
        winner = gameBoard[0];
    };
    if (equals3(gameBoard[3], gameBoard[4], gameBoard[5])) {
        winner = gameBoard[3];
    };
    if (equals3(gameBoard[6], gameBoard[7], gameBoard[8])) {
        winner = gameBoard[6];
    };
    if (equals3(gameBoard[0], gameBoard[3], gameBoard[6])) {
        winner = gameBoard[0];
    };
    if (equals3(gameBoard[1], gameBoard[4], gameBoard[7])) {
        winner = gameBoard[1];
    };
    if (equals3(gameBoard[2], gameBoard[5], gameBoard[8])) {
        winner = gameBoard[0];
    };
    if (equals3(gameBoard[0], gameBoard[4], gameBoard[8])) {
        winner = gameBoard[0];
    };
    if (equals3(gameBoard[2], gameBoard[4], gameBoard[6])) {
        winner = gameBoard[2];
    };

    let openSpots = 0;
    for (let i = 0; i < gameBoard.length; i++) {
        if (gameBoard[i] === "") {
            openSpots = openSpots + 1;
        };
    };

    if (winner === null && openSpots === 0) {
        return 'tie';
    } else {
        return winner;
    };
};

let scores = {
  X: 10,
  O: -10,
  tie: 0
};

//function to create impossible-to-beat AI using minimax algorithm
function bestMove() {
    let bestScore = -Infinity;
    let move;
    for (let i = 0; i < gameBoard.length; i++) {
      if (gameBoard[i] === "") {
        gameBoard[i] = AI;
        let score = minimax(gameBoard, 0, false);
        gameBoard[i] = "";
        if (score > bestScore) {
        bestScore = score;
        move = i;
        }
      }    
    }
    gameBoard[move] = AI;
};

//minimax function
function minimax(gameBoard, depth, isMaximizing){
  let result = checkWinner();
  if (result !== null) {
    return scores[result];
  }

  if (isMaximizing) {
    let bestScore = -Infinity;
    for (let i = 0; i < gameBoard.length; i++) {
      if (gameBoard[i] === "") {
        gameBoard[i] = AI;
        let score = minimax(gameBoard, depth + 1, false);
        gameBoard[i] = "";
        bestScore = Math.max(score, bestScore);
      }
    }
    return bestScore;
  } else {
    let bestScore = Infinity;
    for (let i = 0; i < gameBoard.length; i++) {
      if (gameBoard[i] === "") {
        gameBoard[i] = human;
        let score = minimax(gameBoard, depth + 1, true);
        gameBoard[i] = "";
        bestScore = Math.min(score, bestScore);
      }
    }
    return bestScore;
  }
};

您正在遍历棋盘并为每个方块调用 minimax,这不是必需的,而且会非常慢。你只需要像这样调用它一次:

move, score = minimax(gameBoard, 8, true)

我不确定是否需要它,但我会 return 来自 checkWinner 函数的 0 而不是 return 一个 'tie' 字符串。似乎很难从中选择 max/min 值。一个 1 和一个 'te' 否则。

然后在您的 minimax 函数中,您需要更改一些内容以实际 return 它找到的最佳着法。对于任何编程语言问题,我很抱歉,我已经习惯了 Python。无论如何,我希望你明白我的意思:

//minimax function
function minimax(gameBoard, depth, isMaximizing){
  let result = checkWinner();
  if (result !== null) {
    return None, scores[result];
  }

  if (isMaximizing) {
    let bestScore = -Infinity;
    for (let i = 0; i < gameBoard.length; i++) {
      if (gameBoard[i] === "") {
        gameBoard[i] = AI;
        let score = minimax(gameBoard, depth - 1, false)[1];
        gameBoard[i] = "";
        if score > bestScore:
            bestScore = score
            bestMove = gameBoard[i]
      }
    }
    return bestMove, bestScore;
  } else {
    let bestScore = Infinity;
    for (let i = 0; i < gameBoard.length; i++) {
      if (gameBoard[i] === "") {
        gameBoard[i] = human;
        let score = minimax(gameBoard, depth - 1, true)[1];
        gameBoard[i] = "";
        if score < bestScore:
            bestScore = score
            bestMove = gameBoard[i]
      }
    }
    return bestMove, bestScore;
  }
};