Reputation: 123
I'm creating a simple tic-tac-toe game and I have a boolean called winAlert that if it is true it should alert the player that they have won. This works correctly for the most part, but there is one instance where it does not. If the game is won and all of the cells are filled, the console logs that winAlert's value is false, but it still alerts the player that they have won, as if it were true. Could someone look over this code and see why this is behaving in this way? http://jsfiddle.net/Z5c9P/3/ This function is where I think the problem lies, but I don't know for sure.
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
for (var j = 0; j < winConditions[i].length; j++) {
winAlert = false;
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
winAlert = true;
break;
}
}
if (!winAlert) break;
}
if (winAlert) {
alert(currentPlayer + " wins!");
break;
}
}
};
Here's the code that calls this function:
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
Upvotes: 0
Views: 235
Reputation: 29
i change a little your code Fiddle
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
winAlert = false;
matches = 0;
for (var j = 0; j < winConditions[i].length; j++) {
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
matches++;
}
}
}
if (matches == 3) return true;
}
return false;
};
and then
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
if (determineWin(xMoves)){ // this is changed
alert("X Win")
return;
};
if (determineWin(oMoves)){
alert("O Win")
return;
};
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
** Updated to clarify
Upvotes: 0
Reputation: 8174
This is happening because your code does the following:
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
So if X ever wins the game, determineWin(xMoves)
will set the variable to true, and determinWin(oMoves)
will set it back to false, all before the console.log()
One way to solve this would be to only check for a win for the current player's moves:
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : yMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
Upvotes: 2
Reputation: 1201
You have called determineWin
on each player. so if x wins, determineWin(oMoves);
will make winAlert
false. Is this the problem?
Maybe you should create a new determineWin
which only called once to determine who is the winner.
this code will just skip another user(so winAlert
is still true) when his cell is less than 3, so this problem doesn't need fill all cells but just each player has more than 3 cells.
if (winConditions[i].length > pMoves.length) {
continue;
}
Upvotes: 0