I’m trying to teach myself minimax in javscript from the code here: https://github.com/beaucarnes/fcc-project-tutorials/blob/master/tictactoe/7/script.js
And video: https://youtu.be/P2TcQ3h0ipQ?t=2334
This is the function:
function minimax(newBoard, player) {
var availSpots = emptySquares();
if (checkWin(newBoard, huPlayer)) {
return {score: -10};
} else if (checkWin(newBoard, aiPlayer)) {
return {score: 10};
} else if (availSpots.length === 0) {
return {score: 0};
}
var moves = [];
for (var i = 0; i < availSpots.length; i++) {
var move = {};
move.index = newBoard[availSpots[i]];
newBoard[availSpots[i]] = player;
if (player == aiPlayer) {
var result = minimax(newBoard, huPlayer);
move.score = result.score;
} else {
var result = minimax(newBoard, aiPlayer);
move.score = result.score;
}
newBoard[availSpots[i]] = move.index;
moves.push(move);
}
var bestMove;
if(player === aiPlayer) {
var bestScore = -10000;
for(var i = 0; i < moves.length; i++) {
if (moves[i].score > bestScore) {
bestScore = moves[i].score;
bestMove = i;
}
}
} else {
var bestScore = 10000;
for(var i = 0; i < moves.length; i++) {
if (moves[i].score < bestScore) {
bestScore = moves[i].score;
bestMove = i;
}
}
}
return moves[bestMove];
}
I think I understand most of it, but there are a few gaps preventing me from getting my mind around it completely.
As I understand it, minimax(newBoard, player) starts by getting the available spots from which to play a move, and establishing a way of ranking the end results.
Then it creates an array moves into which objects called move will go. The for loop gets a move object for each available spot.
Each move object gets a property called index through move.index = newBoard[availSpots[i]];
Does
newBoard[availSpots[i]]simply represent the indexes of the available sorts. Is it right to say that in a board that has available spots[4, 5, 6],newBoard[availSpots[0]]is4and thus the first move object will have an index property of 4?The new part of code is
newBoard[availSpots[i]] = player-- does that mean the player's icon is marked innewBoard[4]?
After that, there is an if else statement that adds a .score property to the move object.
- But then I see
newBoard[availSpots[i]] = move.index, which reverses what we did earlier -- why is this?
Then the latest move is pushed into the moves array, and from the array, we loop through the scores to find the best move of moves.
I'm having a hard time seeing how this all works. I tried putting in a console.log and my repl.it fails...
- is it because dozens of permutations are being tried by the compiler and it would be ugly to have them all logged? How many moves does the computer have to try?
And finally:
- Since this is a turn-based game, where in the code is the computer "playing" the other side in order to get a terminal value?
I've gone through a ton of minimax resources online so I'm hoping someone can help -- they all seem to gloss over this. I've looked at:
https://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-1-introduction/
https://learnersbucket.com/tutorials/js-projects/tic-tac-toe-game-in-javascript-with-bot/
https://steveafrost.com/articles/discovering-the-minimax-algorithm/
Thanks!