I am making a simple Tic Tac Toe game in JavaScript, I've got it completely working, but one problem, sometimes it states that a win for a player is a draw between the players, I don't know why it happens, though I have the suspicion that it is because it isn't finding the win. After all, it has only ever happened when the win is coming from when all 9 squares are filled. There for, my script is most likely reading it in a way where it just states that it is a draw if all 9 cells are filled regardless of the content in the cells. However, I just can't seem to see why it is like this.
Here is my check for the win function:
function checkForWin() {
for (let on=0; on<data.pieces.length; on++) {
var onThis = data.pieces[on];
var love = 0;
for (let i=0; i<data.winCond.length; i++) {
var wit = data.winCond[i];
if (data.filledCells[wit[0]][1]==onThis&&data.filledCells[wit[1]][1]==onThis&&data.filledCells[wit[2]][1]==onThis) {
endGame(onThis);
} else {
love=i;
}
}
if (on==(data.pieces.length-1)) {
if (love==(data.winCond.length-1)&&data.filledCells[9]) {
endGame("XO");
}
}
}
}
It should be noted that every time one of the cells is clicked on the checkForWin()
function is called.
data.winCond
is all 8 possible win conditions, each win condition is represented in an array of three numbers, data.pieces
is obviously the 'X' and the 'O'. While the data.filledCells
is representing the 9 cells. So here is the data variable:
const data = { // All the data of the game
gameSet: "In Game", // For stating who won the game or if it ended in a draw, is to be stated as "In Game" when the game is still in session
nextTurn: true, // What player is playing (true for player 1, while false is for player 2)
filledCells: [ // The script representation of the cells
[false,""], // Cell 1
[false,""], // Cell 2
[false,""], // Cell 3
[false,""], // Cell 4
[false,""], // Cell 5
[false,""], // Cell 6
[false,""], // Cell 7
[false,""], // Cell 8
[false,""], // Cell 9
false // This is only true if all cells are filled
],
pieces: ["X","O"], // The pieces
winCond: [ // The win conditions
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 4, 6],
[2, 5, 8],
[3, 4, 5],
[6, 7, 8]
]
};
Here is a jsfiddle: https://jsfiddle.net/Officer_Erik_1K88/kxv4307L/18/
That fiddle has the full code to the Tic Tac Toe thing.
To replicate my problem just fill the full board up, making sure that you've set it up so that the last 'X' or 'O' is placed will be a win, though it will display it to be a draw.
Of course you can also view the problem here in the following snippet:
const data = { // All the data of the game
gameSet: "In Game", // For stating who won the game or if it ended in a draw, is to be stated as "In Game" when the game is still in session
nextTurn: true, // What player is playing (true for player 1, while false is for player 2)
filledCells: [ // The script representation of the cells
[false,""], // Cell 1
[false,""], // Cell 2
[false,""], // Cell 3
[false,""], // Cell 4
[false,""], // Cell 5
[false,""], // Cell 6
[false,""], // Cell 7
[false,""], // Cell 8
[false,""], // Cell 9
false // This is only true if all cells are filled
],
pieces: ["X","O"], // The pieces
winCond: [ // The win conditions
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 4, 6],
[2, 5, 8],
[3, 4, 5],
[6, 7, 8]
]
};
var cellItems = document.querySelectorAll('.cell'); // The call for all the cells
function endGame(winnr) { // This function ends the game
if (winnr==data.pieces[0]) { // If winnr equals 'X' then Player 1 wins
data.gameSet = "Player 1 Won";
} else if (winnr==data.pieces[1]) { // If winnr equals 'O' then Player 2 wins
data.gameSet = "Player 2 Won";
} else if (winnr=="XO") { // If winnr equals 'XO' then nether Player wins
data.gameSet = "Draw";
}
console.log("Winner: "+data.gameSet);
}
function checkForWin() { // This is the function that checks for wins/draw
for (let on=0; on<data.pieces.length; on++) {
var onThis = data.pieces[on];
var love = 0;
for (let i=0; i<data.winCond.length; i++) {
var wit = data.winCond[i];
if (data.filledCells[wit[0]][1]==onThis&&data.filledCells[wit[1]][1]==onThis&&data.filledCells[wit[2]][1]==onThis) {
endGame(onThis);
} else {
love=i;
}
}
if (on==(data.pieces.length-1)) {
if (love==(data.winCond.length-1)&&data.filledCells[9]) {
endGame("XO");
}
}
}
}
function turn() { // This checks who's turn it is and will out put the respective piece
if (data.nextTurn) { // if nextTurn is true then player 1 plays
data.nextTurn=false;
return data.pieces[0];
} else {
data.nextTurn=true;
return data.pieces[1];
}
}
function checkCellFill() { // This checks if all cells are filled
for (let i=0; i<9; i++) {
if (data.filledCells[i][0]) {
data.filledCells[9]=true;
} else {
data.filledCells[9]=false;
break;
}
}
}
function curCellClick() { // This function is used to set the cells click function
for (let i=0; i<cellItems.length; i++) {
cellItems[i].onclick = function() {
if (data.filledCells[i][1]==""&&data.gameSet=="In Game") {
var ins = turn();
cellItems[i].innerHTML = ins;
data.filledCells[i][0] = true;
data.filledCells[i][1] = ins;
checkCellFill();
checkForWin();
}
};
}
}
curCellClick();
#board {
display: inline-grid;
grid-template-columns: auto auto auto;
background-color: #bfbfbf;
gap: 10px;
padding: 10px;
}
.cell {
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 80px;
background-color: #e8e8e8;
cursor: pointer;
}
<div id="board">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>