I have made a tic tac toe using JS however it has some problems My code is:
let x = [];
let o = [];
let xTurn = false;
let winPat = [
['00', '10', '20'],
['01', '11', '21'],
['02', '12', '22'],
['00', '01', '02'],
['10', '11', '12'],
['20', '21', '22'],
['00', '11', '22'],
['02', '11', '20']
];
const tableR = document.getElementsByClassName('tableR');
const button = document.getElementById('btn')
for (let i = 0; i <= 2; i ) {
for (let j = 0; j <= 2; j ) {
let newElement = document.createElement('td');
tableR.item(i).appendChild(newElement);
newElement.addEventListener('click', () => {
if (elementIsEmpty(newElement)) {
const img = document.createElement('img');
if (xTurn) {
img.src = 'https://www.google.com/url?sa=i&url=https://commons.wikimedia.org/wiki/File:Red_X.svg&psig=AOvVaw1B-fppvlN2x5oSCGllnXGc&ust=1634565535566000&source=images&cd=vfe&ved=0CAkQjRxqFwoTCMjbg6XN0fMCFQAAAAAdAAAAABAD';
x.push(String(i) String(j))
} else {
img.src = 'https://www.google.com/imgres?imgurl=https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Letter_o.svg/407px-Letter_o.svg.png&imgrefurl=https://commons.wikimedia.org/wiki/File:Letter_o.svg&tbnid=p-B77Lz3DDttwM&vet=12ahUKEwizlYTWzdHzAhXMg9gFHTSaBJkQMygAegUIARDaAQ..i&docid=K2HPZsIMOu4d5M&w=407&h=768&q=pixture of o&ved=2ahUKEwizlYTWzdHzAhXMg9gFHTSaBJkQMygAegUIARDaAQ';
o.push(String(i) String(j))
}
newElement.append(img)
checkWinOrDraw(xTurn)
xTurn = !xTurn
}
})
}
}
const td = document.getElementsByTagName('td')
button.addEventListener('click', () => {
reset();
});
function elementIsEmpty(el) {
return (/^(\s| )*$/.test(el.innerHTML));
}
function checkWinOrDraw(xTurn) {
for (let i = 0; i < winPat.length; i ) {
if (xTurn) {
if (winPat[i].every(element => x.includes(element))) {
alert('X wins')
reset()
return
}
} else {
if (winPat[i].every(element => o.includes(element))) {
alert('O wins')
reset()
return
}
}
}
for (let item of td) {
if (elementIsEmpty(item))
return
}
alert('Draw')
reset()
}
function reset() {
x = [];
o = [];
for (let item of td) {
item.textContent = ''
}
}
body {
margin: 0px;
background-color: #3c4552;
color: aliceblue;
text-align: center;
}
header {
height: 75px;
background-color: #1f1e1c;
padding: 20px;
font-size: large;
}
table {
border-collapse: collapse;
margin: 40px auto;
}
td {
border: 7px solid black;
height: 121px;
width: 121px;
cursor: pointer;
}
button {
background-color: #1f1e1c;
color: white;
width: 25%;
height: 50px;
font-size: larger;
border: black solid 2px;
border-radius: 7px;
cursor: pointer;
}
img {
display: block;
width: 100%;
height: 100%;
}
<header>
<h1>TicTacToe</h1>
</header>
<main>
<table>
<tr class="tableR"></tr>
<tr class="tableR"></tr>
<tr class="tableR"></tr>
</table>
</main>
<footer>
<button id="btn">RESET</button>
</footer>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
my problem is that when the game ends, say X wins, the image is not rendered on the screen, and alert() is called. I googled a lot and found no solutions.
details and clarity: the image is not rendered on screen at the end of the game. try on your computer and see. alert() is called before the image is present in-game which results in a bad user experience. hence I need a solution.
CodePudding user response:
Here your append()
function is not able to complete image load & your checkWinOrDraw()
function got called that's why this is happening.
Please try with the below code i am calling the checkWinOrDraw()
once image gets loaded or failed.
for (let i = 0; i <= 2; i ) {
for (let j = 0; j <= 2; j ) {
let newElement = document.createElement('td');
tableR.item(i).appendChild(newElement);
newElement.addEventListener('click', () => {
if (elementIsEmpty(newElement)) {
const img = document.createElement('img');
if (xTurn) {
img.src = 'https://dummyimage.com/20x20/3a4ca6/fff';
x.push(String(i) String(j))
} else {
img.src = 'https://dummyimage.com/30x30/fff/fff';
o.push(String(i) String(j))
}
console.log(xTurn)
xTurn = !xTurn
img.addEventListener('load', checkWinOrDraw)
img.addEventListener('error', checkWinOrDraw)
newElement.appendChild(img)
}
})
}
}
function checkWinOrDraw(e,xTurn) {
//console.log('checking',xTurn)
for (let i = 0; i < winPat.length; i ) {
if (xTurn) {
if (winPat[i].every(element => x.includes(element))) {
alert('X wins')
reset()
return
}
} else {
if (winPat[i].every(element => o.includes(element))) {
alert('O wins')
reset()
return
}
}
}
for (let item of td) {
if (elementIsEmpty(item))
return
}
alert('Draw')
reset()
}
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>