I am relatively new to JS and have been working on a Tic Tac Toe game as an exercise. I think I am 90% of the way there, but I am having an annoying bug that comes up after the first play through (ie. when a new game is rendered). In this game, each square is given a class ('x' or 'o') when the corresponding player clicks on it. The game logic checks if that player has any of the game winning combinations, and if they do resets the game (removing the 'x' and 'o' tile classes). This seems to work, but upon subsequent clicking in the next round, some tiles are given BOTH 'x' and 'o' classes, which basically breaks the game. For example, the game can be won with a line of 'x', 'x' and 'o'.
EDIT 1: Okay, so I think the problem is that newGame() is running twice. Still trying to figure out a solution.
I've been searching every for an answer to this, but to no avail! I've included my code below. Thanks!!
$(document).ready(function() {
var xTurn = true;
var xScore = 0;
var oScore = 0;
var count = 0;
newGame();
function newGame() {
$("td").removeClass();
$("td").empty();
count = 0;
xTurn = true;
render();
game();
}
function render() {
$("#xScore").text("x Score: " + xScore);
$("#oScore").text("o Score: " + oScore);
}
function game() {
$("td").on("click", function () {
var self = $(this);
if (xTurn) {
self.text("X");
self.addClass("x");
}
else {
$(this).text("O");
self.addClass("o");
}
xTurn = !xTurn;
$(this).off("click");
count ++;
scoreEval();
});
function scoreEval() {
if (
$("#one").hasClass('x') && $("#two").hasClass('x') && $("#three").hasClass('x') ||
$("#four").hasClass('x') && $("#five").hasClass('x') && $("#six").hasClass('x') ||
$("#seven").hasClass('x') && $("#eight").hasClass('x') && $("#nine").hasClass('x') ||
$("#one").hasClass('x') && $("#four").hasClass('x') && $("#seven").hasClass('x') ||
$("#two").hasClass('x') && $("#five").hasClass('x') && $("#eight").hasClass('x') ||
$("#three").hasClass('x') && $("#six").hasClass('x') && $("#nine").hasClass('x') ||
$("#one").hasClass('x') && $("#five").hasClass('x') && $("#nine").hasClass('x') ||
$("#three").hasClass('x') && $("#five").hasClass('x') && $("#seven").hasClass('x')
) {
xScore ++;
alert("Player X has won the game!");
newGame();
}
else if (
$("#one").hasClass('o') && $("#two").hasClass('o') && $("#three").hasClass('o') ||
$("#four").hasClass('o') && $("#five").hasClass('o') && $("#six").hasClass('o') ||
$("#seven").hasClass('o') && $("#eight").hasClass('o') && $("#nine").hasClass('o') ||
$("#one").hasClass('o') && $("#four").hasClass('o') && $("#seven").hasClass('o') ||
$("#two").hasClass('o') && $("#five").hasClass('o') && $("#eight").hasClass('o') ||
$("#three").hasClass('o') && $("#six").hasClass('o') && $("#nine").hasClass('o') ||
$("#one").hasClass('o') && $("#five").hasClass('o') && $("#nine").hasClass('o') ||
$("#three").hasClass('o') && $("#five").hasClass('o') && $("#seven").hasClass('o')
) {
oScore ++;
alert("Player O has won the game!");
newGame();
}
else if (count === 9) {
alert("Draw!");
newGame();
}
}
}
});
table, td {
border: 1px solid black;
font-size: 50px;
text-align: center;
}
td {
height: 100px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<head>
<title>Tic Tac Toe</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div id="score">
<p>Score</p>
<p id="xScore"></p>
<p id="oScore"></p>
</div>
<table>
<tr>
<td id="one"></td>
<td id="two"></td>
<td id="three"></td>
</tr>
<tr>
<td id="four"></td>
<td id="five"></td>
<td id="six"></td>
</tr>
<tr>
<td id="seven"></td>
<td id="eight"></td>
<td id="nine"></td>
</tr>
</table>
<script src="script.js"></script>
</body>
</html>
You should check in onClick event if there is assigned X or O, before doing any action. I reproduced an error by clicking on box that already has X/O in it.