How I built a Tic Tac Toe Game using vanilla Javascript.
Tags: webdev, javascript, beginners, programming
Published: 2023-05-07 00:30:15


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16fo3y9k5h9ypibsxjle.png)
Tic Tac Toe is a classic game that many of us have played at some point in our lives. The game uses a 3×3 grid. The goal of the game is to be the first player to place three symbols in a straight horizontal, vertical, or diagonal row. If you are a beginner in the field of web development, building a game like Tic Tac Toe is a good start to help build and develop your programming skills.

## **Prerequisite**
To be able to develop a game like Tic Tac Toe, you will need a solid background knowledge in the following languages:

- HTML
- CSS
- JavaScript

**Building a Tic Tac Toe Game with HTML, CSS, and JavaScript**


{% codepen https://codepen.io/Hussayn01/pen/eYPgGBN %}
To start building a Tic Tac Toe Game, we will need to create three seperate files(HTML, CSS, and JavaScript respectively). You can go ahead and open your favourite code editor and proceed to create the files.

## **HTML Structure**

Let's start by creating the HTML structure for our game. We will use a simple table to represent the game board. Each cell in the table will represent a position on the board. We will also create a
 section to display the game score and a button to reset the game. Here is the code for our HTML structure:

```

<!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"> 
    <link rel="stylesheet" href="style.css"> 
    <title>Tic Tac Toe Game</title> 
</head> 
<body> 
    <div id="main"> 
        <table> 
            <caption>Tic Tac Toe Game</caption> 
            <tr> 
                <td id="0"></td> 
                <td id="1"></td> 
                <td id="2"></td> 
            </tr> 
            <tr> 
                <td id="3"></td> 
                <td id="4"></td> 
                <td id="5"></td> 
            </tr> 
            <tr> 
                <td id="6"></td> 
                <td id="7"></td> 
                <td id="8"></td> 
            </tr>
        </table>
        <div id="game-score"> 
            <h1 id="player"></h1> 
            <h3 id="text"></h3> 
        </div> 
        <button id="reset-btn">Reset Game</button> 
</div> <script src="script.js"></script> 
</body> 
</html>
```
The code starts with the HTML5 doctype declaration and sets the language to English for the document. It then defines the head section of the document, which includes the meta tags for character set, compatibility mode, and viewport. The stylesheet for the game is also linked to the document.

The `body` section of the document contains a div element with an ID of "main" that wraps all the game elements, including a table with 3 rows and 3 columns to represent the Tic Tac Toe game board. Each cell of the table has a unique ID (0-8) to enable JavaScript code to access them easily.

The code also includes a div element with an ID of "`game-score`" to display the current game score, a heading element with an ID of "`player`" to display the current player's turn, a subheading element with an ID of "text" to display game-related messages, and a button element with an ID of "`reset-btn`" to reset the game when clicked.

Finally, the code includes a script tag with the source attribute "`script.js`," which will be used to write the JavaScript code for the Tic Tac Toe game.

Now that we've added the HTML structure, let's proceed to include the CSS styling.

## **CSS Styling**
{% codepen https://codepen.io/Hussayn01/pen/eYPgGBN %}

Next, we will add some CSS styling to our HTML elements. We will use CSS to create a simple and clean interface for our game. We will also use CSS to define the style of our table cells, game score section, and reset button. Here is the code for our CSS styling:

```
#main{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
}

```
The `#main` selector applies the` display: flex` property to the `main` element and sets the `flex-direction` to` column`, which aligns the game elements in a vertical column. `justify-content` and `align-items` center the elements both horizontally and vertically, and `text-align` centers the text within the main element.

```
table {
    display: block;
    border-collapse: collapse;
    margin: 20px auto;
}

```
The `table` selector applies the `display: block` property and `border-collapse: collapse`, which removes the borders between cells on the table. It also sets the margin property to center the table horizontally.

```
caption{
    font-size: 32px;
    margin: 24px auto;
}

```
The `caption` selector sets the `font-size` to 32px and adds `margin` to center the caption within the table.
```
td{
    border: 1px solid black;
    width: 80px;
    height: 80px;
    font-size: 48px;
    text-align: center;
    vertical-align: middle;
}


```
The `td` selector sets the `border` property to 1px solid black, and sets the `width` and `height` properties to 80px. The `font-size` is set to 48px to increase the size of the symbols and `text-align` and `vertical-align` properties are set to center the content within each cell.

```
td:hover {
    background-color: #eee;
    cursor: pointer;
}

```
The `td:hover` selector applies the `background-color` of #eee to the table cell when the mouse hovers over it, and the cursor property is set to pointer to provide visual feedback to the user.

```
button {
    display: block;
    margin: 20px auto;
    padding: 10px 20px;
    font-size: 16px;
    border-radius: 5px;
    border: none;
    background-color: #4CAF50;
    color: white;
}

```
The `button` selector sets the display property to block and the `margin` property to center the button. It also sets the padding property,` font-size `property, and `border-radius` property to round the corners. The `border` property is set to none, and the `background-color` is set to #4CAF50, which is a shade of green, while the `color` is set to white.

```
button:hover {
    background-color: #3e8e41;
    cursor: pointer;
}

```
The `button:hover` selector applies the `background-color` of #3e8e41 to the button when the mouse hovers over it and the cursor property is set to pointer.

```
#game-winner{
    display: none;
}
```
The `#game-winner` selector applies the `display: none` property to the game-winner element to hide it by default, and it will be used to display the winner when the game ends.

## **JavaScript Functionality**
Now, we will add JavaScript functionality to our game. We will use JavaScript to implement the game logic, handle user input, and update the game score. We will create functions to check for a winner

**Declare variables**

```

//Declare variables
let currentPlayer = 'X';
let gameEnded = false;
let gameMoves = ['', '', '', '', '', '', '', '', ''];
```
At the beginning of the JavaScript code, there are three variables declared - `currentPlayer`, `gameEnded`, and `gameMoves`.

The `currentPlayer` variable keeps track of whose turn it is. It is initially set to 'X'.

The `gameEnded` variable is used to determine if the game has ended. It is initially set to false.

The `gameMoves` variable is an array that represents the state of the game. Each index in the array corresponds to a cell on the game board. The initial state of the `gameMoves` array is an empty string for each cell.

**Get DOM**

```
//Get DOM
const boxes = document.querySelectorAll('td');
const table = document.querySelector('table');
const gameScore = document.querySelector('#game-score');
let player = document.querySelector('#player');
let text =  document.querySelector('#text');
```
the code uses the `querySelectorAll()` method to select all the table cells (td elements) in the game board. It also selects the `table`, the `#game-score` element, the `#player element `and `#text` element.

**Add event listener to table cells**

```
//add event listener to table boxes
  boxes.forEach((box, index) =>{
      box.addEventListener('click', ()=>{
          if (!gameEnded && gameMoves[index] === '') {
              gameMoves[index] = currentPlayer;
              box.textContent = currentPlayer;
              //check for winner
              if (gameWin()) {
                  table.style.display = 'none';
                  gameScore.style.display = 'block';
                  player.textContent = currentPlayer;
                  text.textContent = 'WINNER';
                  gameEnded = true;
              }
              //check for tie
              else if (gameTie()) {
                  table.style.display = 'none';
                  gameScore.style.display = 'block';
                  player.textContent = 'XO';
                  text.textContent = 'DRAW';
                  gameEnded = true;
              } else{
                  currentPlayer = currentPlayer === 'X' ? '0' : 'X';
              }
          } 
      });
  });
```
A `forEach` loop is used to add a click event listener to each table cell. When a table cell is clicked, the event listener triggers a function that checks if the game has ended, if the cell has already been clicked, and updates the `gameMoves` array accordingly.

**Check for winner function**

```
//Check for winner function
  const gameWin = ()=>{
      const winningCombos = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
      [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
      [0, 4, 8], [2, 4, 6] // diagonals
    ];
    return winningCombos.some(combo=>{
      return combo.every(index=>{
          return gameMoves[index] === currentPlayer;
      })
    })
  }
```
The `gameWin()` function checks if the current player has won the game. It does this by checking if any of the winning combinations (rows, columns, or diagonals) have all the same value (either 'X' or '0').

The function uses the `some()` method to iterate through each winning combination and the `every()` method to iterate through each index in the combination. If all the indexes in a combination have the same value as the current player, the function returns true, and the current player has won.

**Check for tie function**

```
//Check for tie function
  const gameTie = ()=>{
      return gameMoves.every(move => {
          return move !== '';
      });
  }
```
The `gameTie()` function checks if the game is a tie. It does this by checking if all the cells on the game board have been clicked.

The function uses the `every()` method to iterate through each element in the `gameMoves` array. If every element is not an empty string, the function returns true, and the game is a tie.

**Update game state**

If the current player has won the game, the table is hidden, and the `game-score` div is displayed. The div displays the current player's move and the text 'WINNER'. The `gameEnded` variable is set to `true`.

If the game is a tie, the table is hidden, and the game-score div is displayed. The div displays 'XO' and the text 'DRAW'. The `gameEnded` variable is set to true.

If the game is not over, the `currentPlayer` variable is updated to the other player.


**Reset game function**

```
//Reset game function
  const resetGame = ()=>{
    table.style.display = 'block';
    gameScore.style.display = 'none';
    currentPlayer = 'X';
    gameEnded = false;
    gameMoves = ['', '', '', '', '', '', '', '', ''];
    boxes.forEach(box => {
      box.textContent = '';
    });
}
```

```
//Event listener for reset button
const resetButton = document.getElementById('reset-btn');
resetButton.addEventListener('click', resetGame);
```
The `resetGame()` function is called when the reset button is clicked. It sets the game back to its initial state by resetting the `gameMoves` array, the `currentPlayer` variable, and the `gameEnded` variable. It also clears the text in each cell on the game board and hides the game-score div.

Overall, this JavaScript code works by using a combination of event listeners, functions, and variables to keep track of the game state and update the game board as players make their moves. It also checks for a winner or tie and updates the game state accordingly. Finally, it provides a way to reset the game and start over.
This is the complete javascript code.

```
//Declare variables
let currentPlayer = 'X';
let gameEnded = false;
let gameMoves = ['', '', '', '', '', '', '', '', ''];
//Get DOM
  const boxes = document.querySelectorAll('td');
  const table = document.querySelector('table');
  const gameScore = document.querySelector('#game-score');
  let player = document.querySelector('#player');
  let text =  document.querySelector('#text');
  //add event listener to table boxes
  boxes.forEach((box, index) =>{
      box.addEventListener('click', ()=>{
          if (!gameEnded && gameMoves[index] === '') {
              gameMoves[index] = currentPlayer;
              box.textContent = currentPlayer;
              //check for winner
              if (gameWin()) {
                  table.style.display = 'none';
                  gameScore.style.display = 'block';
                  player.textContent = currentPlayer;
                  text.textContent = 'WINNER';
                  gameEnded = true;
              }
              //check for tie
              else if (gameTie()) {
                  table.style.display = 'none';
                  gameScore.style.display = 'block';
                  player.textContent = 'XO';
                  text.textContent = 'DRAW';
                  gameEnded = true;
              } else{
                  currentPlayer = currentPlayer === 'X' ? '0' : 'X';
              }
          } 
      });
  });
  //Check for winner function
  const gameWin = ()=>{
      const winningCombos = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows
      [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns
      [0, 4, 8], [2, 4, 6] // diagonals
    ];
    return winningCombos.some(combo=>{
      return combo.every(index=>{
          return gameMoves[index] === currentPlayer;
      })
    })
  }
  //Check for tie function
  const gameTie = ()=>{
      return gameMoves.every(move => {
          return move !== '';
      });
  }
  //Reset game function
  const resetGame = ()=>{
    table.style.display = 'block';
    gameScore.style.display = 'none';
    currentPlayer = 'X';
    gameEnded = false;
    gameMoves = ['', '', '', '', '', '', '', '', ''];
    boxes.forEach(box => {
      box.textContent = '';
    });
}

  //Event listener for reset button
  const resetButton = document.getElementById('reset-btn');
  resetButton.addEventListener('click', resetGame);
```

Congratulations, you've just learnt how to create a Tic Tac Toe game using HTML, CSS and Javascript. By now you should be able to build your own version, feel free to modify and use the code to build yours. Ensure you do not copy paste the code but rather write it from scratch and play around with the code to see if you can add new functionalities or edit existing ones to suit your needs. This will not only help you understand the code but also ensure you grow your coding skills faster.

Conclusively, i want to thank you for finding time to read this article, i sincerely hope you enjoyed it, however if you come across any bugs whilst trying out the code, please do not hesitate to let me know.

{% codepen https://codepen.io/Hussayn01/pen/eYPgGBN %}


My name is **Hussaini Ahmed**, I am a **front end developer**. I also write about front end languages, frameworks and latest technologies. I’d loved to hear your thought on this article. Feel free to drop a comment below or reach out to me via:

[Upwork](https://www.upwork.com/freelancers/~018f66d92dda7e4417)
[Github](https://github.com/Husayn01)
[WhatsApp](https://wa.me/message/PAGMWLPTLJAOK1)
[Twitter](https://mobile.twitter.com/Husayn_01)
[LinkedIn](https://www.linkedin.com/mwlite/in/hussaini-ahmed-a51232252)