title: minimax algorithm in javaScript is not working as expected and returns the wrong move
body: <p>I'm trying to make a Tic-Tac-Toe in javaScript using minimax algorithm but it seems that I'm doing something wrong and minimax algorithm, is not detecting the best move. Here is the code:</p>
  <pre><code>const board = [&quot;X&quot;, null, null, null, null, &quot;X&quot;, &quot;X&quot;, &quot;O&quot;, &quot;O&quot;];
  /*
      X   _   _
      _   _   X
      X   O   O
  
  */
  
  // duplicate passed board and return the new board state
  const makeAIMove = (currentBoard, square, player) =&gt; {
      const nextBoard = [...currentBoard];
      nextBoard[square] = player;
      return nextBoard;
  };
  
  // find empty squares
  const emptySquares = (sqBoard) =&gt;
      sqBoard
          .map((sq, idx) =&gt; (sq === null ? idx : null))
          .filter((sq) =&gt; sq !== null);
  
  // check if no empty squares are available
  const isFinished = (sqBoard) =&gt; (emptySquares(sqBoard).length ? false : true);
  
  // check winner
  const checkWinner = (sqBoard) =&gt; {
      const winConditions = [
          [0, 1, 2],
          [3, 4, 5],
          [6, 7, 8],
          [0, 3, 6],
          [1, 4, 7],
          [2, 5, 8],
          [0, 4, 8],
          [2, 4, 6],
      ];
  
      for (const winCondition of winConditions) {
          [a, b, c] = winCondition;
          if (sqBoard[a] &amp;&amp; sqBoard[a] === sqBoard[b] &amp;&amp; sqBoard[a] === sqBoard[c])
              return sqBoard[a];
      }
  
      return false;
  };
  
  // minimax algorithm
  const minimax = (sqBoard, depth, isMaximizer) =&gt; {
      // terminal checker
      const theWinner = checkWinner(sqBoard);
      // we have a winner
      if (theWinner) {
          return theWinner === &quot;X&quot; ? -10 : 10;
      }
      // it's a tie
      if (isFinished(sqBoard)) {
          return 0;
      }
  
      let bestScore;
      if (isMaximizer) {
          bestScore = -1000;
          emptySquares(sqBoard).forEach((square) =&gt; {
              // make a sample move
              let nextBoard = makeAIMove(sqBoard, square, &quot;O&quot;);
  
              // recursion
              let score = minimax(nextBoard, depth + 1, false);
              bestScore = Math.max(bestScore, score);
          });
      } else {
          bestScore = 1000;
          emptySquares(sqBoard).forEach((square) =&gt; {
              let nextBoard = makeAIMove(sqBoard, square, &quot;X&quot;);
              let score = minimax(nextBoard, depth + 1, true);
              bestScore = Math.min(bestScore, score);
          });
      }
      return bestScore;
  };
  
  // find the best move
  const nextBestMove = (sqBoard) =&gt; {
      let nextMoveArray = [];
      let remainedSquares = emptySquares(sqBoard);
      remainedSquares.forEach((square) =&gt; {
          let nextBoard = makeAIMove(sqBoard, square, &quot;O&quot;);
          let theScore = minimax(nextBoard, 0, true);
          nextMoveArray.push({
              sq: square,
              sc: theScore,
          });
      });
  
      nextMoveSorted = nextMoveArray.sort((a, b) =&gt; (a.sc &lt; b.sc ? 1 : -1));
      return nextMoveSorted[0].sq;
  };
  
  console.log(nextBestMove(board));
  </code></pre>
  <p>In the above condition, the best move would be stopping X to win by filling the board[3] with an &quot;O&quot; but it always detects another move that has a higher score.</p>
  <p>Can anyone help me to understand what's going wrong with my code?</p>
  <p>Thank you.</p>