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]]
is4
and 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!