Search code examples
javascriptalgorithmminimax

Tic Tac Toe bot with minimax not able to find best move


I am trying to make a tic tac toe ai with minimax algorithm, following the tutorial by freecodecamp. But the bot is not able to find winning moves. I tried comparing the code to other people's code and I don't find any mistakes.

I checked the move which was returned by the function and it's returning a move with a score of -10 even though a move with score 10 was available.

Please tell me what's wrong with my code.

function minimax(gameBoard, player){
    if(checkWin(gameBoard, bot)) return {score: 10};
    if(checkWin(gameBoard, human)) return {score: -10};
    
    var emptyCells = board.filter(e => typeof e === "number");
    
    if(emptyCells.length===0) return {score: 0};
    
    var possibleMoves = [];
    
    for(var i=0;i<emptyCells.length;i++){
        var move = {};
        move.id = gameBoard[emptyCells[i]];
        
        gameBoard[emptyCells[i]] = player;
        
        if(player === bot){
            move.score = minimax(gameBoard, human).score;
        }else{
            move.score = minimax(gameBoard, bot).score;
        }
        
        gameBoard[emptyCells[i]] = move.id;
        possibleMoves.push(move);
        
        var bestMove;
        if(player === bot){
            var bestScore = -100;
            for(var i=0;i<possibleMoves.length;i++){
                if(possibleMoves[i].score>bestScore){
                    bestScore = possibleMoves[i].score;
                    bestMove = i;
                }
            }
        }
        else{
            var bestScore = 100;
            for(var i=0;i<possibleMoves.length;i++){
                if(possibleMoves[i].score<bestScore){
                    bestScore = possibleMoves[i].score;
                    bestMove = i;
                }
            }
        }
    }
    return possibleMoves[bestMove];
}

Solution

  • Assuming that your function checkWin has no mistakes, and that the arguments you pass in the initial call are valid, there are the following two issues in your code:

    • In the following statement there is a reference to board, which should really be gameBoard:

      var emptyCells = board.filter(e => typeof e === "number");
      
    • The part of the code that determines bestMove (starting with var bestMove;) should not be inside the loop. You want to first add all the moves to possibleMoves, and only then iterate those to find the best move. But right now you search for a best move each time you add one move to possibleMove. Worse still, you use the same loop variable i which is already used in the outer loop, which will completely mix up your outer loop.

    Fixing these two issues should resolve the problem you described.