Tic Tac Toe JavaScript


Let's create a simple tic tac toe game in JavaScript. We are going to use HTML to create the game board, CSS to create the game board's style, and use JavaScript to control the game.

There are many different types of games we have. The mobile game, desktop games, web games, etc. Here we are going to create a web game that can be played on the web using the browser.

Tic Tac Toe Game

Tic Tac Toe is a simple well known game. It is played by two players on a 3x3 grid.

Players get their own symbol, either X or O. They have to fill in a square with their symbol on the grid when it's their turn.

The goal of the game is to get three in a row. The first player to get three in a row wins.

For a quick look here is our tic tac toe game:

Test the app tic tac toe javascript

Creating Tic Tac Toe Game

To create a tic tac toe game we need HTML and CSS to create the game board (boxes that are used to play the game).

First, let's discuss how to create the game board, and then in the next step, we will create the game logic using JavaScript.


Creating Game Board

The game contains the following elements:

  1. Player instruction for playing the game
  2. Game board (3x3 grid)
  3. Game result section
  4. Restart button

1. Create main element and player instruction element

Start creating with the main element, it contains all other necessary components of the game.

Create a <div> element with class tic-tac-toe. It will be the main element of the game.

Inside this element create another <div> element with class intro and write the necessary instructions for the player to play the game.

<div class="tic-tac-toe">
  <div class="intro">
    <p>Click on a square to place your X or O</p>
    <p>Player 1: X</p>
    <p>Player 2: O</p>
  </div>
</div>

Now style these elements. Give the body some background color and use CSS flexbox to align them in the center.

Also, give the intro element some different background color and make the text bold.

Here is the style we used in our app.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #eecf79;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  font-family: sans-serif;
}

.tic-tac-toe {
  width: 350px;
  margin: 20px auto;
  background-color: #eeb879;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.intro {
  margin-top: 20px;
}

.intro p {
  font-size: 1.1rem;
  font-weight: bold;
  margin-bottom: 1rem;
  text-align: center;
}

Here is what our app looks like for now.

tic tac toe javascript output 1

2. Create a 3x3 grid

Inside the main element, we will create our board. The board contains 3 rows and 3 columns.

Create a <div> element with class board. Inside this element create 3 rows with class board-row.

Within each row create 3 cells with a class board-cell.

<div class="tic-tac-toe">
  <div class="board">
    <div class="board-row">
      <div class="board-cell"></div>
      <div class="board-cell"></div>
      <div class="board-cell"></div>
    </div>
    <div class="board-row">
      <div class="board-cell"></div>
      <div class="board-cell"></div>
      <div class="board-cell"></div>
    </div>
    <div class="board-row">
      <div class="board-cell"></div>
      <div class="board-cell"></div>
      <div class="board-cell"></div>
    </div>
  </div>
</div>

Now write the necessary CSS to create a square grid with borders around it.

Give the board width and height of 300px. Also, give each cell width and height of 100px.

For a nice look of the input cells give font-size: 2.5rem and align it to center both horizontally and vertically using flexbox.

.board {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid #000000;
  border-right: 2px solid #000000;
}

.board-row {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

.board-cell {
  width: 100px;
  height: 100px;
  border: 1px solid #000000;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
  font-weight: bold;
}

The output of what the result element looks like.

tic tac toe javascript output 2

3. Create result element

Put result element withing the board element because we want to cover the whole board with the result element to show the result.

This way we will also become sure players can't give any input further.

We will make the parent element position: relative and result element position: absolute. Also give result element sufficient top and left value to make sure it is always on top of the board.

<div class="board">
  .
  .
  ... cells
  <div class="result"></div>
</div>
.result {
  position: absolute;
  top: -5px;
  left: -5px;
  display: none;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  color: #000000;
  font-size: 2.5rem;
  font-weight: bold;
  opacity: 0.7;
  width: 310px;
  height: 310px;
}

Output of how result element looks like.

tic tac toe javascript output 3

4. Create Restart button and Turn counter

Create a button with class restart and give it a text Restart.

Add an onclick event to this button to reset the game.

Also, create a turn element and it will have text like Player 1.

Both of this 2 element lies inside the main element.

<div class="tic-tac-toe">
  <div class="turn">Player 1</div>
  <button onclick="restartGame()" class="restart">Restart</button>
</div>

Write JavaScript Code For Tic Tac Toe

To start with writing logic for the game first take an overview of what we are going to do.

  1. Select all the necessary elements from the DOM. For example, cells, result, and turn counter.
  2. Set 'X' and 'O' as the first player and second player. Also, create an array named board to store the values of the cells.
  3. Start the game and attach an onclick event to each cell.
  4. Onclick cells will call a function that will assign the value to the cell, change the turn, store the value in the array board and check if the player won or not.
  5. If the player won then show the result and disable all the cells.

1. Select all elements

Start with selecting all the necessary elements that will be used in the game.

Use the querySelectorAll method to select all the cells on the board.

To select player turn and result element use the querySelector method.

// select all useful elements
const boardCells = document.querySelectorAll('.board-cell');
const turn = document.querySelector('.turn');
const result = document.querySelector('.result');

2. Give player their symbol and create an array to store the values

Now we need to give each player their symbol (X or O) and create an array (3x3) to store the values.

// assign player symbols
const playerOne = 'X';
const playerTwo = 'O';

// board array
var board = [
  ['', '', ''],
  ['', '', ''],
  ['', '', '']
];

3. Start the game

Now create a function that will start the game.

Within the function, we will attach an onclick event to each cell.

Bind the function to each cell and its index and pass the cell and index as an argument.

// start game
function startGame() {
  boardCells.forEach((cell, index) => {
    cell.innerHTML = '';
    cell.addEventListener('click', handleClick.bind(null, cell, index));
  });
};

4. Handle click event

Now create a function, that will handle the click event.

Within the function we will check if the cell is empty or not and if it is empty then we will assign the value according to the turn and change the turn.

Meanwhile use the index of the cell to determine the row and column of the cell and store the value in the board array.

Now remove the click event from the cell so that player may not click on the cell again.

Finally, check if the player won or not using checkWinner() function.

// handle click event
function handleClick(cell, index) {
  const cellValue = cell.innerHTML;
  if (cellValue === '') {
    if (turn.innerHTML === 'Player 1') {
      cell.innerHTML = playerOne;
      turn.innerHTML = 'Player 2';
      // insert into array
      board[Math.floor(index / 3)][index % 3] = playerOne;
    } else {
      cell.innerHTML = playerTwo;
      turn.innerHTML = 'Player 1';
      // insert into array
      board[Math.floor(index / 3)][index % 3] = playerTwo;
    }
  }
  // remove event listener
  cell.removeEventListener('click', handleClick);
  // check if someone won
  checkWinner();
}

5. Check if the player won

Now create a function that will check if the player won or not.

Within the function, we will check if any of the rows, column, or diagonal has 3 same values.

Use the for loop that will check if any of the 3 rows or columns same values.

If the same values are found then show the result using showResult() button and stop for further checking.

To check if the game got drawn. Check if all the cells are filled and if yes then show the result as a draw.

// check if player won
function checkWinner() {
  // check for rows
  for (let i = 0; i < 3; i++) {
    if (board[i][0] === board[i][1] && board[i][0] === board[i][2] && board[i][0] !== '') {
      showResult(board[i][0]);
      return;
    }
  }
  // check for columns
  for (let i = 0; i < 3; i++) {
    if (board[0][i] === board[1][i] && board[0][i] === board[2][i] && board[0][i] !== '') {
      showResult(board[0][i]);
      return;
    }
  }
  // check for diagonals
  if (board[0][0] === board[1][1] && board[0][0] === board[2][2] && board[0][0] !== '') {
    showResult(board[0][0]);
    return;
  }
  if (board[0][2] === board[1][1] && board[0][2] === board[2][0] && board[0][2] !== '') {
    showResult(board[0][2]);
    return;
  }
  // check for a tie
  // if all cells are filled and no winner
  var count = 0;
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      if (board[i][j] != '') {
        count++;
      }
    }
  }
  if (count == 9) {
    showResult('Tie');
    return;
  }
}

6. Show result

Check for the symbol of the winner and show the result accordingly.

The result element is hidden by default. Now to show the result we will use the display property and set it to flex.

// show result
function showResult(symbol) {
  if (symbol === playerOne) {
    result.innerHTML = 'Player 1 Win!';
  } else if (symbol === playerTwo) {
    result.innerHTML = 'Player 2 Win!';
  } else {
    result.innerHTML = 'Tie!';
  }
  result.style.display = 'flex';
}

7. Reset game

Create a function to reset the game when the player won or draws.

Hide the result element. Set turn to Player 1. Reset the board array and call the function startGame().

// reset game
function restartGame() {
  result.style.display = 'none';
  turn.innerHTML = 'Player 1';

  board = [
    ['', '', ''],
    ['', '', ''],
    ['', '', '']
  ];

  startGame();
}

8. Start the game

Finally, call the function startGame() to start the game.

// start game
startGame();

Complete Code For Tic Tac Toe Game In JavaScript

Here is the complete code for Tic Tac Toe Game in JavaScript.

Example

<!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">
  <title>Tic-Tac-Toe</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      background-color: #eecf79;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      font-family: sans-serif;
    }

    .tic-tac-toe {
      width: 350px;
      margin: 20px auto;
      background-color: #eeb879;
      border-radius: 10px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .intro {
      margin-top: 20px;
    }

    .intro p {
      font-size: 1.1rem;
      font-weight: bold;
      margin-bottom: 1rem;
      text-align: center;
    }

    .board {
      position: relative;
      width: 300px;
      height: 300px;
      border: 1px solid #000000;
      border-right: 2px solid #000000;
    }

    .board-row {
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
    }

    .board-cell {
      width: 100px;
      height: 100px;
      border: 1px solid #000000;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 2.5rem;
      font-weight: bold;
    }

    .turn {
      color: #68432b;
      font-size: 1.5rem;
      font-weight: bold;
      margin: 10px 0;
    }

    .restart {
      background-color: #68432b;
      color: #ffffff;
      border: none;
      border-radius: 5px;
      padding: 10px 20px;
      font-size: 1.2rem;
      font-weight: bold;
      cursor: pointer;
      margin: 10px 0;
    }

    .result {
      position: absolute;
      top: -5px;
      left: -5px;
      display: none;
      align-items: center;
      justify-content: center;
      background: #ffffff;
      color: #000000;
      font-size: 2.5rem;
      font-weight: bold;
      opacity: 0.7;
      width: 310px;
      height: 310px;
    }
  </style>
</head>

<body>
  <div class="tic-tac-toe">
    <div class="intro">
      <p>Click on a square to place your X or O</p>
      <p>Player 1: X</p>
      <p>Player 2: O</p>
    </div>
    <div class="board">
      <div class="board-row">
        <div class="board-cell"></div>
        <div class="board-cell"></div>
        <div class="board-cell"></div>
      </div>
      <div class="board-row">
        <div class="board-cell"></div>
        <div class="board-cell"></div>
        <div class="board-cell"></div>
      </div>
      <div class="board-row">
        <div class="board-cell"></div>
        <div class="board-cell"></div>
        <div class="board-cell"></div>
      </div>
      <div class="result">Player 1 Win!</div>
    </div>
    <div class="turn">Player 1</div>
    <button onclick="restartGame()" class="restart">Restart</button>
  </div>

  <script>
    const boardCells = document.querySelectorAll('.board-cell');
    const turn = document.querySelector('.turn');
    const result = document.querySelector('.result');

    // set a symbol
    const playerOne = 'X';
    const playerTwo = 'O';
    // board array
    var board = [
      ['', '', ''],
      ['', '', ''],
      ['', '', '']
    ];

    // start the game
    startGame();

    function startGame() {
      boardCells.forEach((cell, index) => {
        cell.innerHTML = '';
        cell.addEventListener('click', handleClick.bind(null, cell, index));
      });
    };

    function handleClick(cell, index) {
      const cellValue = cell.innerHTML;
      if (cellValue === '') {
        if (turn.innerHTML === 'Player 1') {
          cell.innerHTML = playerOne;
          turn.innerHTML = 'Player 2';
          // insert into array
          board[Math.floor(index / 3)][index % 3] = playerOne;
        } else {
          cell.innerHTML = playerTwo;
          turn.innerHTML = 'Player 1';
          // insert into array
          board[Math.floor(index / 3)][index % 3] = playerTwo;
        }
      }
      // remove event listener
      cell.removeEventListener('click', handleClick);
      // check if someone won
      checkWinner();
    }

    function checkWinner() {
      // check for rows
      for (let i = 0; i < 3; i++) {
        if (board[i][0] === board[i][1] && board[i][0] === board[i][2] && board[i][0] !== '') {
          showResult(board[i][0]);
          return;
        }
      }
      // check for columns
      for (let i = 0; i < 3; i++) {
        if (board[0][i] === board[1][i] && board[0][i] === board[2][i] && board[0][i] !== '') {
          showResult(board[0][i]);
          return;
        }
      }
      // check for diagonals
      if (board[0][0] === board[1][1] && board[0][0] === board[2][2] && board[0][0] !== '') {
        showResult(board[0][0]);
        return;
      }
      if (board[0][2] === board[1][1] && board[0][2] === board[2][0] && board[0][2] !== '') {
        showResult(board[0][2]);
        return;
      }
      // check for a tie
      // if all cells are filled and no winner
      var count = 0;
      for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
          if (board[i][j] != '') {
            count++;
          }
        }
      }
      if (count == 9) {
        showResult('Tie');
        return;
      }
    }

    function showResult(symbol) {
      if (symbol === playerOne) {
        result.innerHTML = 'Player 1 Win!';
      } else if (symbol === playerTwo) {
        result.innerHTML = 'Player 2 Win!';
      } else {
        result.innerHTML = 'Tie!';
      }
      result.style.display = 'flex';
    }

    function restartGame() {
      result.style.display = 'none';
      turn.innerHTML = 'Player 1';

      board = [
        ['', '', ''],
        ['', '', ''],
        ['', '', '']
      ];

      startGame();
    }
  </script>
</body>

</html>

Conclusion

In this complete guide on how to build a tic-tac-toe game, we learned how to create a game using HTML, CSS, and JavaScript. We create a 2 player game where each player can place their symbol on the board.