JSFiddle - React, Tailwind, and code Playground

by Eric Zell

HTML

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">

  <title>Tic Tac Toe</title>
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="style.css">
  <script src="script.js" defer></script>
</head>

<body>
  <h1>Welcome to Tic Tac Toe!</h1>
  <h3 id="info">It's your turn, please make a selection...</h3>
  <div class="grid-container">
    <div id="item-0-0" class="grid-item unplayed">-</div>
    <div id="item-0-1" class="grid-item unplayed">-</div>
    <div id="item-0-2" class="grid-item unplayed">-</div>
    <div id="item-1-0" class="grid-item unplayed">-</div>
    <div id="item-1-1" class="grid-item unplayed">-</div>
    <div id="item-1-2" class="grid-item unplayed">-</div>
    <div id="item-2-0" class="grid-item unplayed">-</div>
    <div id="item-2-1" class="grid-item unplayed">-</div>
    <div id="item-2-2" class="grid-item unplayed">-</div>
  </div>

  <button id="refresh" type="button">Start a new game</button>
</body>
</html>

CSS

body {
  color: #1d3557;
  font-family: sans-serif;
}
.grid-container {
  display: grid;
  grid-template-columns: auto auto auto;
  height: 300px;
  width: 300px;
  border: 5px solid #a8dadc;
}

.grid-item {
  background-color: #f1faee;
  border: 4px solid #1d3557;
  padding: 30px 0px;
  font-size: 20px;
  text-align: center;
  vertical-align: middle;
}

.unplayed {
  color: #f1faee;
  cursor: pointer;
}

.alert {
  color: #e63946;
}

.success {
  color: #457b9d;
}

button {
  margin-top: 30px;
}

JavaScript

// Initialize the game
let board = [["-", "-","-"],["-","-","-"],["-", "-","-"]];
let turns = 0;

// Allow the player to refresh the game to start over
var refreshButton = document.getElementById("refresh");
refreshButton.onclick = function() {
  refresh();
}

// select all the square elements on board
let squares = document.getElementsByClassName('grid-item');

// add an onclick event for each square on the board
for (var square of squares) {
  square.onclick = function() {
    if (!this.classList.contains("unplayed")) {
      console.log("this square has been played");
      return;
    }
    this.innerText = "X";
    this.classList.remove("unplayed");

    // The row and column number of squares are stored in the elements' ID's
    // Such as 'item-1-2' is for row 1, column 2
    // Here we split the id to parse the row and column
    var splitID = this.id.split("-");
    var row = parseInt(splitID[1]);
    var column = parseInt(splitID[2]);
    board[row][column] = "X"
    turns++;

    if (checkForWinner("X")) {
      document.getElementById('info').innerText = "Congratulations, you win!";
      document.getElementById('info').classList.add("success");
      return;
    }

    if (checkForGameOver()){
      document.getElementById('info').innerText = "The game has ended in a tie!";
      return;
    }

    document.getElementById('info').innerText = "The computer is picking...";
    document.getElementById('info').classList.add("alert");

    // Display 'The computer is picking...' for half a second
    setTimeout(computerTurn, 500);;
  };
}

// This function selects an unplayed square at random for the computer
var computerTurn = function() {
  var unplayed = document.getElementsByClassName('unplayed');
  var randomIndex = Math.floor(Math.random() * unplayed.length);
  var computerPick = unplayed[randomIndex];
  computerPick.innerText = "O";
  computerPick.classList.remove("unplayed");
  // Make the computer's pick the alert color
 ...