JavaScript Tic Tac Toe Game

In this tutorial, we will learn how to develop an advanced JavaScripttic tac toe game. TheTic-Tac-Toe is a very common game that is fairly easy to play. The rules of the game are simple and well-known.

In this tutorial, we are going to develop the web-based Tic Tac Toe game. In this game, the user is prompted to choose one of the nine squares in the grid. The grid chosen by the player is then shown by the corresponding sign of the player. The first player marksXand the second player marksO.

JavaScript Tic Tac Toe Game

Create a folder calledJavaScript-Tic-Tac-Toe as project workspace and we will create all the project files inside this folder.

1. index.html

Let's createindex.html and add the following code to it:

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><metahttp-equiv="X-UA-Compatible"content="ie=edge"><linkrel="stylesheet"href="style.css"><scriptsrc="script.js"defer></script><title>Document</title></head><body><divclass="board"id="board"><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div><divclass="cell"data-cell></div></div><divclass="winning-message"id="winningMessage"><divdata-winning-message-text></div><buttonid="restartButton">Restart</button></div></body></html>

2. script.js

Let's create JavaScript file namedscript.js and add following JavaScript code to it:

constX_CLASS='x'constCIRCLE_CLASS='circle'constWINNING_COMBINATIONS=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]constcellElements=document.querySelectorAll('[data-cell]')constboard=document.getElementById('board')constwinningMessageElement=document.getElementById('winningMessage')constrestartButton=document.getElementById('restartButton')constwinningMessageTextElement=document.querySelector('[data-winning-message-text]')letcircleTurnstartGame()restartButton.addEventListener('click',startGame)functionstartGame(){circleTurn=falsecellElements.forEach(cell=>{cell.classList.remove(X_CLASS)cell.classList.remove(CIRCLE_CLASS)cell.removeEventListener('click',handleClick)cell.addEventListener('click',handleClick,{once:true})})setBoardHoverClass()winningMessageElement.classList.remove('show')}functionhandleClick(e){constcell=e.targetconstcurrentClass=circleTurn ?CIRCLE_CLASS :X_CLASSplaceMark(cell,currentClass)if(checkWin(currentClass)){endGame(false)}elseif(isDraw()){endGame(true)}else{swapTurns()setBoardHoverClass()}}functionendGame(draw){if(draw){winningMessageTextElement.innerText='Draw!'}else{winningMessageTextElement.innerText=`${circleTurn ?"O's" :"X's"} Wins!`}winningMessageElement.classList.add('show')}functionisDraw(){return[...cellElements].every(cell=>{returncell.classList.contains(X_CLASS)||cell.classList.contains(CIRCLE_CLASS)})}functionplaceMark(cell,currentClass){cell.classList.add(currentClass)}functionswapTurns(){circleTurn= !circleTurn}functionsetBoardHoverClass(){board.classList.remove(X_CLASS)board.classList.remove(CIRCLE_CLASS)if(circleTurn){board.classList.add(CIRCLE_CLASS)}else{board.classList.add(X_CLASS)}}functioncheckWin(currentClass){returnWINNING_COMBINATIONS.some(combination=>{returncombination.every(index=>{returncellElements[index].classList.contains(currentClass)})})}

3. style.css

Let's create a CSS file namedstyle.css and add the following CSS code to it:

*,*::after,*::before {box-sizing: border-box;}:root {--cell-size:100px;--mark-size:calc(var(--cell-size)*.9);}body {margin:0;}.board {width:100vw;height:100vh;display: grid;justify-content: center;align-content: center;justify-items: center;align-items: center;grid-template-columns:repeat(3, auto)}.cell {width:var(--cell-size);height:var(--cell-size);border:1px solid black;display: flex;justify-content: center;align-items: center;position: relative;cursor: pointer;}.cell:first-child,.cell:nth-child(2),.cell:nth-child(3) {border-top: none;}.cell:nth-child(3n+1) {border-left: none;}.cell:nth-child(3n+3) {border-right: none;}.cell:last-child,.cell:nth-child(8),.cell:nth-child(7) {border-bottom: none;}.cell.x,.cell.circle {cursor: not-allowed;}.cell.x::before,.cell.x::after,.cell.circle::before {background-color: black;}.board.x .cell:not(.x):not(.circle):hover::before,.board.x .cell:not(.x):not(.circle):hover::after,.board.circle .cell:not(.x):not(.circle):hover::before {background-color: lightgrey;}.cell.x::before,.cell.x::after,.board.x .cell:not(.x):not(.circle):hover::before,.board.x .cell:not(.x):not(.circle):hover::after {content:'';position: absolute;width:calc(var(--mark-size)*.15);height:var(--mark-size);}.cell.x::before,.board.x .cell:not(.x):not(.circle):hover::before {transform:rotate(45deg);}.cell.x::after,.board.x .cell:not(.x):not(.circle):hover::after {transform:rotate(-45deg);}.cell.circle::before,.cell.circle::after,.board.circle .cell:not(.x):not(.circle):hover::before,.board.circle .cell:not(.x):not(.circle):hover::after {content:'';position: absolute;border-radius:50%;}.cell.circle::before,.board.circle .cell:not(.x):not(.circle):hover::before {width:var(--mark-size);height:var(--mark-size);}.cell.circle::after,.board.circle .cell:not(.x):not(.circle):hover::after {width:calc(var(--mark-size)*.7);height:calc(var(--mark-size)*.7);background-color: white;}.winning-message {display: none;position: fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.9);justify-content: center;align-items: center;color: white;font-size:5rem;flex-direction: column;}.winning-messagebutton {font-size:3rem;background-color: white;border:1px solid black;padding:.25em.5em;cursor: pointer;}.winning-messagebutton:hover {background-color: black;color: white;border-color: white;}.winning-message.show {display: flex;}

Open index.html in Browser

Let's open theindex.html file in the browser and you will be able to see the following screen:

More Free JavaScript Projects with Source Code


Comments