what i learned last week: how to build tic tac toe using html, css and javascript
Tags: html, css, javascript
Published: 2022-01-10 14:14:09

Good Morning! It's a snowy Sunday here in Chicago and today I'm going to build the game tic tac toe. In the process of building this program I will provide a high level overview of HTML, CSS and JavaScript. 
![tic tac toe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2i1ii5zqtbncp9v4mwv.png)
#HTML
The first thing I'm going to do is create an `index.html` file. Remember, [HTML](https://www.w3schools.com/html/html_intro.asp) is the standard markup language for creating Web pages. I like to think of it as the "skeleton" of a website. 
![html skeleton](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0idanl4x8gvpojfk3efb.jpg) Next, I want to start writing code in the newly created `index.html` file. The [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) for an `index.html` file should look something like this...
```
<!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>Document</title>
</head>
<body>
    
</body>
</html>
```
Note, [HTML (HyperText Markup Language)](https://developer.mozilla.org/en-US/docs/Web/HTML) is the most basic building block of the Web. It defines the meaning and structure of web content.
![element tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o4q3jqixkpj1iexvtps.gif) Next, utilizing `<div>`'s, I'm going to build the tic tac toe board. The `<div>` [tag](https://www.w3schools.com/tags/tag_div.ASP) defines a division or a section in an HTML document. It's also used as a container for HTML elements - which is then styled with CSS or manipulated with JavaScript.
```
<!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>Document</title>
</head>
<body>
    <!-- Tic Tac Toe Board -->
    <div id="board-container">
      <div data-index="1" class="box"></div>
      <div data-index="2" class="box"></div>
      <div data-index="3" class="box"></div>
      <div data-index="4" class="box"></div>
      <div data-index="5" class="box"></div>
      <div data-index="6" class="box"></div>
      <div data-index="7" class="box"></div>
      <div data-index="8" class="box"></div>
      <div data-index="9" class="box"></div>
    </div>
</body>
</html>
```
I'm making good progress! So far, I've created an `index.html` file and added `<div>`'s that represent a tic tac toe board. Notice that I've created a div with an [id](https://www.w3schools.com/html/html_id.asp) of `board-container`. The HTML id attribute is used to specify a unique id for an HTML element. Nested inside of the `#board-container` div there are 9 separate, child, `<div>`'s that represent a cell in the tic tac toe board. Remember, an HTML document [is](https://marksheet.io/html-hierarchy.html) like a big family tree, with parents, siblings, children, ancestors, and descendants. I'm about to dive into CSS and will need to somehow reference these newly created children elements so I'm adding a class of `box` to each individual `<div>`.
#CSS
Next, I want to see this newly created grid so let's build and display it to the client side using CSS. If HTML is the skeleton of a website than CSS is the clothes that dress up a person. 
![CSS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xm3d4jvyc4x3xk2x9cbv.png)
Below, is a screenshot of my completed tic tac toe game - designed with CSS.
![tictactoe1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju3mm0mfpkp6v36tvyax.png)
```
#board-container {
  width: 300px;
  height: 300px;
  margin: 0 auto;
  background-color: #e9c46a;
  color: #fff;
  border: 6px solid #e9c46a;
  border-radius: 10px;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  position: relative;
  top: 30%;
}
```
Note, I'm able to style a div by referencing it's id attribute. The same thing can also be done with the class attribute.
![css syntax](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ek34ccfnjomwb1ac5pe.png)
#JavaScript
Below is part of the code used to build and store the logic of my program.
```
document.addEventListener("DOMContentLoaded", () => {
    console.log("DOM Content Loaded");
    //RETREIVE HTML ELEMENTS
    const boxes = document.querySelectorAll(".box");
    const strikethrough = document.getElementById("strikethrough");
    const gameOverArea = document.getElementById("game-over-area");
    const gameOverText = document.getElementById("game-over-text");
    const playAgain = document.getElementById("play-again");
    const playerxDiv = document.getElementById("player-X");
    const playeroDiv = document.getElementById("player-O");
    //CREATE PLAYERS, ARRAY THAT REPRESENTS BOARD AND WINNING COMBOS
    const playerX = "X";
    const playerO = "O";
    const boardArray = Array(boxes.length); //TRACKS STATE OF PROGRAM - CREATED AN ARRAY WHICH HAS 9 ITEMS(BOXES)
    const winningCombos = [
        //ROWS
        {  // KEY   VALUE
            combo: [0, 1, 2],
            strikeClass: "strike-row-1"
        },
        {
            combo: [3, 4, 5],
            strikeClass: "strike-row-2"
        },
        {
            combo: [6, 7, 8],
            strikeClass: "strike-row-3"
        },
        //COLUMNS
        {
            combo: [0, 3, 6],
            strikeClass: "strike-column-1"
        },
        {
            combo: [1, 4, 7],
            strikeClass: "strike-column-2"
        },
        {
            combo: [2, 5, 8],
            strikeClass: "strike-column-3"
        },
        //DIAGONALS
        {
            combo: [0, 4, 8],
            strikeClass: "strike-diagonal-1"
        },
        {
            combo: [2, 4, 6],
            strikeClass: "strike-diagonal-2"
        },
    ];
    let turn = playerX; //TRACKS WHO'S TURN IT IS

    playAgain.addEventListener("click", restartGame);

    //THE FILL() METHOD CHANGES ALL ELEMENTS IN AN ARRAY TO A STATIC VALUE, FROM A START INDEX (DEFAULT 0) TO 
    //AN END INDEX (DEFAULT ARRAY.LENGTH). IT RETURNS THE MODIFIED ARRAY
    boardArray.fill(null);

    playerxDiv.append(playerX);
    playeroDiv.append(playerO);


    boxState();
    //FUNCTION THAT ITERATATES OVER LIST OF BOXES AND ADDS AN EVENT LISTENER TO EACH INDIVIDUAL BOX
    function boxState() {
        boxes.forEach((box) => {
            box.addEventListener("click", boxClick); //FUNCTION WILL BE CALLED WHENEVER THE SPECIFIED EVENT IS DELIVERED TO THE TARGET
        })
    }

    function boxClick(e) {
        const box = e.target; //REFERENCE TO THE HTML ELEMENT CLICKED
        const boxNumber = box.dataset.index;//ACCESS DATA-INDEX ATTRIBUTE
        //IF GAMEOVER AREA CLASSLIST CONTAINNS "VISIBLE" THE FUNCTION WILL STOP EXECUTING
        if (gameOverArea.classList.contains("visible")) {
            return;
        }
        //CHECK IF SPECIFIC BOX IS EMPTY OR HAS AN "X" OR "O" IN IT
        if (box.innerText != "") {
            return;
        }
        if (turn === playerX) {
            box.innerText = playerX;
            boardArray[boxNumber - 1] = playerX; //ARRAYS ARE ZERO INDEXED SO I NEED TO SUBTRACT 1 FROM PLAYERS CHOICE FOR GAME TO BE ACCURATE
            turn = playerO;
            console.log(`It's ${playeroDiv.innerText}'s turn`);
        } else {
            box.innerText = playerO;
            boardArray[boxNumber - 1] = playerO;
            turn = playerX;
            console.log(`It's ${playerxDiv.innerText}'s turn`);
        }

        //FUNCTION IS CALLED ON EVERY SINGLE BOX CLICK - CHECKS IF THERE IS A WINNER
        checkWinner()
    }
```
Deployed Program: https://clever-noether-f61a54.netlify.app/
Github: https://github.com/reyes2981/project1