I’ve been messing around with some vanilla JS, having gotten too used to frameworks, and was building a simple TicTacToe game, and I am stuck on a certain piece of the win logic and switch players logic. Here is the code (hopefully it’s not too long):
const GameBoard = (() => {
const board = Array(9).fill("");
const getBoard = () => board;
const resetBoard = () => board.fill("");
const setBoard = (symbol, index) =>
board.forEach(() => (board[index] === "" ? (board[index] = symbol) : ""));
const checkForWinner = () => {
const winningCombinations = [
[0, 1, 2], // Top row
[3, 4, 5], // Middle row
[6, 7, 8], // Bottom row
[0, 3, 6], // Left column
[1, 4, 7], // Middle column
[2, 5, 8], // Right column
[0, 4, 8], // Diagonal from top-left to bottom-right
[2, 4, 6], // Diagonal from top-right to bottom-left
];
for (const combo of winningCombinations) {
const [a, b, c] = combo;
if (
getBoard()[a] &&
getBoard()[a] === getBoard()[b] &&
getBoard()[a] === getBoard()[c]
) {
return true;
}
}
return false;
};
return { checkForWinner, getBoard, resetBoard, setBoard };
})();
const players = () => {
const activePlayers = [
{
name: "Player 1 (X)",
symbol: "X",
active: true,
},
{
name: "Player 2 (O)",
symbol: "O",
active: false,
},
];
const getActivePlayer = () => activePlayers.find((player) => player.active);
const switchPlayers = () =>
activePlayers.forEach((player) => (player.active = !player.active));
return { getActivePlayer, switchPlayers };
};
(() => {
const gameBoardContainer = document.querySelector("#game-board");
const { checkForWinner, getBoard, setBoard } = GameBoard;
const { getActivePlayer, switchPlayers } = players();
let button;
for (let i = 0; i < getBoard().length; i++) {
button = document.createElement("button");
gameBoardContainer.appendChild(button);
}
document.querySelectorAll("button").forEach((button, index) => {
button.addEventListener("click", () => {
if (getBoard()[index] === "" && !checkForWinner()) {
setBoard(getActivePlayer().symbol, index);
button.textContent = getActivePlayer().symbol;
switchPlayers();
}
if (checkForWinner()) {
console.log(`${getActivePlayer().name} has won!`);
return;
}
});
});
})();
My issue is specifically in the addEventListener of the button elements. The logic to check for a winner seems to work, but for some reason, when I am console.logging the active player winner, it actually logs the incorrect user for the win. If I have all X, then it logs that O is the winner, and vice versa. It’s something to do with the switchPlayers functionality I’m assuming, but not sure exactly where it’s failing and why.
Anyone offer any thoughts? Thank you…!
EDIT: And for reference, here is the corresponding HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Tic Tac Toe</title>
</head>
<body>
<div id="game-board"></div>
<script src="script.js"></script>
</body>
</html>