-1

I am trying to build a tic-tac-toe game using the minimax algorithm. It is not functioning correctly yet (meaning it is generating moves that are not optimal), and I think this is because I am not accounting for the moves of the opposite player. I'm just not quite sure how to incorporate this into my code. For context, I am working from http://neverstopbuilding.com/minimax.

Here is my code. The helper methods are all functional on their own but i did not include them here.

// this variable stores the optimum next move. 
var choice; 
// this stands for 'computer mark', the computer goes second and plays as 'x'
var cmark = 'X'; 
// mark of human player. Currently not integrated into the algorithm. 
var pmark = 'O' 
// 'game' is an array which starts as [0,1,2,3,4,5,6,7,8], each number corresponding 
//to a space on the tic tac toe board. 
function minimax(game){
    // this is the last state of the recursion, it checks if the game has ended
    // score() returns +10 if the computer wins, -10 for loss, 0 for tie 
    if (gameOver(game)){
        return score(game);     
    }
    // this array stores all the possible scores so we can later search for the highest. 
    var scores = []; 
    //this array stores the moves that correspond to the scores array
    var moves = []; 
    // loops through every open move. 
    //HOW DO I MAKE IT SO IT ALTERNATES BETWEEN HUMAN AND COMPUTER MOVES  
    for (var i = 0; i<game.length; i++){
      if (open(game[i])){
        //game[i] is a number corresponding to a space on the board. 
        moves.push(game[i]); 
        //create a new variable representing the game state if this move is chosen
        var possibleGame = game; 
        possibleGame[i] = cmark; 
        //run minimax on this game state,thus obtaining scores for all possible outcomes.  
        scores.push(minimax(possibleGame)); 
      }
    }
//this is another place where I need to add something for opposite player? 
//find the maximum score from the scores list. this will be returned. 
var maxScore = Math.max(...scores);
var maxScoreIndex = scores.indexOf(maxScore); 
//find the move with the same index as the maximum score. this will be stored as 'choice' 
choice = moves[maxScoreIndex]; 
return maxScore; 
}
Galen
  • 13
  • 1
  • 3
  • What do you think `var possibleGame = game; possibleGame[i] = cmark;` does? That will update `game` too... – nnnnnn May 30 '16 at 02:15
  • **It is not functioning correctly yet** is super vague. You've barely explained what the function *should do* and you havent mentioned at all *how it fails to do that*. have a look at [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) – Wesley Smith May 30 '16 at 02:27
  • Thanks for your feedback. I tried to clarify. – Galen May 30 '16 at 13:43

1 Answers1

0

Just keep track of the current user, after the for-loop has ended, you choose a move. So right before you return a choice at the end of the minmax function, you change the current user (which you make a global variable, or at least outside of the minmax function's scope.

It's important that you find the minimal value for a move made by the opponent instead of the maximal value that you correctly find for the player. This principle is derived from the idea that your opponent is a perfect player, meaning that he will always choose the best move available for him.

So in conclusion: create a 'global' variable keeping the current player. When it's the homeplayers turn, return the maximum score's move. When it's the opponent's turn, return the minimum score's move.

Glubus
  • 2,819
  • 1
  • 12
  • 26