I used hover on element box that i did by (event listener "mouse enter and mouse leave") that changes color on mouse enter and changes back to normal when mouse leave(red when x turn and blue when o turn) only when game is not over.But my script changes the colors on hover even when the game is over and i dont want that.
Here is my code:
// The if statement if (boxes[a].innerText) checks if the innerText property of the DOM element at index a in the boxes array is truthy. If it is truthy, then the condition in the if statement will be evaluated as true and the code inside the if block will be executed.
// The innerText property of a DOM element is a string that represents the text content of the element. If the element has no text content, the innerText property will be an empty string. An empty string is considered a falsy value in JavaScript, so the condition if (boxes[a].innerText) will be evaluated as false if the innerText property of the element at index a is an empty string.
// The purpose of this if statement is to check if the element at index a has been clicked by a player (i.e., if it has a value of "X" or "O"). If it has not been clicked, the innerText property will be an empty string and the condition will be evaluated as false, causing the code inside the if block to be skipped. If the element at index a has been clicked, the innerText property will be a non-empty string and the condition will be evaluated as true, allowing the code inside the if block to be executed.
boxes = Array.from(document.getElementsByClassName("boxes"))
reset = document.getElementById("restart_btn")
wintext = document.getElementById("winning_text")
const X_text = "X"
const O_text = "O"
let current_player = X_text
const startgame = () => {
if ((playerhaswon() == false) || (checkDraw() == false)){
// mouse oper aye to red ya green , jayga to normal colour
boxes.forEach(box =>
{box.addEventListener("mouseenter", () => {
box.style.backgroundColor = current_player==X_text?"rgb(215 175 175)":"rgb(175 215 193)"
})
}
)
boxes.forEach(box=>{
box.addEventListener("mouseleave",()=>{
box.style.backgroundColor = "rgb(222, 238, 225)"
})
})}
boxes.forEach(box => {
box.addEventListener("click", e => {
if (playerhaswon() === false) {// agr player nahi jeeta to click kr sakty hain
const id = e.target.id;// id lelo uski 0,1 ,2 etc
if (e.target.innerText === "") { //agr kahli ha
e.target.style.color = current_player == X_text ? "red" : "green"
e.target.innerText = current_player; //uskay andr x ya o
if (playerhaswon() !== false) {//is doraan agr jeet jaye to yeh karo
wintext.innerHTML = `${current_player} has won`;
let winning_blocks = playerhaswon();// player has won wala function 3 id return karay ga
for (const num of winning_blocks) { // winnig block ma 3 blocks ki id ha
boxes[num].style.backgroundColor = current_player == X_text?"rgb(215 175 175)":"rgb(175 215 193)";// un 3 blocks ka colour change
}
} else if (checkDraw()) {// draw ha to draw likh do
wintext.innerHTML = "Draw!";
} else {// agr na jeeta hain na draw hain to ,, x ko o ma tabdel kar do ya o ko x ma
current_player =
current_player == X_text ? O_text : X_text;
}
}
}
});
});
};
const winning_combos = [ // in teen jgah par x hua to jeet jaye ga
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function playerhaswon() {// kab jeetay ga is trah pata chalay ga
for (const condition of winning_combos) { // winning comb ma se [a,b,c] no. letay jau
let [a, b, c] = condition;
if (// agr box ka a th element likha hua hai aur box kay b th aur c th element k brabar ha
boxes[a].innerText &&
(boxes[a].innerText == boxes[b].innerText &&
boxes[a].innerText == boxes[c].innerText)
) {
return [a, b, c];// to unhay return krdo kyuki yehi element ma x ya o same hai.
}
}
return false; // agr aisa nahi ha matlabgame jaari hai
}
// let hover_thing;
// if ((playerhaswon()!==false)&& (checkDraw() == true)){
// let hover_thing = true
// }
function checkDraw() {
// Check if any cell on the board is empty
for (let i = 0; i < 9; i++) {
if (boxes[i].innerText === "") {
return false;// agr khali hai matlab abhi draw nahi hua to false bhej do
}
}
// Check if no player has won the game
if (playerhaswon() === false) {
return true;
}
// Otherwise, the game is not a draw
return false;
}
function resetit() {// sab kuch reset kardo
boxes.forEach(box => {
box.innerHTML = "";
box.style.backgroundColor = "";
});
current_player = X_text;
wintext.innerHTML = "Tic Tac Toe";
}
reset.addEventListener("click", () => resetit());
// if (hover_thing == true){
// document.getElementsByTagName("style")[0].innerHTML =
// ".boxes:hover { background-color: initial; }";
// }
startgame();
I tried to condition hover only when game is not over. ::
if ((playerhaswon() == false) || (checkDraw() == false)){
// mouse oper aye to red ya green , jayga to normal colour
boxes.forEach(box =>
{box.addEventListener("mouseenter", () => {
box.style.backgroundColor = current_player==X_text?"rgb(215 175 175)":"rgb(175 215 193)"
})
}
)
boxes.forEach(box=>{
box.addEventListener("mouseleave",()=>{
box.style.backgroundColor = "rgb(222, 238, 225)"
})
})}
The problem is that you check whether the game is over at the wrong moment (and in the wrong way). It concerns the following statement:
if ((playerhaswon() == false) || (checkDraw() == false)){
This is executed when the game starts, not when the user moves the mouse. So that is the wrong moment to execute it.
Secondly, this condition checks whether no player has won yet OR there is no draw. But logically, this condition is always true. Because if a player has won, then still it is no draw, and when it is a draw then no player has won. The ||
should be a &&
, as you want both playerhaswon()
and checkDraw()
to be false at the same time. Alternatively, you can invert the condition, and when that is true, exit the function (which is what I will do in below snippet).
So, correct that condition in either way and move it inside the mouseenter
and mouseleave
event handlers.
For the click
event handler you have done it almost right, but the check for a draw is missing there, so that must be added.
Here is a correction (I added some HTML to make it work):
const boxes = Array.from(document.getElementsByClassName("boxes"))
const reset = document.getElementById("restart_btn")
const wintext = document.getElementById("winning_text")
const X_text = "X"
const O_text = "O"
let current_player = X_text
const startgame = () => {
// mouse oper aye to red ya green, jayga to normal colour
boxes.forEach(box => {
box.addEventListener("mouseenter", () => {
if (playerhaswon() || checkDraw()) return;
box.style.backgroundColor = current_player==X_text?"rgb(215 175 175)":"rgb(175 215 193)";
});
});
boxes.forEach(box=>{
box.addEventListener("mouseleave",()=>{
if (playerhaswon() || checkDraw()) return;
box.style.backgroundColor = "rgb(222, 238, 225)"
});
});
boxes.forEach(box => {
box.addEventListener("click", e => {
if (playerhaswon() || checkDraw()) return; // agr player nahi jeeta to click kr sakty hain
const id = e.target.id;// id lelo uski 0,1 ,2 etc
if (e.target.innerText === "") { //agr kahli ha
e.target.style.color = current_player == X_text ? "red" : "green"
e.target.innerText = current_player; //uskay andr x ya o
if (playerhaswon() !== false) {//is doraan agr jeet jaye to yeh karo
wintext.innerHTML = `${current_player} has won`;
let winning_blocks = playerhaswon();// player has won wala function 3 id return karay ga
for (const num of winning_blocks) { // winnig block ma 3 blocks ki id ha
boxes[num].style.backgroundColor = current_player == X_text?"rgb(215 175 175)":"rgb(175 215 193)";// un 3 blocks ka colour change
}
} else if (checkDraw()) {// draw ha to draw likh do
wintext.innerHTML = "Draw!";
e.target.style.backgroundColor = "rgb(222, 238, 225)";
} else {// agr na jeeta hain na draw hain to ,, x ko o ma tabdel kar do ya o ko x ma
current_player =
current_player == X_text ? O_text : X_text;
}
}
});
});
};
const winning_combos = [ // in teen jgah par x hua to jeet jaye ga
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function playerhaswon() {// kab jeetay ga is trah pata chalay ga
for (const condition of winning_combos) { // winning comb ma se [a,b,c] no. letay jau
let [a, b, c] = condition;
if (// agr box ka a th element likha hua hai aur box kay b th aur c th element k brabar ha
boxes[a].innerText &&
(boxes[a].innerText == boxes[b].innerText &&
boxes[a].innerText == boxes[c].innerText)
) {
return [a, b, c];// to unhay return krdo kyuki yehi element ma x ya o same hai.
}
}
return false; // agr aisa nahi ha matlabgame jaari hai
}
// let hover_thing;
// if ((playerhaswon()!==false)&& (checkDraw() == true)){
// let hover_thing = true
// }
function checkDraw() {
// Check if any cell on the board is empty
for (let i = 0; i < 9; i++) {
if (boxes[i].innerText === "") {
return false;// agr khali hai matlab abhi draw nahi hua to false bhej do
}
}
// Check if no player has won the game
if (playerhaswon() === false) {
return true;
}
// Otherwise, the game is not a draw
return false;
}
function resetit() {// sab kuch reset kardo
boxes.forEach(box => {
box.innerHTML = "";
box.style.backgroundColor = "";
});
current_player = X_text;
wintext.innerHTML = "Tic Tac Toe";
}
reset.addEventListener("click", () => resetit());
// if (hover_thing == true){
// document.getElementsByTagName("style")[0].innerHTML =
// ".boxes:hover { background-color: initial; }";
// }
startgame();
table { border-collapse: collapse; margin: 10px 0 10px 0 }
table td { border: 1px solid; width: 25px; text-align: center; }
tr { height: 25px; v-align: middle }
.boxes { background-color: rgb(222, 238, 225) }
<div id="winning_text">Tic Tac Toe</div>
<table>
<tr><td class="boxes"></td><td class="boxes"></td><td class="boxes"></td></tr>
<tr><td class="boxes"></td><td class="boxes"></td><td class="boxes"></td></tr>
<tr><td class="boxes"></td><td class="boxes"></td><td class="boxes"></td></tr>
</table>
<button id="restart_btn">Restart</button>