Open In App

Simple Tic-Tac-Toe Game using JavaScript

Last Updated : 06 Feb, 2025
Suggest changes
Share
Like Article
Like
Report

This is a simple and interactive Tic Tac Toe game built using HTML, CSS, and JavaScript. Players take turns to mark X and O on the grid, with automatic win detection and the option to reset or start a new game.

What We’re Going to Create

  • Players take turns marking X and O on a 3x3 grid, with real-time interaction.
  • The game checks for a winner or a draw, displaying messages accordingly.
  • The layout adapts to different screen sizes, with a reset button to start a new game.

Project Preview

Screenshot-2025-01-25-125249
Simple Tic-Tac-Toe Game using JavaScript

Simple Tic-Tac-Toe Game - HTML and CSS Code

This Tic Tac Toe game features a simple yet interactive design, allowing two players to take turns marking X and O on a 3x3 grid. The layout is responsive, with a reset button to restart the game.

HTML
<html> <head> <style>  * {  margin: 0;  padding: 0;  }  body {  background-color: lightcyan;  text-align: center;  }  .container {  height: 70vh;  display: flex;  justify-content: center;  align-items: center;  }  .game {  height: 60vmin;  width: 60vmin;  display: flex;  flex-wrap: wrap;  gap: 1.5vmin;  justify-content: center;  }  .box {  height: 18vmin;  width: 18vmin;  border-radius: 1rem;  border: none;  box-shadow: 0 0 1rem rgba(0, 0, 0, 0.3);  font-size: 8vmin;  color: red;  background-color: yellow;  }  #reset {  padding: 1rem;  font-size: 1.25rem;  background: #191913;  color: white;  border-radius: 1rem;  border: none;  }  .box:hover {  background-color: chocolate;  }  #new-btn {  padding: 1rem;  font-size: 1.25rem;  background: #191913;  color: white;  border-radius: 1rem;  border: none;  }  #msg {  font-size: 8vmin;  }  .msg-container {  height: 30vmin;  }  .hide {  display: none;  }  </style> </head> <body> <div class="msg-container hide"> <p id="msg">Winner</p> <button id="new-btn">New Game</button> </div> <main> <h1>Tic Tac Toe</h1> <div class="container"> <div class="game"> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> </div> </div> <button id="reset">Reset Game</button> </main> </body> </html> 

In this example

  • The game board is a flexbox-based grid inside a .container, ensuring a centered and responsive design.
  • Buttons for each cell have hover effects, rounded corners, and shadows, enhancing user experience.
  • The winner message container (.msg-container) is hidden by default and appears when the game ends, with buttons to start a new game or reset.

Simple Tic-Tac-Toe Game - JavaScript code

The JavaScript code manages the gameplay of Tic Tac Toe, including alternating turns, detecting winners based on patterns, and handling game resets.

JavaScript
let boxes = document.querySelectorAll('.box'); let resetBtn = document.querySelector('#reset'); let turnO = true; // Player O starts let newGameBtn = document.querySelector('#new-btn'); let msgContainer = document.querySelector('.msg-container'); let msg = document.querySelector('#msg'); const winPatterns = [  [0, 1, 2],  [0, 3, 6],  [0, 4, 8],  [1, 4, 7],  [2, 5, 8],  [2, 4, 6],  [3, 4, 5],  [6, 7, 8] ]; boxes.forEach((box) => {  box.addEventListener('click', function () {  if (turnO) {  box.innerText = 'O';  box.style.color = 'green';  turnO = false;  box.disabled = true;  checkWinner();  } else {  box.innerText = 'X';  box.style.color = 'black';  turnO = true;  box.disabled = true;  checkWinner();  }  }); }); const enableBoxes = () => {  for (let box of boxes) {  box.disabled = false;  box.innerText = "";  } }; const disableBoxes = () => {  for (let box of boxes) {  box.disabled = true;  } }; const showWinner = (winner) => {  msg.innerText = `Congratulations, Winner is ${winner}`;  msgContainer.classList.remove('hide');  disableBoxes(); }; const checkWinner = () => {  let hasWin = false;  for (let pattern of winPatterns) {  let pos1Val = boxes[pattern[0]].innerText;  let pos2Val = boxes[pattern[1]].innerText;  let pos3Val = boxes[pattern[2]].innerText;  if (pos1Val !== "" && pos2Val!=="" && pos3Val!==""   && pos1Val === pos2Val && pos2Val === pos3Val) {  showWinner(pos1Val);  hasWin = true;  return;  }  }  if (!hasWin) {  const allBoxes = [...boxes].every((box) => box.innerText !== "");  if (allBoxes) {  msgContainer.classList.remove('hide');  msg.innerText = 'Match Drawn';  }  } }; const resetGame = () => {  turnO = true;  enableBoxes();  msgContainer.classList.add('hide'); }; newGameBtn.addEventListener('click', resetGame); resetBtn.addEventListener('click', resetGame); 

In this example

  • The turnO variable tracks the player, placing 'X' or 'O' on each button click and switching turns.
  • box.addEventListener('click', …) detects clicks, marks the cell, and checks for a winner after each move.
  • checkWinner() scans predefined win patterns to see if any row, column, or diagonal has three identical marks.
  • resetGame() clears the board, re-enables boxes, and hides the winner message for a fresh start.
  • showWinner() reveals the winning message, disables all grid buttons, and stops further moves.

Simple Tic-Tac-Toe Game - Complete code

HTML
<html> <head> <style>  * {  margin: 0;  padding: 0;  }  body {  background-color: lightcyan;  text-align: center;  }  .container {  height: 70vh;  display: flex;  justify-content: center;  align-items: center;  }  .game {  height: 60vmin;  width: 60vmin;  display: flex;  flex-wrap: wrap;  gap: 1.5vmin;  justify-content: center;  }  .box {  height: 18vmin;  width: 18vmin;  border-radius: 1rem;  border: none;  box-shadow: 0 0 1rem rgba(0,0,0,0.3);  font-size: 8vmin;  color: red;  background-color: yellow;  }  #reset {  padding: 1rem;  font-size: 1.25rem;  background: #191913;  color: white;  border-radius: 1rem;  border: none;  }  .box:hover {  background-color: chocolate;  }  #new-btn {  padding: 1rem;  font-size: 1.25rem;  background: #191913;  color: white;  border-radius: 1rem;  border: none;  }  #msg {  font-size: 8vmin;  }  .msg-container {  height: 30vmin;  }  .hide {  display: none;  }  </style> </head> <body> <div class="msg-container hide"> <p id="msg">Winner</p> <button id="new-btn">New Game</button> </div> <main> <h1>Tic Tac Toe</h1> <div class="container"> <div class="game"> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> <button class="box"></button> </div> </div> <button id="reset">Reset Game</button> </main> <script>  let boxes = document.querySelectorAll('.box');  let resetBtn = document.querySelector('#reset');  let turnO = true; // Player O starts  let newGameBtn = document.querySelector('#new-btn');  let msgContainer = document.querySelector('.msg-container');  let msg = document.querySelector('#msg');  const winPatterns = [  [0, 1, 2],  [0, 3, 6],  [0, 4, 8],  [1, 4, 7],  [2, 5, 8],  [2, 4, 6],  [3, 4, 5],  [6, 7, 8]  ];  boxes.forEach((box) => {  box.addEventListener('click', function () {  if (turnO) {  box.innerText = 'O';  box.style.color = 'green';  turnO = false;  box.disabled = true;  checkWinner();  } else {  box.innerText = 'X';  box.style.color = 'black';  turnO = true;  box.disabled = true;  checkWinner();  }  });  });  const enableBoxes = () => {  for (let box of boxes) {  box.disabled = false;  box.innerText = "";  }  };  const disableBoxes = () => {  for (let box of boxes) {  box.disabled = true;  }  };  const showWinner = (winner) => {  msg.innerText = `Congratulations, Winner is ${winner}`;  msgContainer.classList.remove('hide');  disableBoxes();  };  const checkWinner = () => {  let hasWin = false;  for (let pattern of winPatterns) {  let pos1Val = boxes[pattern[0]].innerText;  let pos2Val = boxes[pattern[1]].innerText;  let pos3Val = boxes[pattern[2]].innerText;  if (pos1Val !== "" && pos2Val!=="" && pos3Val!=="" &&   pos1Val === pos2Val && pos2Val === pos3Val) {  showWinner(pos1Val);  hasWin = true;  return;  }  }  if (!hasWin) {  const allBoxes = [...boxes].every((box) => box.innerText !== "");  if (allBoxes) {  msgContainer.classList.remove('hide');  msg.innerText = 'Match Drawn';  }  }  };  const resetGame = () => {  turnO = true;  enableBoxes();  msgContainer.classList.add('hide');  };  newGameBtn.addEventListener('click', resetGame);  resetBtn.addEventListener('click', resetGame);  </script> </body> </html> 

Similar Reads