Build Tic Tac Toe Game Using JavaScript
Tags: Web Development, CSS, Programming, HTML, JavaScript

handleCellClick

In handleCellClick, we have to handle two things. Fist we have to check if the cell has been already clicked. If not continue our game play.

Let’s see how it looks like.

function handleCellClick(clickedCellEvent) {

/*

We will save the clicked html element in a variable for easier further use

*/

const clickedCell = clickedCellEvent.target;

/*

Here we will grab the 'data-cell-index' attribute from the clicked cell to identify where that cell is in our grid.

Please note that the getAttribute will return a string value. Since we need an actual number we will parse it to an

integer(number)

*/

const clickedCellIndex = parseInt(

clickedCell.getAttribute('data-cell-index')

);

/*

Next up we need to check whether the call has already been played,

or if the game is paused. If either of those is true we will simply ignore the click.

*/

if (gameState[clickedCellIndex] !== "" || !gameActive) {

return;

}

/*

If everything if in order we will proceed with the game flow

*/

handleCellPlayed(clickedCell, clickedCellIndex);

handleResultValidation();

}

handleCellPlayed

In this handler, we have to update two things. First update our ge state and then user interface.

function handleCellPlayed(clickedCell, clickedCellIndex) {

/*

We update our internal game state to reflect the played move,

as well as update the user interface to reflect the played move

*/

gameState[clickedCellIndex] = currentPlayer;

clickedCell.innerHTML = currentPlayer;

}

We accept only currently clicked cell and index of the cell that is clicked.

handleResultValidation

The result validation is the core of our tic tac toe game. Here only we will check whether the game end with win or draw.

Let’s start checking ifcurrent player won the game.

const winningConditions = [

[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 handleResultValidation() {

let roundWon = false;

for (let i = 0; i <= 7; i++) {

const winCondition = winningConditions[i];

let a = gameState[winCondition[0]];

let b = gameState[winCondition[1]];

let c = gameState[winCondition[2]];

if (a === '' || b === '' || c === '') {

continue;

}

if (a === b && b === c) {

roundWon = true;

break

}

}

if (roundWon) {

statusDisplay.innerHTML = winningMessage();

gameActive = false;

return;

}

}

Let’s check the other condition if the game has ended with draw. The way in which the game is ended in draw under certain conditions.

const winningConditions = [

[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 handleResultValidation() {

let roundWon = false;

for (let i = 0; i <= 7; i++) {

const winCondition = winningConditions[i];

let a = gameState[winCondition[0]];

let b = gameState[winCondition[1]];

let c = gameState[winCondition[2]];

if (a === '' || b === '' || c === '') {

continue;

}

if (a === b && b === c) {

roundWon = true;

break

}

}

if (roundWon) {

statusDisplay.innerHTML = winningMessage();

gameActive = false;

return;

}

/*

We will check weather there are any values in our game state array

that are still not populated with a player sign

*/

let roundDraw = !gameState.includes("");

if (roundDraw) {

statusDisplay.innerHTML = drawMessage();

gameActive = false;

return;

}

/*

If we get to here we know that the no one won the game yet,

and that there are still moves to be played, so we continue by changing the current player.

*/

handlePlayerChange();

}

handlePlayerChange

This will change the current player and update the game status. Here we are using ternary operator to assign the value to the new player.

function handlePlayerChange() {

currentPlayer = currentPlayer === "X" ? "O" : "X";

statusDisplay.innerHTML = currentPlayerTurn();

}

handleRestartGame

This will set all our game tracking back into default. It clear all sings in the game board and update the game status into the current player message.