In the process of creating a tic tac toe game for a project on Free Code Camp, I have successfully added a minmax algorithm to determine the best square for the computer player's next move.
While the algorithm performs as intended in most cases I've tested, there is one scenario where it does not:
var userIs = 'o'
var computerIs = 'x'
function countInArray(array, what) {
var count = 0;
for (var i = 0; i < array.length; i++) {
if (array[i] === what) {
count++;
}
}
return count;
}
function nextMove(board, player) {
var nextPlayer;
if (computerIs !== player) {
nextPlayer = userIs;
} else {
nextPlayer = computerIs;
}
if (isGameOver(board)) {
if (player === userIs) {
return {
"willWin": -1,
"nextMove": -1
};
} else {
return {
"willWin": 1,
"nextMove": -1
};
}
}
var listOfResults = [];
if (countInArray(board, '-') === 0) {
return {
"willWin": 0,
"nextMove": -1,
};
}
var _list = [];//keeping track of avalible moves
for (var i=0; i < board.length; i++) {
if (board[i] === '-') {
_list.push(i);
}
}
for (var j = 0; j < _list.length; j++) {
board[_list[j]] = player;
var nextTry = nextMove(board, nextPlayer);
listOfResults.push(nextTry.willWin);
board[_list[j]] = '-';
}
if (player === computerIs) {
var maxele = Math.max.apply(Math, listOfResults);
return {
"willWin": maxele,
"nextMove": _list[listOfResults.indexOf(maxele)]
};
} else {
var minele = Math.min.apply(Math, listOfResults);
return {
"willWin": minele,
"nextMove": _list[listOfResults.indexOf(minele)]
};
}
}
function isGameOver(board) {
//horizontal wins
var gameOver = false;
var rowOffset = [0,3,6];
rowOffset.forEach(function(row){
if (board[row] === board[row + 1] && board[row + 1] === board[row + 2] && board[row] !== "-") {
gameOver = true;
}
});
//vertical wins
var colOffset = [0,1,2];
colOffset.forEach(function(col){
if (board[col] === board[col + 3] && board[col + 3] === board[col + 6] && board[col] !== "-" ){
gameOver = true;
}
});
///diag wins
if (board[0] === board[4] && board[4] === board[8] && board[8] !== "-" ) {
gameOver = true;
}
if (board[2] === board[4] && board[4] === board[6] && board[6] !== "-" ) {
gameOver = true;
}
return gameOver;
}
nextMove(["x", "x", "o", "o", "x", "-", "-", "-", "o"], computerIs)
During testing, I encountered an unexpected outcome where it returned: {willWin: 1, nextMove: 5}
instead of {willWin: 1, nextMove: 7}
Referring to a Python implementation example found here: https://gist.github.com/SudhagarS/3942029, I expected the same result as shown in the Python code.
Would you be able to identify any specific reason or issue that could explain this behavior?