Javascript Tic Tac Toe AI-未选择最佳空间

Javascript Tic Tac Toe AI-未选择最佳空间,javascript,artificial-intelligence,minimax,Javascript,Artificial Intelligence,Minimax,我一直在努力为Tic-Tac-Toe项目创造无与伦比的人工智能 我一直在用谷歌搜索&使用编码训练教程——然而,人工智能似乎仍然在选择一个随机的正方形虽然它选择的方块背后一定有逻辑,但我搞不清楚逻辑是什么 这是我的代码笔-,我复制了下面的相关代码 如果有人能看看这个,我会非常感激的。我已经被困了好几天了,搞不清楚是什么问题 //functions to assess winning combos function equals3(a, b, c) { return a === b &

我一直在努力为Tic-Tac-Toe项目创造无与伦比的人工智能

我一直在用谷歌搜索&使用编码训练教程——然而,人工智能似乎仍然在选择一个随机的正方形虽然它选择的方块背后一定有逻辑,但我搞不清楚逻辑是什么

这是我的代码笔-,我复制了下面的相关代码

如果有人能看看这个,我会非常感激的。我已经被困了好几天了,搞不清楚是什么问题

//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;
  }
};
//用于评估获胜组合的函数
函数等式3(a、b、c){
返回a==b&&b==c&&a!==“”;
}
函数checkWinner(){
设winner=null;
if(等式3(游戏板[0],游戏板[1],游戏板[2])){
赢家=游戏板[0];
};
if(等式3(游戏板[3]、游戏板[4]、游戏板[5])){
赢家=游戏板[3];
};
if(等式3(游戏板[6],游戏板[7],游戏板[8])){
赢家=游戏板[6];
};
if(等式3(游戏板[0],游戏板[3],游戏板[6])){
赢家=游戏板[0];
};
if(等式3(游戏板[1],游戏板[4],游戏板[7])){
赢家=游戏板[1];
};
if(等式3(游戏板[2],游戏板[5],游戏板[8])){
赢家=游戏板[0];
};
if(等式3(游戏板[0],游戏板[4],游戏板[8])){
赢家=游戏板[0];
};
if(等式3(游戏板[2],游戏板[4],游戏板[6])){
赢家=游戏板[2];
};
设openSpots=0;
for(设i=0;i最佳分数){
最佳分数=分数;
move=i;
}
}    
}
游戏板[移动]=人工智能;
};
//极小极大函数
函数minimax(游戏板、深度、isMaximizing){
让结果=checkWinner();
如果(结果!==null){
返回分数[结果];
}
if(最大化){
让bestScore=-无穷大;
for(设i=0;i
您正在电路板中循环,并为每个方块调用minimax,这是不必要的,而且速度会非常慢。你只需要这样称呼它一次:

move, score = minimax(gameBoard, 8, true)
我不确定是否需要它,但我会从checkWinner函数返回一个0,而不是返回一个“tie”字符串。似乎很难从例如1和“te”中选择最大/最小值

然后,在你的minimax函数中,你需要改变一些东西来实际返回它找到的最佳移动。很抱歉出现任何编程语言问题,我已经习惯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;
  }
};
//极小极大函数
函数minimax(游戏板、深度、isMaximizing){
让结果=checkWinner();
如果(结果!==null){
返回无,得分[结果];
}
if(最大化){
让bestScore=-无穷大;
for(设i=0;i最佳得分:
最佳分数
最佳移动=游戏板[i]
}
}
返回最佳移动,最佳得分;
}否则{
让bestScore=无穷大;
for(设i=0;i
非常感谢您的帮助,非常感谢!我使用了这个(并查看了另一个教程),现在有了一些有用的东西。这是在同一个代码笔链接的情况下,其他人被困在同一件事,并无意中发现了这个页面。很高兴它的工作!如果您对解决方案满意,请接受答案():)