Tic Tac Toe Game



Tic Tac Toe is well-known two square board game in which two players have to put their mark on certain spaces in turns. The player that gets three of their marks in a row either in a horizontal, vertical, or diagonal manner wins that game. If all turns are used and no player gets the line, then the draw is the end of the game.

In this article, we will see how to build a Tic Tac Toe game in plain HTML, CSS, and JavaScript. The code allows a two-player mode game and additional features including the Reset button, an Undo button, and an option for the system to decide who the winner is.

Steps to Build Tic Tac Toe Game

  • HTML Structure ? A basic 3x3 cube is being generated using only a div structure, Where each of the grid items depicts a cell that can be filled in by a player's turn.
  • CSS Layout ? The board and other UI elements are constructed with flexbox and grid and the gradient and hover effects are being provided to give an attractive view of the layout. And here a media queries helps in crafting a good layout for the small screens as well.
  • Game Initialization ? Firstly the P1, moves, and choice are Javascript variables that are declared to hold current state variables in the game.
  • Reset Game ? The resetGame function implemented in the code will erase the board, re-enable all buttons again, and reset the turn to Player 1. It also reloads the page so that it is a new page.
  • Undo Move ? The undoMove function decrements the currentMove and reverses the change made to the cell of the previous move while also changing the turn to the player who made the previous move.
  • Marking Cells ? Another function called box function controls player turns. It draws an "X" or "O" into the selected cell, writes the cell under protected mode, and passes the turn to the other player.
  • Checking for Winner ? The checkResult function analyzes all the possibilities of win conditions with the help of a predefined array of win combinations. If anyone gets a winner then the game is over, all further moves are disabled and a sound is also produced.
  • Sound Effects ? There are audio files playing a victory or tie music depending on the score of the game they are associated with.
  • Pop-up Functionality ? A condition of JavaScript functions governs the display of the rules of the game in the pop-up window as well as alerts when the game is finished.
  • Responsive Design ? Today, CSS media queries allow the game board to shrink down and stay fully navigable on smaller devices while keeping the game mobile.

HTML Code

Here is an HTML code for the Tic Tac Toe game, providing basic structure and layouts for the game.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Tic Tac Toe" />
<meta property="og:type" content="website" />
<meta property="og:description" content="Play Tic Tac Toe Game online!" />
<meta property="og:image" content="./assets/Images/image.png" />
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="./assets/css/index.css" />
<link rel="icon" href="./assets/Images/tic-tac-toe.png" type="image/x-icon">
<audio id="win">
<source src="./assets/sound/winsound.mp3" type="audio/mpeg">
</audio>
<audio id="tie">
<source src="./assets/sound/gametie.mp3" type="audio/mpeg">
</audio>
</head>
<body>
<div class="parent">
   <h1 class="title">Tic Tac Toe Game</h1>
   <div class="playground">
      <button class="box" id="box1" onclick="box(1)"></button>
      <button class="box" id="box2" onclick="box(2)"></button>
      <button class="box" id="box3" onclick="box(3)"></button>
      <button class="box" id="box4" onclick="box(4)"></button>
      <button class="box" id="box5" onclick="box(5)"></button>
      <button class="box" id="box6" onclick="box(6)"></button>
      <button class="box" id="box7" onclick="box(7)"></button>
      <button class="box" id="box8" onclick="box(8)"></button>
      <button class="box" id="box9" onclick="box(9)"></button>
   </div>
   <div class="btn-container">
      <button type="button" class="feature-btn" title="Undo" onclick="undoMove()">
         <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-arrow-return-left" viewBox="0 0 16 16">
            <path fill-rule="evenodd" d="M14.5 1.5a.5.5 0 0 1 .5.5v4.8a2.5 2.5 0 0 1-2.5 2.5H2.707l3.347 3.346a.5.5 0 0 1-.708.708l-4.2-4.2a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 8.3H12.5A1.5 1.5 0 0 0 14 6.8V2a.5.5 0 0 1 .5-.5z" />
         </svg>
      </button>
      <button type="button" class="feature-btn" title="Reset" onclick="resetGame()">
         <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-arrow-repeat" viewBox="0 0 16 16">
            <path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z" />
            <path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z" />
         </svg>
      </button>
   </div>
   <h1 id="result">1st Player Turn</h1>
   <!-- Add Reset and Undo buttons -->
   <div class="container">
      <button type="button" class="btn" onclick="openPopup()">Rules</button>
   </div>
   <div class="popup" id="popup">
      <h2>Rules:</h2>
      <ol>
         <li>The game is played on a grid that's 3 squares by 3 squares.</li>
         <li>Player 1 is X and Player 2 is O. Players take turns putting their marks in empty squares.</li>
         <li>The first player to get 3 of his marks in a row (up, down, across, or diagonally) is the winner.</li>
         <li>When all 9 squares are full, the game is over. If no player has 3 marks in a row, the game ends in a tie.</li>
      </ol>
      <button type="button" onclick="closePopup()">OK</button>
   </div>
</div>
<script src="./assets/js/script.js"></script>
</body>
</html>

CSS Code

Here is a CSS code for the Tic Tac Toe game, defining its layout, colors, and appearance of the game board and its elements.

/* "Roboto" font from google fonts*/
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");

*,
*::after,
*::before {
   box-sizing: border-box;
   font-family: inherit;
}

:root {
   --boardbg: #dcf5ff;
   --aliceblue: aliceblue;
}

body {
   margin: 0;
   padding: 0;
   background-image: linear-gradient(10deg, #ec5e00, #ffffff 38%, #17cc06ef);
   font-family: "Roboto", sans-serif;
   background-attachment: fixed;
}

.parent {
   display: flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   height: 100vh;
}

.playground {
   display: grid;
   grid-template-columns: auto auto auto;
   box-shadow: 0 10px 20px rgba(43, 41, 41, 0.2);
   border: 1px solid rgb(255, 255, 255);
   border-width: 2px;
   padding: 10px;
   justify-content: center;
   border-radius: 1rem;
   border-radius: 5px;
   margin-top: 30px;
}

.box {
   background-color: rgb(35, 134, 255);
   border: 1px solid #ffffff;
   border-width: 2px;
   border-radius: 5px;
   padding: 2px;
   margin: 2px;
   width: 7rem;
   height: 7rem;
   text-align: center;
   font-size: 50px;
   font-weight: bold;
   transition: background-color 0.2s ease-in-out;
}

.box:hover {
   background-color: rgb(210, 244, 244);
}

.box:active {
   background-color: rgb(6, 116, 116);
   border-radius: 5px;
   margin: 0;
}

.title {
   background: linear-gradient(75deg, #00e1ff88, #6f00ff73 48%, #ff686871);
   border-radius: 10px;
   padding: 5px 28px;
   font-size: 2.5rem;
   margin-top: 10vh;
   margin-bottom: 2vh;
   text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.444);
   border-top: 1px solid white;
   border-bottom: 1px solid white;
   text-transform: uppercase;
   background-image: linear-gradient(75deg, #00e0ff, #7000ff 48%, #ff6868);
   background-clip: border-box;
   background-size: 200% auto;
   color: #fff;
   background-clip: text;
   text-fill-color: transparent;
   -webkit-background-clip: text;
   -webkit-text-fill-color: transparent;
   animation: textclip 2s linear infinite;
   display: inline-block;
}
@keyframes textclip {
   to {
      background-position: 300% center;
   }
}

h1 {
   background-color: #00e0ff;
   background-image: linear-gradient(75deg, #00e0ff, #7000ff 48%, #ff6868);
   border: 0.5 thin black;
   background-repeat: no-repeat;
   border-radius: 10px;
   color: black;
   font-size: 2rem;
   text-align: center;
   padding: 0.5rem;
}

#result {
   background-color: transparent;
   background-image: none;
   background-clip: text;
   color: #00fff2;
   margin-top: -10px;
}

.container {
   padding: auto;
   text-align: center;
   margin-top: auto;
   position: relative;
   height: 10px;
   width: 100%;
}

.btn {
   padding: 20px 60px;
   background-color: rgb(216, 180, 234);
   border: 0;
   outline: none;
   cursor: pointer;
   font-size: 22px;
   font-weight: 500;
   border-radius: 30px;
   position: absolute;
   right: 30px;
   bottom: 50px;
}

.btn:hover {
   background-color: rgb(203, 153, 228);
}

.feature-btn {
   padding: 14px 12px 9px 12px;
   background-color: rgb(182, 243, 248);
   border: 0;
   outline: none;
   cursor: pointer;
   font-size: 22px;
   font-weight: 500;
   border-radius: 30px;
   position: relative;
}

.feature-btn:hover {
   background-color: rgb(132, 206, 247);
}

.btn-container {
   position: relative;
   top: 1rem;
   width: 25%;
   display: flex;
   flex-direction: row;
   justify-content: space-between;
}

.popup {
   min-width: 600px;
   background: rgb(169, 121, 193);
   border-radius: 5px;
   position: absolute;
   top: 0;
   left: 50%;
   transform: translate(-50%, -50%) scale(0.1);
   font-size: 19px;
   padding: 0 30px 30px;
   visibility: hidden;
   transition: transform 0.4s, top 0.4s;
   transition: transform 0.4s, top 0.4s, visibility 0.4s;
}

.popup h2 {
   font-size: 30px;
   font-weight: 500;
   margin: 30px 0 10px;
}

.popup button {
   width: 100%;
   margin-top: 30px;
   padding: 10px 0;
   background-color: #ff6868;
   color: white;
   border: 0;
   outline: none;
   font-size: 18px;
   border-radius: 4px;
   cursor: pointer;
}

.popup button:hover {
   background: #ee4e4e;
}

.open-popup {
   visibility: visible;
   top: 50%;
   transform: translate(-50%, -50%) scale(1);
   transition: all 0.5s ease-in-out;
}

.popup ol li {
   font-size: 1rem;
   margin-bottom: 15px;
   line-height: 0.95;
}

/*Mobile screen styles*/
@media (max-width: 600px) {
   .title {
      font-size: 2.2rem;
      margin-bottom: 7vh;
   }
   .box {
      width: 6rem;
      height: 6rem;
      font-size: 40px;
   }
   .btn {
      padding: 10px 30px;
      font-size: 15px;
   }
   .popup {
      min-width: 400px;
      padding: 0 10px 20px 10px;
   }
   .popup h2 {
      font-size: 20px;
   }
}

JavaScript Code

Here is the given JavaScript code implementing the logic and interactivity for the Tic Tac Toe game.

let P1 = true;
let moves = [];
let choice = [null, null, null, null, null, null, null, null, null];
let emptyCells = 9;
// Function to reset the game
function resetGame() {
   P1 = true;
   emptyCells = 9;
   moves = [];
   choice = [null, null, null, null, null, null, null, null, null];
   document.getElementById("result").innerHTML = "1st Player Turn";
   for (let i = 1; i <= 9; i++) {
      const button = document.getElementById("box" + i);
      button.innerHTML = "";
      button.disabled = false;
   }
   window.location.reload();
}

// Function to undo the last move
function undoMove() {
   if (moves.length > 0) {
      const idx = moves.pop(); // Get the most recent move
      const button = document.getElementById("box" + idx);
      button.innerHTML = "";
      button.disabled = false;
      choice[idx - 1] = "-";
      P1 = !P1;
      document.getElementById("result").innerHTML = P1
         ? "1st Player Turn"
         : "2nd Player Turn";
   }
}

// Function to mark cells on board
function box(idx) {
   let pos = idx - 1;
   if (choice[pos] == null) {
      let cell = document.getElementById("box" + idx);
      cell.innerHTML = P1 ? "X" : "O";
      choice[pos] = P1 ? "X" : "O";
      moves.push(idx);
      emptyCells = emptyCells - 1;
      P1 = !P1;
      document.getElementById("result").innerHTML = P1
         ? "1st Player Turn"
         : "2nd Player Turn";
      checkResult();
   }
}

// Helper function to get the coordinates of the last move
function getLastMove() {
   for (let row = 2; row >= 0; row--) {
      for (let col = 2; col >= 0; col--) {
         if (choice[row][col] !== "-") {
            return [row, col];
         }
      }
   }
   return null; // No moves made yet
}

// Function to FindWinner
function checkResult() {
   let checkWinner = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6],
   ];
   let isAnyoneWins = false;
   for (const element of checkWinner) {
      const [a, b, c] = element;
      if (choice[a] && choice[a] === choice[b] && choice[b] === choice[c]) {
         playWinSound();
         let resultText = choice[a] == "X" ? "Player 1 Win" : "Player 2 Win";
         document.getElementById("result").innerHTML = resultText;
         for (let i = 1; i <= 9; i++) {
            let boardCell = document.getElementById("box" + i);
            boardCell.disabled = true;
         }
         isAnyoneWins = true;
         setTimeout(resetGame, 4000);
         return;
      }
   }
   if (!isAnyoneWins && emptyCells == 0) {
      document.getElementById("result").innerHTML = "It's a Draw!";
      playTieSound();
      setTimeout(resetGame, 4000);
   }
}

// Function to play the win sound
function playWinSound() {
   let winSound = document.getElementById("win");
   winSound.play(); // Play the win sound
}

// Function to play the tie sound
function playTieSound() {
   let tieSound = document.getElementById("tie");
   tieSound.play(); // Play the tie sound
}

let popup = document.getElementById("popup");
function openPopup() {
   popup.classList.add("open-popup");
}
function closePopup() {
   popup.classList.remove("open-popup");
   popup.classList.add("fade-out");
   setTimeout(() => {
      popup.classList.remove("visible");
      popup.classList.remove("fade-out");
   }, 1000);
}

Conclusion

From this implementation of Tic Tac Toe one can learn how the main technologies such as HTML, CSS, and JavaScript can be put together to make a fun game. The game is very easy to expand as all you'll need to add is the next feature in the list - score or opponent AI. With this knowledge of how to manipulate the DOM and handle the game logic, you can use and improve on this knowledge to develop other browser-based games or browser-based applications.

Updated on: 2025-01-30T11:09:13+05:30

486 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements