javascript

How you can make a Tic Tac Toe Game in HTML, CSS, and JS?

How you can make a Tic Tac Toe Game in HTML, CSS, and JS?
8 min read
#javascript

Tic Tac Toe

Tic-tac-toe is a two-player game in which players take turns marking the spaces in a three-by-one grid with X or O. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row wins the game.

Gameplay

  1. To start, two players choose who will play X and who will play O.
  2. The player with an X goes first and chooses a space in the grid to mark with an X.
  3. The other player then chooses a space in the grid to mark with an O.
  4. Players continue taking turns marking spaces in the grid until one player achieves three in a row, either horizontally, vertically, or diagonally.
  5. The first player to achieve three in a row wins the game.

Strategy

The best strategy for tic-tac-toe is to try to block your opponent from getting three in a row while also trying to get three in a row yourself. Here are some tips:

  • Pay attention to the center square. The center square is the most important square in tic-tac-toe, as it gives you the most options for getting three in a row. If you can, try to mark the center square first.
  • Block your opponent’s moves. If you see that your opponent is about to get three in a row, try to block them by marking the square that they need to complete their row.
  • Look for opportunities to get three in a row yourself. If you have two marks in a row, look for opportunities to mark the third square to complete your row.
  • Don’t give away free moves. If you don’t have any good moves yourself, don’t give away a free move to your opponent by marking a square that they need to complete their row.

Variations

There are many variations of tic-tac-toe, such as:

  • Tic-tac-toe on a larger board. Tic-tac-toe can be played on a larger board, such as a four-by-four or five-by-five grid. This makes the game more challenging and strategic.
  • Tic-tac-toe with more than two players. Tic-tac-toe can be played with more than two players, but it becomes more difficult to keep track of all of the moves.
  • Three-dimensional tic-tac-toe. Three-dimensional tic-tac-toe is played on a three-by-three-by-three grid. This variation is even more challenging and strategic than regular tic-tac-toe.

Code

Let’s start making it,

HTML

First, we need to write HTML for it, ON this first screen I have shown three buttons, one for starting the game, second for the learning about the game, and the last one for quitting the game.

<html>

<head>
  <title>Tic Tac Toe</title>
  <meta name="description" content="Multiplayer Tic Tac Toe Game">
  <link rel="stylesheet" href="./css/index.css">
</head>

<body class="center">
  <h1>Tic Tac Toe Game</h2>
    <div class="center" id="main">
      <h4>--Play and Enjoy--</h4>
      <button onclick="start()" class="button">Start a New Game</button>
      <br>
      <button onclick="learn()" class="button">Learn How to Play GAME?</button>
      <br>
      <button onclick="exit()" class="button">Exit</button>
    </div>
    <div class="center" id="learn">
      <p>
          You are X, your friend is O. 
          <br>
          The first player to get 3 of her marks in a row (up, down, across, or diagonally) is the winner.
          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.
      </p>
      <img src="./image/learn.jpg" alt="Learn">
      <br>
      <button onclick="main()" class="button">Back</button>
    </div>
    <div class="center" id="game">
      <div class="center" style="margin: 5px;">
        <h3 id="textPlayer" style="font-size: 0.9rem;">(Current Player 1)</h2>
          <h3 id="textComd" style="font-size: 0.9rem;">Player 2 can play now...</h2>
      </div>
      <canvas id="tic-tac-toe-board" class="center"></canvas>
    </div>
    <!-- Script OF Game -->
    <script src="./js/index.js"></script>
</body>

</html>

CSS

CSS for making it better visually, you can also improve the design more by adding different types of animations with CSS.

body,html
{
    margin: 0px;
    color: #000000;
    font-size: 1.3rem;
    font-family: Roobert,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
}

.center
{
  text-align: center;
}

/* Game Board */
#tic-tac-toe-board {
  display: block;
  margin: auto;
  margin-top: 20px;
}

/* Button Style */
.button {
  appearance: none;
  background-color: #000000;
  border: 2px solid #1A1A1A;
  box-sizing: border-box;
  color: #FFFFFF;
  cursor: pointer;
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  line-height: normal;
  margin: 5px;
  min-height: 60px;
  min-width: 0;
  outline: none;
  padding: 0px 24px;
  text-align: center;
  text-decoration: none;
  transition: all 300ms cubic-bezier(.23, 1, 0.32, 1);
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  will-change: transform;
}

.button:disabled {
  pointer-events: none;
}

.button:hover {
  box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
  transform: translateY(-2px);
}

.button:active {
  box-shadow: none;
  transform: translateY(0);
}

JS

After designing of the game, we need to add functionalities to it, so users can do different actions and enjoy the game,

var count = 0;
var player = 1;
var board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];

var canvas = document.getElementById("tic-tac-toe-board");
var context = canvas.getContext('2d');
var canvasSize = 500;
var sectionSize = canvasSize / 3;
canvas.width = canvasSize;
canvas.height = canvasSize;
context.translate(0.5, 0.5);
context.lineWidth = 10;

/* Event Func */
function main() {
  document.getElementById("main").style.display = "block";
  document.getElementById("learn").style.display = "none";
  document.getElementById("game").style.display = "none";
}

/* Event Func */
function start() {
  document.getElementById("main").style.display = "none";
  document.getElementById("learn").style.display = "none";
  document.getElementById("game").style.display = "block";

  canvas.addEventListener('mouseup', function (event) {
    addPlayingPiece(getCanvasMousePosition(event));
    drawBoard();
    setTimeout(() => {
      if(!checkWhoWin(1) && !checkWhoWin(2)){
        checkIsOver();
      }
    }, 100);
  });
  drawBoard();
}

/* Event Func */
function learn() {
  document.getElementById("main").style.display = "none";
  document.getElementById("learn").style.display = "block";
  document.getElementById("game").style.display = "none";
}

/* Event Func */
function exit() {
  window.close();
}

function addPlayingPiece(mouse) {
  var xCordinate;
  var yCordinate;
  for (var x = 0; x < 3; x++) {
    for (var y = 0; y < 3; y++) {
      xCordinate = x * sectionSize;
      yCordinate = y * sectionSize;
      if (
        mouse.x >= xCordinate && mouse.x <= xCordinate + sectionSize &&
        mouse.y >= yCordinate && mouse.y <= yCordinate + sectionSize && board[y][x] == 0
      ) {
        board[y][x] = player;
        player = player == 1 ? 2 : 1;
        count++;
      }
    }
  }
}

function getCanvasMousePosition(event) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: event.clientX - rect.left,
    y: event.clientY - rect.top
  }
}

function clearPlayingArea(xCordinate, yCordinate) {
  context.fillStyle = "#fff";
  context.fillRect(
    xCordinate,
    yCordinate,
    sectionSize,
    sectionSize
  );
}

function drawO(xCordinate, yCordinate) {
  var halfSectionSize = (0.5 * sectionSize);
  var centerX = xCordinate + halfSectionSize;
  var centerY = yCordinate + halfSectionSize;
  var radius = (sectionSize - 100) / 2;
  var startAngle = 0 * Math.PI;
  var endAngle = 2 * Math.PI;
  context.beginPath();
  context.arc(centerX, centerY, radius, startAngle, endAngle);
  context.stroke();
}

function drawX(xCordinate, yCordinate) {
  context.beginPath();
  var offset = 50;
  context.moveTo(xCordinate + offset, yCordinate + offset);
  context.lineTo(xCordinate + sectionSize - offset, yCordinate + sectionSize - offset);
  context.moveTo(xCordinate + offset, yCordinate + sectionSize - offset);
  context.lineTo(xCordinate + sectionSize - offset, yCordinate + offset);
  context.stroke();
}

function drawBoard() {
  //Updating the Command
  document.querySelector("#textPlayer").textContent = "(Current Player: " + player + " )";
  document.querySelector("#textComd").textContent = "(Player " + (count % 2 + 1) + " can play now... )";

  var xCordinate;
  var yCordinate;
  for (var x = 0; x < 3; x++) {
    for (var y = 0; y < 3; y++) {
      xCordinate = x * sectionSize;
      yCordinate = y * sectionSize;
      //Clearing First then Drawing 
      clearPlayingArea(xCordinate, yCordinate);
      if (board[y][x] === 1) {
        drawX(xCordinate, yCordinate);
      }
      else if (board[y][x] === 2) {
        {
          drawO(xCordinate, yCordinate);
        }
      }
    }
  }

  //DRAW LINES of Boards
  var lineStart = 4;
  var lineLenght = canvasSize - 5;
  context.beginPath();
  for (var y = 1; y <= 2; y++) {
    context.moveTo(lineStart, y * sectionSize);
    context.lineTo(lineLenght, y * sectionSize);
  }
  for (var x = 1; x <= 2; x++) {
    context.moveTo(x * sectionSize, lineStart);
    context.lineTo(x * sectionSize, lineLenght);
  }
  context.stroke();
}


function checkWhoWin(number) {
  //check win   number will be 1 or 2
  // 1 for player is ONE
  // 2 for player is TWO
  let isWin = false;
  for (let i = 0; i < 3; i++) {
    if ((board[i][0] === number && board[i][1] === number && board[i][2] === number) || (board[0][i] === number && board[1][i] === number && board[2][i] === number)) {
      isWin = true;
      alert("Player " + number + " win the Game");
      window.location.reload();
    }
  }
  if ((board[0][0] === number && board[1][1] === number && board[2][2] === number) || (board[0][2] === number && board[1][1] === number && board[2][0] === number)) {
    isWin = true;
    alert("Player " + number + " win the Game");
    window.location.reload();
  }
  return isWin;
}

function checkIsOver() {
  //IF BOTH ARE NOT WIN AND NO NEXT MOVE
  if (count >= 9) {
    alert("Game is Over!!!");
    window.location.reload();
  }
}

window.onload = main(); //CALL ON LOAD

Conclusion

I have provided the full code of the Tic Tac Toe game and I have used HTML, CSS, and JS for it. You can enjoy the game and code. HAPPY CODING!!

Follow and Support me on Medium and Patreon. Clap and Comment on Medium Posts if you find this helpful for you. Thanks for reading it!!!