I tried to write a simple tic tac toe game. When I was coding I encounter a weird "bug" I would say? A function called "isWinner" checks if someone won. It compares one array called "winningCombinations" with a combination which it gets. The thing is that code should show "winner chicken dinner" immediately after it finds the winning combination. Well, It doesn't. It shows it up after 3 additional moves. I don't have any idea what's wrong, so I will appreciate any help. Thanks in advance. Oh, and here is the code:
Codepen: https://codepen.io/vivmaha/pen/abJNBzX
const turndiv = document.getElementById('turn');
const board = document.getElementById('board');
const boxes = document.querySelectorAll('.boxes');
const winningCombinations = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 4, 7],
[2, 5, 8],
[3, 6, 9],
[1, 5, 9],
[3, 5, 7]
];
let claimedcells = new Array();
let xturn = true;
/* Those variables will have X and O combinations separetly */
let xcombination = new Array();
let ocombination = new Array();
let turn = xcombination;
/* Add event listeners to every cell */
boxes.forEach(cell => {
cell.addEventListener('click', handleCellClick);
});
/* Handles cell, at this stage is confirmed, that this cell has ben clicked for first time */
function handleCellPlayed(cell, value) {
if(xturn) {
cell.textContent = 'x';
xturn = false;
xcombination.push(value);
}
else {
cell.textContent = 'o';
xturn = true;
ocombination.push(value);
}
}
/* Handles click on any cell */
function handleCellClick() {
if(xturn) {
if(isWinner(xcombination)) {
alert('winner chicken dinner');
}
}
else if(isWinner(ocombination)) {
alert('winner chicken dinner');
}
let clickedcell = this.getAttribute('value');
let freeCell = isCellFree(clickedcell);
if(freeCell) {
handleCellPlayed(this, this.getAttribute('value'));
claimedcells.push(clickedcell);
}
}
/* Checks is Cell free */
function isCellFree(cell) {
let freeCell = true;
for(i=0; i<claimedcells.length; i++) {
let claimedcell = claimedcells[i];
if(cell == claimedcell) {
freeCell = false;
}
}
return freeCell;
}
/* Check if game has winner */
function isWinner(usercombination) {
let winner = false;
winningCombinations.forEach(combination => {
let a = combination[0] + "";
let b = combination[1] + "";
let c = combination[2] + "";
if(usercombination.includes(a) && usercombination.includes(b) && usercombination.includes(c)) {
winner = true;
}
});
return winner;
}
body {
background-color:azure;
}
.container {
min-width: 100%;
min-height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#gameholder {
width: 30vw;
background-color: beige;
padding: 10px;
text-align: center;
}
#board {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
flex-basis: 33.333333%;
text-transform: uppercase;
font-weight: bold;
font-size: 100px;
}
.boxes {
width: 31%;
height: 8vw;
border: 0.5px black solid;
}
.boxes:first-child, .boxes:nth-child(2), .boxes:nth-child(3) {
border-top: none;
}
.boxes:first-child, .boxes:nth-child(4), .boxes:nth-child(7) {
border-left: none;
}
.boxes:nth-child(7), .boxes:nth-child(8), .boxes:nth-child(9) {
border-bottom: none;
}
.boxes:nth-child(3),
.boxes:nth-child(6),
.boxes:nth-child(9) {
border-right: none;
}
<body>
<div class="container">
<div id="gameholder">
<!-------Current turn-------------->
<div id="turn">
<h1>X turn!</h1>
</div>
<!--- Game board --->
<div id="board">
<div class="boxes" value='1'></div>
<div class="boxes" value='2'></div>
<div class="boxes" value='3'></div>
<div class="boxes" value='4'></div>
<div class="boxes" value='5'></div>
<div class="boxes" value='6'></div>
<div class="boxes" value='7'></div>
<div class="boxes" value='8'></div>
<div class="boxes" value='9'></div>
</div>
<div id="time"></div>
</div>
</div>
<script src="game.js" async></script>
</body>
You had 2 issues here,
Below I'v modified to fix both.
I did a simple xturn = !xturn;
to flip the user after working out if they had won.
const turndiv = document.getElementById('turn');
const board = document.getElementById('board');
const boxes = document.querySelectorAll('.boxes');
const winningCombinations = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[1, 4, 7],
[2, 5, 8],
[3, 6, 9],
[1, 5, 9],
[3, 5, 7]
];
let claimedcells = new Array();
let xturn = true;
/* Those variables will have X and O combinations separetly */
let xcombination = new Array();
let ocombination = new Array();
let turn = xcombination;
/* Add event listeners to every cell */
boxes.forEach(cell => {
cell.addEventListener('click', handleCellClick);
});
/* Handles cell, at this stage is confirmed, that this cell has ben clicked for first time */
function handleCellPlayed(cell, value) {
if(xturn) {
cell.textContent = 'x';
//xturn = false;
xcombination.push(value);
}
else {
cell.textContent = 'o';
//xturn = true;
ocombination.push(value);
}
}
/* Handles click on any cell */
function handleCellClick() {
let clickedcell = this.getAttribute('value');
let freeCell = isCellFree(clickedcell);
if(freeCell) {
handleCellPlayed(this, this.getAttribute('value'));
if(xturn) {
if(isWinner(xcombination)) {
alert('winner chicken dinner');
}
}
else if(isWinner(ocombination)) {
alert('winner chicken dinner');
}
xturn = !xturn;
claimedcells.push(clickedcell);
}
}
/* Checks is Cell free */
function isCellFree(cell) {
let freeCell = true;
for(i=0; i<claimedcells.length; i++) {
let claimedcell = claimedcells[i];
if(cell == claimedcell) {
freeCell = false;
}
}
return freeCell;
}
/* Check if game has winner */
function isWinner(usercombination) {
let winner = false;
winningCombinations.forEach(combination => {
let a = combination[0] + "";
let b = combination[1] + "";
let c = combination[2] + "";
if(usercombination.includes(a) && usercombination.includes(b) && usercombination.includes(c)) {
winner = true;
}
});
return winner;
}
body {
background-color:azure;
}
.container {
min-width: 100%;
min-height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#gameholder {
width: 30vw;
background-color: beige;
padding: 10px;
text-align: center;
}
#board {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
flex-basis: 33.333333%;
text-transform: uppercase;
font-weight: bold;
font-size: 100px;
}
.boxes {
width: 31%;
height: 8vw;
border: 0.5px black solid;
}
.boxes:first-child, .boxes:nth-child(2), .boxes:nth-child(3) {
border-top: none;
}
.boxes:first-child, .boxes:nth-child(4), .boxes:nth-child(7) {
border-left: none;
}
.boxes:nth-child(7), .boxes:nth-child(8), .boxes:nth-child(9) {
border-bottom: none;
}
.boxes:nth-child(3),
.boxes:nth-child(6),
.boxes:nth-child(9) {
border-right: none;
}
<body>
<div class="container">
<div id="gameholder">
<!-------Current turn-------------->
<div id="turn">
<h1>X turn!</h1>
</div>
<!--- Game board --->
<div id="board">
<div class="boxes" value='1'></div>
<div class="boxes" value='2'></div>
<div class="boxes" value='3'></div>
<div class="boxes" value='4'></div>
<div class="boxes" value='5'></div>
<div class="boxes" value='6'></div>
<div class="boxes" value='7'></div>
<div class="boxes" value='8'></div>
<div class="boxes" value='9'></div>
</div>
<div id="time"></div>
</div>
</div>
<script src="game.js" async></script>
</body>