24+ JavaScript Tic Tac Toe Examples

This post contains a total of 24+ Hand-Picked JavaScript Tic Tac Toe Examples with Source Code. All the Tic Tac Toe programs are made using JavaScript and uses little bit of CSS for Styling.

You can use the source code of these examples for educational use with credits to the original owner.

Related Posts

Click a Code to Copy it.

1. By Augustas Macijauskas

Made by Augustas Macijauskas. A complete Tic Tac Toe game made using JavaScript. It has three modes you can play, these are Normal, Magic Board and Play with AI. Normal mode is for two players, magic board is for three players and the Play with AI is for playing with Artificial Intelligence aka Robot, this mode has three sub-modes, beginner, amateur and master. ( Source )

<!DOCTYPE html>
<!--
  * Welcome to my tic tac toe game!!!
  * Special thanks to Baptiste E. Prunier
    for inspiration and help while coding

-->

<!--
# Title          : Magic Tic Tac Toe
# Version        : 3.0
# AI             : 3 difficulties available: Beginner, Amateur and Master
# Magic board    : A game mode for 3 players: X, O and M
# Last update    : 01 August 2017
# Author         : Augustas Macijauskas
# Language       : HTML, CSS, Javascript
# Dependancy     : Lodash and jQuery scripts added at the end
-->

<html>

  <head>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic Tac Toe game!</title>
    <link href="https://fonts.googleapis.com/css?family=Amatic+SC" rel="stylesheet">
    <link rel="stylesheet" href="tictactoe.css">

  </head>

  <body>
<style>
    /* CSS GRID IS AWESOME, CHECK OUT! */

@import url('https://fonts.googleapis.com/css?family=Amatic+SC');

body {
    background-color: white;
}

/* Creating the layout for mobiles first*/

.grid_main {
  display: grid;
  max-width: 296px;
  margin: auto;
  margin-top: 10%;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto auto auto;

  grid-template-areas:
    "header"
    "normal"
    "magic"
    "AI";

  background-color: white;
}

.grid_main .header {
  grid-area: header;
  justify-self: center;
}

.grid_main h1 {
  margin: 0 auto;
  margin-bottom: 2.5%;
  border-bottom: 1px solid black;
  text-align: center;
  padding: 20px 0 20px 0;
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 30pt;
  font-weight: 700;
}

.grid_main .normal {
  grid-area: normal;
  justify-self: center;
}

.grid_main .magicBoard {
  grid-area: magic;
  justify-self: center;
}

.grid_main .vsAI {
  grid-area: AI;
  justify-self: center;
}

.grid_main a {
  text-decoration: none;
  font-family: 'Amatic SC', cursive;
  color: black;
  margin: 2.5% auto;
  font-size: 25pt;
  font-weight: 400;
}

.grid_main a:hover {
  font-weight: 700;
}

.grid_AI_setup {
  display: none;
  max-width: 296px;
  margin: auto;
  margin-top: 10%;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto auto auto;

  grid-template-areas:
    "header"
    "beginner"
    "amateur"
    "master";

  background-color: white;
}

.grid_AI_setup .header {
  grid-area: header;
  justify-self: center;
}

.grid_AI_setup h1 {
  margin: 0 auto;
  margin-bottom: 2.5%;
  border-bottom: 1px solid black;
  text-align: center;
  padding: 20px 0 20px 0;
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 30pt;
  font-weight: 700;
}

.grid_AI_setup .beginner {
  grid-area: beginner;
  justify-self: center;
}

.grid_AI_setup .amateur {
  grid-area: amateur;
  justify-self: center;
}

.grid_AI_setup .master {
  grid-area: master;
  justify-self: center;
}

.grid_AI_setup a {
  text-decoration: none;
  font-family: 'Amatic SC', cursive;
  color: black;
  margin: 2.5% auto;
  font-size: 25pt;
  font-weight: 400;
}

.grid_AI_setup a:hover {
  font-weight: 700;
}

.grid_normal {
  max-width: 296px;
  margin: auto;
  display: none;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto auto auto;

  grid-template-areas:
    "heading heading"
    "message message"
    "table table"
    "back startOver";

  background-color: white;
}

.grid_AI {
  max-width: 296px;
  margin: auto;
  display: none;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto auto auto;

  grid-template-areas:
    "heading heading"
    "message message"
    "table table"
    "back startOver";

  background-color: white;
}

.grid_magic {
  max-width: 296px;
  margin: auto;
  display: none;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto auto auto;

  grid-template-areas:
    "heading heading"
    "message message"
    "table table"
    "back startOver";

  background-color: white;
}

.grid_normal .heading {
  grid-area: heading;
  justify-self: center;
}

.grid_AI .heading {
  grid-area: heading;
  justify-self: center;
}

.grid_magic .heading {
  grid-area: heading;
  justify-self: center;
}

.grid_normal .message {
  grid-area: message;
  margin-left: 1.5%;
}

.grid_AI .message {
  grid-area: message;
  margin-left: 1.5%;
}

.grid_magic .message {
  grid-area: message;
  margin-left: 2.5%;
}

.grid_normal .table {
  grid-area: table;
  justify-self: center;
}

.grid_AI .table {
  grid-area: table;
  justify-self: center;
}

.grid_magic .table {
  grid-area: table;
  justify-self: center;
}

.grid_normal .back {
  grid-area: back;
  justify-self: left;
  margin-left: 2.5%;
}

.grid_AI .back {
  grid-area: back;
  justify-self: left;
  margin-left: 2.5%;
}

.grid_magic .back {
  grid-area: back;
  justify-self: left;
  margin-left: 3.5%;
}

.grid_normal .startOver {
  grid-area: startOver;
  justify-self: right;
  margin-right: 2.5%;
}

.grid_AI .startOver {
  grid-area: startOver;
  justify-self: right;
  margin-right: 2.5%;
}

.grid_magic .startOver {
  grid-area: startOver;
  justify-self: right;
  margin-right: 3.5%;
}

.grid_normal .square {
  width: 90px;
  height: 90px;
  font-family: 'Comfortaa', serif;
  font-size: 40pt;
  text-align: center;
}

.grid_AI .square {
  width: 90px;
  height: 90px;
  font-family: 'Comfortaa', serif;
  font-size: 40pt;
  text-align: center;
}

.grid_normal .square {
  width: 90px;
  height: 90px;
  font-family: 'Comfortaa', serif;
  font-size: 40pt;
  text-align: center;
}

.grid_magic .square {
  width: 65px;
  height: 65px;
  font-family: 'Comfortaa', serif;
  font-size: 30pt;
  text-align: center;
}

/* Styling elements */
.grid_normal h1 {
  margin: 0 auto;
  margin-bottom: 2.5%;
  text-align: center;
  padding: 20px 0 20px 0;
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 20pt;
  font-weight: 400;
}

.grid_normal h1 span {
  font-weight: 700;
}

.grid_normal h2{
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 20pt;
  font-weight: 400;
  margin-top: 0;
  margin-bottom: 0;
}

.grid_normal a {
  text-decoration: none;
  font-family: 'Amatic SC', cursive;
  color: black;
  margin-top: 5%;
  font-size: 20pt;
}

.grid_normal a:hover {
  text-decoration: underline;
}

.grid_AI h1 {
  margin: 0 auto;
  margin-bottom: 2.5%;
  text-align: center;
  padding: 20px 0 20px 0;
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 20pt;
  font-weight: 400;
}

.grid_AI h1 span {
  font-weight: 700;
}

.grid_AI h2{
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 20pt;
  font-weight: 400;
  margin-top: 0;
  margin-bottom: 0;
}

.grid_AI a {
  text-decoration: none;
  font-family: 'Amatic SC', cursive;
  color: black;
  margin-top: 5%;
  font-size: 20pt;
}

.grid_AI a:hover {
  text-decoration: underline;
}

.grid_magic h1 {
  margin: 0 auto;
  margin-bottom: 2.5%;
  text-align: center;
  padding: 20px 0 20px 0;
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 18pt;
  font-weight: 400;
}

.grid_magic h1 span {
  font-weight: 700;
}

.grid_magic h2{
  font-family: 'Amatic SC', cursive;
  color: black;
  font-size: 20pt;
  font-weight: 400;
  margin-top: 0;
  margin-bottom: 0;
}

.grid_magic a {
  text-decoration: none;
  font-family: 'Amatic SC', cursive;
  color: black;
  margin-top: 5%;
  font-size: 20pt;
}

.grid_magic a:hover {
  text-decoration: underline;
}

    </style>

    <div class="grid_main" id="grid_main">
      <h1 class="header">LET'S PLAY!</h1>
      <a href="javascript: P1vsP2();" id="normal" class="normal">NORMAL</a>
      <a href="javascript: magicBoard();" id="magicBoard" class="magicBoard">MAGIC BOARD</a>
      <a href="javascript: selectDifficulty();" id="vsAI" class="vsAI">PLAY VS AI</a>
    </div>
    
    <div class="grid_AI_setup" id="grid_AI_setup">
      <h1 class="header">SELECT DIFFICULTY</h1>
      <a href="javascript: vsAInoob();" id="beginner" class="beginner">BEGINNER</a>
      <a href="javascript: vsAImiddle();" id="amatuer" class="amateur">AMATEUR</a>
      <a href="javascript: vsAI();" id="master" class="master">MASTER</a>
    </div>



    <div class="grid_normal" id="grid_normal">
      <h1 class="heading"><span id="player1">Player1</span> vs <span id="player2">Player2</span></h1>

      <h2 class="message" id="message"></h2>

      <table class="table" border="1">

        <tr>
          <td class="square" id="tile1" onClick="update(this)"></td>
          <td class="square" id="tile2" onClick="update(this)"></td>
          <td class="square" id="tile3" onClick="update(this)"></td>
        </tr>

        <tr>
          <td class="square" id="tile4" onClick="update(this)"></td>
          <td class="square" id="tile5" onClick="update(this)"></td>
          <td class="square" id="tile6" onClick="update(this)"></td>
        </tr>

        <tr>
          <td class="square" id="tile7" onClick="update(this)"></td>
          <td class="square" id="tile8" onClick="update(this)"></td>
          <td class="square" id="tile9" onClick="update(this)"></td>
        </tr>

      </table>

      <a href="javascript: back();" id="back" class="back">Back</a>
      <a href="javascript: startGame();" id="start_over" class="startOver">Start over!</a>
    </div>
   
    
    
    <div class="grid_AI" id="grid_AI">
    <h1 class="heading"><span id="player_name">Player1</span> vs <span>Computer</span></h1>

    <h2 class="message" id="messageAI"></h2>

    <table class="table" border="1">

      <tr>
        <td class="square" id="tileAI0-0" onClick="updateAI(this, 0, 0)"></td>
        <td class="square" id="tileAI0-1" onClick="updateAI(this, 0, 1)"></td>
        <td class="square" id="tileAI0-2" onClick="updateAI(this, 0, 2)"></td>
      </tr>

      <tr>
        <td class="square" id="tileAI1-0" onClick="updateAI(this, 1, 0)"></td>
        <td class="square" id="tileAI1-1" onClick="updateAI(this, 1, 1)"></td>
        <td class="square" id="tileAI1-2" onClick="updateAI(this, 1, 2)"></td>
      </tr>

      <tr>
        <td class="square" id="tileAI2-0" onClick="updateAI(this, 2, 0)"></td>
        <td class="square" id="tileAI2-1" onClick="updateAI(this, 2, 1)"></td>
        <td class="square" id="tileAI2-2" onClick="updateAI(this, 2, 2)"></td>
      </tr>

    </table>

    <a href="javascript: backAI()" id="backAI" class="back">Back</a>
    <a href="javascript: startGameAI();" id="start_overAI" class="startOver">Start over!</a>
  </div>


    <div class="grid_magic" id="grid_magic">
      <h1 class="heading"><span id="magic1">Player1</span> vs <span id="magic2">Player2</span> vs <span id="magic3">Player3</span></h1>

      <h2 class="message" id="magicMessage"></h2>

      <table class="table" border="1">

        <tr>
          <td class="square" id="magictile1" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile2" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile3" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile4" onClick="updateMagic(this)"></td>
        </tr>

        <tr>
          <td class="square" id="magictile5" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile6" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile7" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile8" onClick="updateMagic(this)"></td>
        </tr>

        <tr>
          <td class="square" id="magictile9" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile10" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile11" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile12" onClick="updateMagic(this)"></td>
        </tr>

        <tr>
          <td class="square" id="magictile13" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile14" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile15" onClick="updateMagic(this)"></td>
          <td class="square" id="magictile16" onClick="updateMagic(this)"></td>
        </tr>

      </table>

      <a href="javascript: backMagic();" id="back" class="back">Back</a>
      <a href="javascript: magicStartGame();" id="start_over" class="startOver">Start over!</a>
    </div>
    
    <!-- <div class="grid_noob" id="grid_noob">
      <h1 class="heading"><span id="player_name_noob"></span> vs <span>Computer</span></h1>

      <h2 class="message" id="messageAInoob"></h2>

      <table class="table" border="1">

        <tr>
          <td class="square" id="tileAI1" onClick="updateAI(this, 0)"></td>
          <td class="square" id="tileAI2" onClick="updateAI(this, 1)"></td>
          <td class="square" id="tileAI3" onClick="updateAI(this, 2)"></td>
        </tr>

        <tr>
          <td class="square" id="tileAI4" onClick="updateAI(this, 3)"></td>
          <td class="square" id="tileAI5" onClick="updateAI(this, 4)"></td>
          <td class="square" id="tileAI6" onClick="updateAI(this, 5)"></td>
        </tr>

        <tr>
          <td class="square" id="tileAI7" onClick="updateAI(this, 6)"></td>
          <td class="square" id="tileAI8" onClick="updateAI(this, 7)"></td>
          <td class="square" id="tileAI9" onClick="updateAI(this, 8)"></td>
        </tr>

      </table>

      <a href="javascript: backAInoob();" id="backAInoob" class="back">Back</a>
      <a href="javascript: startGameAInoob();" id="start_overAInoob" class="startOver">Start over!</a>
    </div> -->
<script>
    function P1vsP2(){
  //Function to set up the game for Player1 vs Player2 mode
  var nope = document.getElementById('grid_main');
  var element = document.getElementById('grid_normal');
  nope.style.display = "none";
  element.style.display = "grid";

  var name1 = "Player1";
  var name2 = "Player2";
  name1 = prompt("Enter first player's name: ");
  name2 = prompt("Enter second player's name: ");
  document.getElementById('player1').innerHTML = name1;
  document.getElementById('player2').innerHTML = name2;
  startGame();
}



function back(){
    //Function to go back to the main screen when playing P1 vs P2 mode
  var nope = document.getElementById('grid_main');
  var element = document.getElementById('grid_normal');
  nope.style.display = "grid";
  element.style.display = "none";
}



function startGame(){
  for(var i = 1; i <= 9; i++){
      document.getElementById("tile" + i).innerText = "";
      document.getElementById("tile" + i).style.color = "black";
  }
  document.turn = "X";
  document.winner = null;
  document.countTiles = 0;
  setMessage(document.turn + " gets to start");
}



function update(square){
  if(document.winner === true){
      setMessage(document.turn + " already won");
  }
  else if(document.countTiles == 9){
      setMessage("It's a draw");
  }
  else if(square.innerText == "X" || square.innerText == "O"){
      setMessage("Pick an empty tile");
  }else{
  square.innerText = document.turn;
  switchTurn(document.turn);
  }
}



function switchTurn(turn){

    //Function that switches turns
    document.countTiles++;
    if(checkForWinner(document.turn)){
      setMessage("Congrats " + document.turn + " you won!");
    }
    else if (turn == "X"){
        document.turn = "O";

        if(document.countTiles == 9){
            setMessage("It's a draw");
        }
        else{
            setMessage(document.turn + "'s turn");
        }
    }
    else{
        document.turn = "X";

        if(document.countTiles == 9){
            setMessage("It's a draw");
        }
        else{
            setMessage(document.turn + "'s turn");
        }
    }
}



function setMessage(msg){
    //Function to set the message
    document.getElementById('message').innerHTML = msg;
}



function returnBox(index){
    //Function to return a selected tile
    return document.getElementById("tile" + index).innerText;
}



function isRowFilled(tile1, tile2, tile3, move){
  //Function to check if any row is filled
  //At first, the value is false
  var isFilled = false;
  if(returnBox(tile1) == move && returnBox(tile2) == move && returnBox(tile3) == move){
      isFilled = true;
      document.getElementById("tile" + tile1).style.color = "red";
      document.getElementById("tile" + tile2).style.color = "red";
      document.getElementById("tile" + tile3).style.color = "red";
  }

  return isFilled;
}



function checkForWinner(move){
  //Function to check if there is a winner
  var isThereAWinner = false;
  if(isRowFilled (1, 2, 3, move) ||
     isRowFilled (4, 5, 6, move) ||
     isRowFilled (7, 8, 9, move) ||
     isRowFilled (1, 4, 7, move) ||
     isRowFilled (2, 5, 8, move) ||
     isRowFilled (3, 6, 9, move) ||
     isRowFilled (1, 5, 9, move) ||
     isRowFilled (3, 5, 7, move)
     ){
         isThereAWinner = true;
         document.winner = true;
     }

   return isThereAWinner;
}






//Code for the AI game mode

function selectDifficulty() {
    //Function so set up the game for P1 vs AI mode
    var nope = document.getElementById('grid_main');
    var element = document.getElementById('grid_AI_setup');
    nope.style.display = "none";
    element.style.display = "grid";
}


document.difficulty; //Defines difficulty;





function vsAI(){
    //Function so set up the game for P1 vs AI mode
    alert("Whoever goes first is selected randomly \n\nMaster level AI is impossible to beat \n\nIMPORTANT NOTE: If computers gets to start, give him some time to work out the move");
    var nope = document.getElementById('grid_AI_setup');
    var element = document.getElementById('grid_AI');
    nope.style.display = "none";
    element.style.display = "grid";

    document.playerName = "Player1";
    document.playerName = prompt("Enter your name: ");
    document.getElementById('player_name').innerHTML = document.playerName;
    document.difficulty = 3;
    startGameAI();
}

function vsAInoob(){
    //Function so set up the game for P1 vs AI mode
    alert("Whoever goes first is selected randomly \n\nBeginner level AI is really simple, so it is pretty easy to win\n\nIMPORTANT NOTE: If computers gets to start, give him some time to work out the move");
    var nope = document.getElementById('grid_AI_setup');
    var element = document.getElementById('grid_AI');
    nope.style.display = "none";
    element.style.display = "grid";

    document.playerName = "Player1";
    document.playerName = prompt("Enter your name: ");
    document.getElementById('player_name').innerHTML = document.playerName;
    document.difficulty = 1;
    startGameAI();
}

function vsAImiddle(){
    //Function so set up the game for P1 vs AI mode
    alert("Whoever goes first is selected randomly \n\nAmateur level AI plays different each turn, it might play very good or like a complete beginner \n\nIMPORTANT NOTE: If computers gets to start, give him some time to work out the move");
    var nope = document.getElementById('grid_AI_setup');
    var element = document.getElementById('grid_AI');
    nope.style.display = "none";
    element.style.display = "grid";

    document.playerName = "Player1";
    document.playerName = prompt("Enter your name: ");
    document.getElementById('player_name').innerHTML = document.playerName;
    document.difficulty = 2;
    startGameAI();
}

function backAI(){
    //Function to go back to the main screen when playing P1 vs P2 mode
  var nope = document.getElementById('grid_main');
  var element = document.getElementById('grid_AI');
  nope.style.display = "grid";
  element.style.display = "none";
}

function setMessageAI(msg){
    //Function to set the message
    document.getElementById('messageAI').innerHTML = msg;
}

/*
   Board state array -  contains 9 integers, each one representing one tile of the game board
   * 0 means empty(free, available)
   * 1 means taken by human
   * -1 means taken by AI
*/
  document.boardState  = [
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
  ];

  const HUMANVALUE = 1;
  const COMPUTERVALUE = -1;

  document.player;
  document.countTilesAI;





//Function to start the game / restart the game
function startGameAI(){
  for (var a = 0; a < 3; a++){
    for(var b = 0; b < 3; b++){
      document.getElementById("tileAI" + a + "-" + b).innerText = "";
      document.getElementById("tileAI" + a + "-" + b).style.color = "black";
    }
  }

  for (var j = 0; j < 3; j++){
    for(var k = 0; k < 3; k++){
      document.boardState[j][k] = 0;
    }
  }

  document.AIturn = "X";
  document.countTilesAI = 0;

  //The player who starts the game is decided randomly;
  if (Math.floor(Math.random() * 2) === 0){
      document.player = "HUMAN";
  }
  else{
      document.player = "COMPUTER";
  }

  if(document.player === "HUMAN"){
      setMessageAI(document.playerName + ", you get to start");
  }
  else{
      setMessageAI("Computer gets to start");

      //Uncomment the line below if you want the AI to be called with a timer
      //But don't forget to comment the other line!
      // No timer --> moveAI();
      // With timer --> BELOW
      setTimeout(moveAI, 500);
  }
}





function checkForWinnerAI(board){
  //Function to check if there is a winner

  //Check horizontal
  for (var i = 0; i < 3; i++){
    if (board[i][0] !== 0 &&
      board[i][0] === board [i][1] &&
      board[i][0] === board [i][2]){
        return board[i][0];
      }
  }

  //Check vertical
  for (var j = 0; j < 3; j++){
    if (board[0][j] !== 0 &&
      board[0][j] === board [1][j] &&
      board[0][j] === board [2][j]){
        return board[0][j];
      }
  }

  //Check diagonal: Top left - bottom right;
  if (board[0][0] !== 0 &&
    board[0][0] === board [1][1] &&
    board[0][0] === board [2][2]){
      return board[0][0];
  }

  //Check diagonal: Top left - bottom right;
  if (board[2][0] !== 0 &&
    board[2][0] === board [1][1] &&
    board[2][0] === board [0][2]){
      return board[2][0];
  }

  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (board[i][j] === 0){
        return false;
      }
    }
  }
  return null;
}

function checkFull(board){
  for(var x = 0; x < 3; x++){
    for(var y = 0; y < 3; y++)
    if(board[x][y] === 0) return false;
  }

  return true;
}





function updateAI(square, row, column){
  let gameState = checkForWinnerAI(document.boardState);

  if(document.player != "HUMAN"){
    return;
  }
  if(gameState !== null && gameState !== false){
    if(gameState === HUMANVALUE){
      setMessageAI(document.playerName + ", you already won!");
    }
    else{
      setMessageAI("Computer already won");
    }
  }
  else if(checkFull(document.boardState)){
    setMessageAI("It's a draw. Start over!");
  }
  else if(document.boardState[row][column] !== 0){
      setMessageAI("Pick an empty tile");
  }
  else{
      square.innerText = document.AIturn;
      document.boardState[row][column] = HUMANVALUE;
      switchTurnAI(document.AIturn, document.player);

      //Uncomment the line below if you want the AI to be called with a timer
      //But don't forget to comment the other line!
      // No timer --> moveAI();
      // With timer --> BELOW
      setTimeout(moveAI, 500);
  }
}

//Function to switch the turn
function switchTurnAI(turn, currentPlayer){

  document.countTilesAI++;
  let gameState = checkForWinnerAI(document.boardState);

  if(gameState !== null && gameState !== false){
    if(gameState === HUMANVALUE){

      //Check horizontal
      for (var i = 0; i < 3; i++){
        if (document.boardState[i][0] !== 0 &&
          document.boardState[i][0] === document.boardState [i][1] &&
          document.boardState[i][0] === document.boardState [i][2]){
            document.getElementById("tileAI" + i + "-" + 0).style.color = "red";
            document.getElementById("tileAI" + i + "-" + 1).style.color = "red";
            document.getElementById("tileAI" + i + "-" + 2).style.color = "red";
          }
      }

      //Check vertical
      for (var j = 0; j < 3; j++){
        if (document.boardState[0][j] !== 0 &&
          document.boardState[0][j] === document.boardState [1][j] &&
          document.boardState[0][j] === document.boardState [2][j]){
            document.getElementById("tileAI" + 0 + "-" + j).style.color = "red";
            document.getElementById("tileAI" + 1 + "-" + j).style.color = "red";
            document.getElementById("tileAI" + 2 + "-" + j).style.color = "red";
          }
      }

      //Check diagonal: Top left - bottom right;
      if (document.boardState[0][0] !== 0 &&
        document.boardState[0][0] === document.boardState [1][1] &&
        document.boardState[0][0] === document.boardState [2][2]){
          document.getElementById("tileAI" + 0 + "-" + 0).style.color = "red";
          document.getElementById("tileAI" + 1 + "-" + 1).style.color = "red";
          document.getElementById("tileAI" + 2 + "-" + 2).style.color = "red";
      }

      //Check diagonal: Top left - bottom right;
      if (document.boardState[2][0] !== 0 &&
        document.boardState[2][0] === document.boardState [1][1] &&
        document.boardState[2][0] === document.boardState [0][2]){
          document.getElementById("tileAI" + 2 + "-" + 0).style.color = "red";
          document.getElementById("tileAI" + 1 + "-" + 1).style.color = "red";
          document.getElementById("tileAI" + 0 + "-" + 2).style.color = "red";
      }

      setMessageAI("Congrats " + document.playerName +  " you won!");
      return;
    } else{

      //Check horizontal
      for (var i = 0; i < 3; i++){
        if (document.boardState[i][0] !== 0 &&
          document.boardState[i][0] === document.boardState [i][1] &&
          document.boardState[i][0] === document.boardState [i][2]){
            document.getElementById("tileAI" + i + "-" + 0).style.color = "red";
            document.getElementById("tileAI" + i + "-" + 1).style.color = "red";
            document.getElementById("tileAI" + i + "-" + 2).style.color = "red";
          }
      }

      //Check vertical
      for (var j = 0; j < 3; j++){
        if (document.boardState[0][j] !== 0 &&
          document.boardState[0][j] === document.boardState [1][j] &&
          document.boardState[0][j] === document.boardState [2][j]){
            document.getElementById("tileAI" + 0 + "-" + j).style.color = "red";
            document.getElementById("tileAI" + 1 + "-" + j).style.color = "red";
            document.getElementById("tileAI" + 2 + "-" + j).style.color = "red";
          }
      }

      //Check diagonal: Top left - bottom right;
      if (document.boardState[0][0] !== 0 &&
        document.boardState[0][0] === document.boardState [1][1] &&
        document.boardState[0][0] === document.boardState [2][2]){
          document.getElementById("tileAI" + 0 + "-" + 0).style.color = "red";
          document.getElementById("tileAI" + 1 + "-" + 1).style.color = "red";
          document.getElementById("tileAI" + 2 + "-" + 2).style.color = "red";
      }

      //Check diagonal: Top left - bottom right;
      if (document.boardState[2][0] !== 0 &&
        document.boardState[2][0] === document.boardState [1][1] &&
        document.boardState[2][0] === document.boardState [0][2]){
          document.getElementById("tileAI" + 2 + "-" + 0).style.color = "red";
          document.getElementById("tileAI" + 1 + "-" + 1).style.color = "red";
          document.getElementById("tileAI" + 0 + "-" + 2).style.color = "red";
      }


      setMessageAI("You were defeated. Start over!");
      return;
    }
  }
  else if(turn == "X"){
    document.AIturn = "O";

    if(checkFull(document.boardState)){ //Check if it is a draw
        setMessageAI("It's a draw. Start over!");
    }
    else{
      if(currentPlayer === "HUMAN"){
        document.player = "COMPUTER";
        setMessageAI("It's computer's turn");
      }
      else{
        document.player = "HUMAN";
        setMessageAI("It's your turn, " + document.playerName + "!");
      }
    }
  }
  else if (turn == "O"){
    document.AIturn = "X";

    if(checkFull(document.boardState)){ //Check if it is a draw
        setMessageAI("It's a draw. Start over!");
    }
    else{
      if(currentPlayer === "HUMAN"){
        document.player = "COMPUTER";
        setMessageAI("It's computer's turn");
      }
      else{
        document.player = "HUMAN";
        setMessageAI("It's your turn, " + document.playerName + "!");
      }
    }
  }
}


function minmax(newGrid, depth, player){

  const gameState = checkForWinnerAI(newGrid);

  if(gameState === false){
    const values = [];

    for(var i = 0; i < 3; i++){
      for(var j = 0; j < 3; j++){
        const gridCopy = _.cloneDeep(newGrid);
        if (gridCopy[i][j] !== 0) continue;
        gridCopy[i][j] = player;
        const value = minmax(gridCopy, depth + 1, (player === HUMANVALUE) ? COMPUTERVALUE : HUMANVALUE);
        values.push({
          cost: value,
          cell: {
            i: i,
            j: j
          }
        });
      }
    }

    if (player === COMPUTERVALUE){
      const max = _.maxBy(values, (v) => {
        return v.cost;
      });
      if (depth === 0) {
        return max.cell;
      } else {
        return max.cost;
      }
    } else {
      const min = _.minBy(values, (v) => {
        return v.cost;
      });
      if (depth === 0) {
        return min.cell;
      } else {
        return min.cost;
      }
    }

  } else if (gameState === null) {
    return 0;
  } else if (gameState === HUMANVALUE) {
    return depth - 10;
  } else {
    return 10 - depth;
  }
}



function minmaxnoob(newGrid, depth, player){

  const gameState = checkForWinnerAI(newGrid);

  if(gameState === false){
    const values = [];

    for(var i = 0; i < 3; i++){
      for(var j = 0; j < 3; j++){
        const gridCopy = _.cloneDeep(newGrid);
        if (gridCopy[i][j] !== 0) continue;
        gridCopy[i][j] = player;
        const value = minmaxnoob(gridCopy, depth + 1, (player === HUMANVALUE) ? COMPUTERVALUE : HUMANVALUE);
        values.push({
          cost: value,
          cell: {
            i: i,
            j: j
          }
        });
      }
    }

    if (player === HUMANVALUE){
      const max = _.maxBy(values, (v) => {
        return v.cost;
      });
      if (depth === 0) {
        return max.cell;
      } else {
        return max.cost;
      }
    } else {
      const min = _.minBy(values, (v) => {
        return v.cost;
      });
      if (depth === 0) {
        return min.cell;
      } else {
        return min.cost;
      }
    }

  } else if (gameState === null) {
    return 0;
  } else if (gameState === HUMANVALUE) {
    return depth - 10;
  } else {
    return 10 - depth;
  }
}



function callAI(){
  return minmax(document.boardState, 0, COMPUTERVALUE);
}

function callAInoob(){
  return minmaxnoob(document.boardState, 0, COMPUTERVALUE);
}

//Function for the AI move;
function moveAI(){
  let gameState = checkForWinnerAI(document.boardState);

  if(document.player != "COMPUTER"){
    return;
  } else if (gameState !== null && gameState !== false){
    if(gameState === HUMANVALUE){
      setMessageAI(document.playerName + ", you already won!");
    } else{
      setMessageAI("Computer already won");
    }
  } else{
      
      if (document.difficulty === 1) {
      
          if (document.countTilesAI === 0){
              
              let startMove1 = Math.floor((Math.random() * 4) + 1);
              if (startMove1 === 1) {
                  document.boardState[0][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove1 === 2) {
                  document.boardState[0][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove1 === 3) {
                  document.boardState[2][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove1 === 4) {
                  document.boardState[2][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              }
          } else {
              const noob = callAInoob();
              document.boardState[noob.i][noob.j] = COMPUTERVALUE;
              document.getElementById("tileAI" + noob.i + "-" + noob.j).innerText = document.AIturn;
              switchTurnAI(document.AIturn, document.player);
          }
      } else if (document.difficulty === 2) {
          
          if (document.countTilesAI === 0){
              
              let startMove2 = Math.floor((Math.random() * 4) + 1);
              if (startMove2 === 1) {
                  document.boardState[0][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove2 === 2) {
                  document.boardState[0][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove2 === 3) {
                  document.boardState[2][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove2 === 4) {
                  document.boardState[2][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              }
          } else {
              let whatMove = Math.floor((Math.random() * 100) + 1);
              if (whatMove > 40) {
                  const move2 = callAI();
                  document.boardState[move2.i][move2.j] = COMPUTERVALUE;
                  document.getElementById("tileAI" + move2.i + "-" + move2.j).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else {
                  const movenoob2 = callAInoob();
                  document.boardState[movenoob2.i][movenoob2.j] = COMPUTERVALUE;
                  document.getElementById("tileAI" + movenoob2.i + "-" + movenoob2.j).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              }
          }
      } else if (document.difficulty === 3) {
          
          if (document.countTilesAI === 0){
              
              let startMove3 = Math.floor((Math.random() * 4) + 1);
              if (startMove3 === 1) {
                  document.boardState[0][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove3 === 2) {
                  document.boardState[0][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 0 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove3 === 3) {
                  document.boardState[2][0] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 0).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              } else if (startMove3 === 4) {
                  document.boardState[2][2] = COMPUTERVALUE;
                  document.getElementById("tileAI" + 2 + "-" + 2).innerText = document.AIturn;
                  switchTurnAI(document.AIturn, document.player);
              }
          } else {
              const move = callAI();
              document.boardState[move.i][move.j] = COMPUTERVALUE;
              document.getElementById("tileAI" + move.i + "-" + move.j).innerText = document.AIturn;
              switchTurnAI(document.AIturn, document.player);
          }
      }
  }
}



 

















//Javascript for magic board game
function magicBoard(){
  //Function to set up the game for Player1 vs Player2 mode
  var nope = document.getElementById('grid_main');
  var element = document.getElementById('grid_magic');
  nope.style.display = "none";
  element.style.display = "grid";

  var name1 = "Player1";
  var name2 = "Player2";
  var name3 = "Player3";
  name1 = prompt("Enter first player's name: ");
  name2 = prompt("Enter second player's name: ");
  name3 = prompt("Enter third player's name: ");
  document.getElementById('magic1').innerHTML = name1;
  document.getElementById('magic2').innerHTML = name2;
  document.getElementById('magic3').innerHTML = name3;
  magicStartGame();
}



function backMagic(){
    //Function to go back to the main screen when playing P1 vs P2 mode
  var nope = document.getElementById('grid_main');
  var element = document.getElementById('grid_magic');
  nope.style.display = "grid";
  element.style.display = "none";
}



function magicStartGame(){
  for(var i = 1; i <= 16; i++){
      document.getElementById("magictile" + i).innerText = "";
      document.getElementById("magictile" + i).style.color = "black";
  }
  document.turn = "X";
  document.winner = null;
  document.countTiles = 0;
  setMessageMagic(document.turn + " gets to start");
}



function updateMagic(square){
  if(document.winner === true){
      setMessageMagic(document.turn + " already won");
  }
  else if(document.countTiles == 16){
      setMessageMagic("It's a draw");
  }
  else if(square.innerText === "X" || square.innerText === "O" || square.innerText === "M"){
      setMessageMagic("Pick an empty tile");
  }else{
  square.innerText = document.turn;
  switchTurnMagic(document.turn);
  }
}



function switchTurnMagic(turn){

    //Function that switches turns
    document.countTiles++;
    if(checkForWinnerMagic(document.turn)){
      setMessageMagic("Congrats " + document.turn + " you won!");
    }
    else if (turn == "X"){
        document.turn = "O";

        if(document.countTiles == 16){
            setMessageMagic("It's a draw");
        }
        else{
            setMessageMagic(document.turn + "'s turn");
        }
    }
    else if (turn == "O"){
        document.turn = "M";

        if(document.countTiles == 16){
            setMessageMagic("It's a draw");
        }
        else{
            setMessageMagic(document.turn + "'s turn");
        }
    }
    else{
        document.turn = "X";

        if(document.countTiles == 16){
            setMessageMagic("It's a draw");
        }
        else{
            setMessageMagic(document.turn + "'s turn");
        }
    }
}


function setMessageMagic(msg){
    //Function to set the message
    document.getElementById('magicMessage').innerHTML = msg;
}



function returnBoxMagic(index){
    //Function to return a selected tile
    return document.getElementById("magictile" + index).innerText;
}



function isRowFilledMagic(tile1, tile2, tile3, move){
  //Function to check if any row is filled
  //At first, the value is false
  var isFilled = false;
  if(returnBoxMagic(tile1) == move && returnBoxMagic(tile2) == move && returnBoxMagic(tile3) == move){
      isFilled = true;
      document.getElementById("magictile" + tile1).style.color = "red";
      document.getElementById("magictile" + tile2).style.color = "red";
      document.getElementById("magictile" + tile3).style.color = "red";
  }

  return isFilled;
}



function checkForWinnerMagic(move){
  //Function to check if there is a winner
  var isThereAWinner = false;
  if(isRowFilledMagic (1, 2, 3, move) ||
     isRowFilledMagic (5, 6, 7, move) ||
     isRowFilledMagic (9, 10, 11, move) ||
     isRowFilledMagic (13, 14, 15, move) ||
     isRowFilledMagic (2, 3, 4, move) ||
     isRowFilledMagic (6, 7, 8, move) ||
     isRowFilledMagic (10, 11, 12, move) ||
     isRowFilledMagic (14, 15, 16, move) ||
     isRowFilledMagic (1, 5, 9, move) ||
     isRowFilledMagic (2, 6, 10, move) ||
     isRowFilledMagic (3, 7, 11, move) ||
     isRowFilledMagic (4, 8, 12, move) ||
     isRowFilledMagic (5, 9, 13, move) ||
     isRowFilledMagic (6, 10, 14, move) ||
     isRowFilledMagic (7, 11, 15, move) ||
     isRowFilledMagic (8, 12, 16, move) ||
     isRowFilledMagic (5, 10, 15, move) ||
     isRowFilledMagic (1, 6, 11, move) ||
     isRowFilledMagic (6, 11, 16, move) ||
     isRowFilledMagic (2, 7, 12, move) ||
     isRowFilledMagic (3, 6, 9, move) ||
     isRowFilledMagic (4, 7, 10, move) ||
     isRowFilledMagic (7, 10, 13, move) ||
     isRowFilledMagic (8, 11, 14, move)
     ){
         isThereAWinner = true;
         document.winner = true;
     }

   return isThereAWinner;
}

    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
    <script src="tictactoe.js"></script>
  </body>

</html>

2. By dρlυѕρlΟ…Ρ•

Made by dρlυѕρlΟ…Ρ•. A very simple tic tac toe game. You can click the switch button at the bottom to select a different symbol, you can also reset the game by clicking the reset button. The game also keeps history of the wins, lose and draws. ( Source )

<!DOCTYPE html>
<!--
Created: 26.10.2017.
Original design:  https://dribbble.com/shots/3402966-Tic-Tac-Toe
To choose the symbol specifically, use the switch each time.
-->

<html>
    <head>
     <title>Tic tac toe</title>
        <meta charset="utf-8">
        <meta name="author" content="dplusplus" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"> </script>
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    </head>
    <body>
        <style>
            @import url('https://fonts.googleapis.com/css?family=Nunito');

*{
  font-family: "Nunito", sans-serif;
}

body{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  overflow: hidden;
}


.wrap{
  position: absolute;
  top:50%;
  left:50%;
  transform:translate(-50%,-50%);
  height: 440px;
  max-height: 440px;
  width: 340px;
  border: solid thin #01bbc2;
  border-image: -webkit-linear-gradient(to top, #01bbc2, #3150ce);
  border-image-slice: 1;
  box-shadow: 0 15px 25px rgba(1, 118, 122, 0.2);
 
}


table {
  margin: 0px;
  border-collapse: collapse;
  border-style: hidden;
  position: absolute;
  top:50%;
  left:50%;
  transform:translate(-50%,-50%);
  height:200px;
  max-height: 200px;
  width: 200px;
  table-layout: fixed;
 
  /*box-shadow: 0 2px 8px rgba(0,0,0,0.3);*/
 
}
table td {
  padding: 0px;
  border: 5px solid #ddd;
  
  
}

.cell {
  text-align: center;
  font-family: "Nunito", sans-serif;
  font-weight: 900;
  margin: 0px;
  white-space: nowrap;
  height: 80px;
  max-height: 80px;
  width: 90px;
  position: relative;
  display: table-cell;
  color: #01bbc2;
}

span.fa-4x{
    font-size: 57px ;
}
span.fa-times{
    font-size: 62px;
}


header {
  height: 10%;
  width: 100%;
  margin: 0;
  position: absolute;
  top: 0%; 
  padding: 20px;
  display: inline-block;
  /*background-color: yellow;*/
  
}

/*#o_win, #draws{
    padding-left: 50px;
}*/

#x_win{
  color: #547cd8;
  top: 13px; left:  35px;
  position: absolute;
}
#o_win{
   color: #01bbc2;
   top: 18px; left: 150px;
   position: absolute;
}
#draws{
  color: #888;
  top: 19px; left: 270px;
  position: absolute;
  
}

#ooo,#xx,#draws0 {
    font-variant-numeric:tabular-nums;
}


.fa-times{
  font-size: 34px;
  
}

.fa-circle-o{
  font-size: 27px;
}

.fa-balance-scale{
   font-size: 23px;
  
}



/*footer*/

#result {
  color: #01bbc2;
  font-size: 20px;
  font-family: "Nunito";
  position: relative;
  bottom: 40px; left: 130px;
}

footer{
  width: 100%;
  height: 15%;
  position: absolute;
  bottom: 0px; 
  display: inline-flex;
  
}


/*switch*/

.toggleXO{
  position: absolute;
  bottom: 15px; left: 250px;
  width: 60px;
  height: 30px;
  display: inline;
  
}
.toggleXO  input{
  display: none;
}

.slider::before{
  content:"βœ–";
  color: #547cd8;
  position: absolute;
  cursor: pointer;
  top: 0px; left: 10px;
  font-weight: 500;
  font-size:20px;
}
.slider{
 
  position: absolute;
  cursor: pointer;
  top: 0; left: 0;
  bottom:0; right: 0;
  /*border: 1px solid red;*/
  background: rgba(0, 0, 0, 0.2);
  background-color: #fff;
  box-shadow: inset 0 0 2px 2px rgba(0, 0, 0, 0.2), inset 0 0 3px 3px rgba(0, 0, 0, 0.1), 0 0 1px 1px rgba(255, 255, 255, 0.1);
  border-radius: 25px;
  -webkit-transition: .25s;
  transition: .25s;
}
.slider::after {
    
    content: " β—― ";
    padding-top: 6px;
    padding-left: 7px;
    position: absolute;
    height: 34px;
    width: 34px;
    left: 0px; bottom: -2px;
    -webkit-transition: .3s;
    transition: .3s;
    border-radius: 50%;
    background-color: #01bbc2;
    color: #fff;
    font-weight: 900;
   /* box-shadow: 0 2px 5px rgba(85, 85, 85, 0.7)*/;
  }
input:checked + .slider::after {
   transform: translateX(35px); 
}

.fa-refresh {
    font-size: 20px;
}
#butt_reset{
  width: 34px;
  height: 34px;
  border-radius: 100%;
  border: none;
  outline: none;
  position: relative;
  color: #fff;
  background-color: #bbb;
  bottom: -1px;
  
}

 #butt_reset.active{
  background-color: #999;
  bottom: -2px;
  transition: background-color .25s ease;
  outline: none;
}

#around {
  border: 1px solid #ddd;
  position: absolute;
  left: 30px; bottom: 13px;
  width: 45px;
  height: 45px;
  border-radius: 100%;
  padding: 3px 8px 4px 4px;
  
}
            </style>
        <div class="wrap">
<header>
 
    <div id="x_win"> <i class="fa fa-times" aria-hidden="true"> </i> <div id="xx"> wins </div></div>
   <div id="o_win"> <i class="fa fa-circle-o" aria-hidden="true"></i><div id="ooo"> wins </div> </div>
   <div id="draws"> <i class="fa fa-balance-scale" aria-hidden="true"></i> <div id="draw0"> draws</div></div>
 
</header>
<table id="board">
  <tr>
    <td class="cell" id="cell_1" onclick="cell_click('cell_1');"></td>
    <td class="cell" id="cell_2" onclick="cell_click('cell_2');"></td>
    <td class="cell" id="cell_3" onclick="cell_click('cell_3');"></td>
  </tr>
  <tr>
    <td class="cell" id="cell_4" onclick="cell_click('cell_4');"></td>
    <td class="cell" id="cell_5" onclick="cell_click('cell_5');"></td>
    <td class="cell" id="cell_6" onclick="cell_click('cell_6');"></td>
    
  </tr>
  <tr>
    <td class="cell" id="cell_7" onclick="cell_click('cell_7');"></td>
    <td class="cell" id="cell_8" onclick="cell_click('cell_8');"></td>
    <td class="cell" id="cell_9" onclick="cell_click('cell_9');"></td>

  </tr>
</table>
 <footer>

  <label class="toggleXO">
  <input id="myCheckBox" type="checkbox" onclick="switchxo();">
  <span class="slider"></span>
      </label>
     
        <div id="around">
          <button id="butt_reset" onclick="reset(), button();" value="RESET"> <i class="fa fa-refresh " aria-hidden="true"></i> </button>
        </div>
        <h3 id="result"> # result </h3>


      </footer>
     </div>
        
        <script>
            
//there's still a bug in cwitch
// work in progress

window.onload = function(){
 
};


var countx= 0;
var count=0;
var counto=0;
var count_draws=0;
var player = 0;
var checkcheck= false;
var x= '<span class="fa fa-times"></span>';
var o= '<span class="fa fa-circle-o fa-4x"></span>';


function cell_click(cell){
  document.getElementById("result").innerHTML= "# result";
  var element= document.getElementById(cell);
  
   if(element.innerHTML != "") return;

    if(player == 1) {
        element.innerHTML = x;
        element.style.color= "#547cd8";
        player -= 1;
        ++count;
        winner ();
    } else {
        element.innerHTML = o;
        element.style.color= "#01bbc2";
        player += 1;
        ++count;
        winner ();
    }
}


function winner(){
  if( 
//horizontal X
document.getElementById("cell_1").innerHTML == x && document.getElementById("cell_2").innerHTML == x && document.getElementById("cell_3").innerHTML == x || document.getElementById("cell_4").innerHTML == x  && document.getElementById("cell_5").innerHTML == x  && document.getElementById("cell_6").innerHTML == x || document.getElementById("cell_7").innerHTML == x  && document.getElementById("cell_8").innerHTML == x && document.getElementById("cell_9").innerHTML == x  ||

//vertical X   
document.getElementById("cell_1").innerHTML == x  && document.getElementById("cell_4").innerHTML == x  && document.getElementById("cell_7").innerHTML == x  || document.getElementById("cell_2").innerHTML == x  && document.getElementById("cell_5").innerHTML == x  && document.getElementById("cell_8").innerHTML == x  || document.getElementById("cell_3").innerHTML == x  && document.getElementById("cell_6").innerHTML == x  && document.getElementById("cell_9").innerHTML == x ||
//diagonal X
document.getElementById("cell_1").innerHTML == x  && document.getElementById("cell_5").innerHTML == x  && document.getElementById("cell_9").innerHTML == x || document.getElementById("cell_3").innerHTML == x  && document.getElementById("cell_5").innerHTML == x  && document.getElementById("cell_7").innerHTML == x 
    ){
 document.getElementById("result").innerHTML= "# X won";
    ++countx;
   document.getElementById("xx").innerHTML= countx +"&nbsp;" + "wins";   
   reset();
    count= 0;
   //  document.getElementById("result").innerHTML= "result";
  } else if ( 
//horizontal O
document.getElementById("cell_1").innerHTML == o  && document.getElementById("cell_2").innerHTML == o && document.getElementById("cell_3").innerHTML == o || document.getElementById("cell_4").innerHTML == o && document.getElementById("cell_5").innerHTML == o && document.getElementById("cell_6").innerHTML == o || document.getElementById("cell_7").innerHTML == o && document.getElementById("cell_8").innerHTML == o && document.getElementById("cell_9").innerHTML == o ||
//vertical O   
document.getElementById("cell_1").innerHTML == o && document.getElementById("cell_4").innerHTML == o && document.getElementById("cell_7").innerHTML == o || document.getElementById("cell_2").innerHTML == o && document.getElementById("cell_5").innerHTML == o && document.getElementById("cell_8").innerHTML == o || document.getElementById("cell_3").innerHTML == o && document.getElementById("cell_6").innerHTML == o && document.getElementById("cell_9").innerHTML == o ||
//diagonal O
document.getElementById("cell_1").innerHTML == o && document.getElementById("cell_5").innerHTML == o && document.getElementById("cell_9").innerHTML == o || document.getElementById("cell_3").innerHTML == o && document.getElementById("cell_5").innerHTML == o && document.getElementById("cell_7").innerHTML == o
    ){
    
  document.getElementById("result").innerHTML= "# O won";
    ++counto;
  document.getElementById("ooo").innerHTML=  counto +"&nbsp;" + "wins";  
    reset();
    count=0;
    //document.getElementById("result").innerHTML= "result";
  } 

 else if (count == 9){
    ++count_draws;
    document.getElementById("draw0").innerHTML=  count_draws +"&nbsp;" + "draws"; 
   document.getElementById("result").innerHTML= "# draw";
    reset();
   count = 0;
   
  // document.getElementById("result").innerHTML= "result";
}
}

function reset (){
  //reset buttons to empty
 
  document.getElementById("cell_1").innerHTML = "";
  document.getElementById("cell_2").innerHTML = "";
  document.getElementById("cell_3").innerHTML = "";
  document.getElementById("cell_4").innerHTML = "";
  document.getElementById("cell_5").innerHTML = ""; 
  document.getElementById("cell_6").innerHTML = "";
  document.getElementById("cell_7").innerHTML = "";
  document.getElementById("cell_8").innerHTML = "";
  document.getElementById("cell_9").innerHTML = ""; 
  count=0;
};


function switchxo(){
  reset();
  var check= document.getElementById("myCheckBox").checked;
  
   if(!checkcheck){ 
     player = 1;

   } else {
     player = 0; 
   }
checkcheck = !checkcheck;
};

function button(){
  var b= document.getElementById("butt_reset");
  b.classList.toggle("active", 200);
}
            </script>
    </body>
</html>

3. By Madhav

Made by Madhav. A Tic Tac Toe JavaScript App. By default the game mode is set to medium, and you play with a AI. To change that click the menu icon and after that go to settings, in settings select the options you want to enable, like two player mode, or a difficult AI Mode. ( Source )

<!DOCTYPE html>
<html>
    <head>
      <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css?family=Merienda|Montserrat|EB+Garamond|Raleway" rel="stylesheet">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    
        <title>Tic Tac Toe | [ Game ]</title>
    </head>
    <body>
        <style>
            body {
    margin:0; padding:0;
    background-color:#262626;
    user-select:none;
    color:white;
    font-family: 'EB Garamond', serif;
}
i {
    margin:3px;
}
img{
    width:80%; max-width:500px;
    margin:auto;
    border-radius:5px;
}
header {

    display:block;
    top:0;  margin:0;
    text-align:center;
    background-color:#00C4C4;
    width:100%;
    color:#262626;
    height:58px;
    z-index:10;
}
h1 {
    text-align:center;
    margin:0;
     padding:7px; color:#262626;
     z-index:12;
}
#openMenu,#closeMenu {
    position:absolute ;
    display:block;
    top:10px; left:10px;
    background-color:transparent ;
    height:40px;  width:60px;
}
#openMenu > span {
    position:relative ;
    display:block ;
    height:4px; width:36px;
    margin:6px;
    background-color:#262626;
    transition-duration:0.5s;
}
#closeMenu {
    z-index:-1;
}
#menuHolder {
    display:block;
    position:absolute;
    width:100%; 
    background-color:#00C4C4;
    top:60px; left:-100%;
    height:calc(100% - 60px);
    transition-duration:0.55s;
    z-index:10;
}
nav {
    position:relative;
    display:block ;
    width:48%; max-width:380px;
    padding:15px;
    margin:40px auto 40px auto;
    text-align:center;
    font-size:20px;
    color:white;
    border-radius:5px;
    font-weight:bold;
    font-family: 'Merienda', cursive;     
}
#sett {
    background-color:#1C252E;
}
.tab {
    position:absolute ;
    display:block ;
    top:70px; width:100%;
    visibility:hidden;
}
#HOME {
    padding-top:20px;
    font-family: 'Raleway', sans-serif;
}
#ABOUT > p {
    text-align:left;
    margin:50px;
    font-size:19px;
    font-family: 'Merienda', cursive; 
}
span {
    font-family: 'EB Garamond', serif;
    font-size:22px;
    font-weight:bold ;
}
#INST > p > span {
    color:#00C4C4;
    margin:10px;
}
#INST > p {
    text-align:left;
    margin:10px;
    font-size:16px;
    font-family: 'Merienda', cursive;
}
table {
    display:block ;
    position:relative ;
    margin:auto;
    margin-top:10px;
    color:#FF0066;
    text-align:center;
    font-weight:bolder;
    font-size:42px;
    border-collapse:collapse;
    width:312px;
}
td{ 
    height:100px; width:100px;
    background-color:#353F4A;
    border-radius:4px;
    border:3px solid #E90663;
}

table tr:first-child td {
    border-top:0;
}
table tr:last-child td {
    border-bottom:0;
}
table tr td:first-child {
    border-left:0;
}
table tr td:last-child {
    border-right:0;
}

.pad,.block {
    height:60px; width:60px;
    margin:10px; padding:10px;
    background-color:#00C4C4;
    border-radius:4px;
    transition-duration:.18s;
}
 
#level,#player {
    display:block ;
    position:relative ;
    margin:auto; margin-top:10px;
    outline:none; 
    border-radius:30px;
    border:none;
    width:75%; max-width:380px;
    padding:15px 25px 15px 35px;
    background-color:white;
    box-shadow:0 1px 3px rgba(0,0,0,0.12), 0 3px 5px rgba(0,0,0,0.3);
    font-size:16px;
   font-family: 'Merienda', cursive; 

}
#SETT {
    text-align:center;
    padding-top:10px;
    visibility:visible;
}
#SETT > span {
    color:#00C4C4;
    margin:10px;
}
.block {
    display:inline-block ;
    position:relative ;
    height:50px; width:50px;
    margin:20px; margin-bottom:0px;
    color:#FF0066;
    text-align:center;
    font-weight:bolder;
    font-size:40px;
    font-family: 'Raleway', sans-serif;
    background-color:#fff;
    transition-duration:0s;
}
button {
    display:block ;
    position:relative;
    background-image:-webkit-linear-gradient(-45deg,#13547a,#80d0c7);
    color:white; margin:auto;
    border:none;  outline:none;
    border-radius:10px;
    height:54px;  width:34%;
    margin-top:30px;
    max-width:200px;
    font-size:20px;
    font-weight:bold;
    box-shadow:0 1px 3px rgba(0,0,0,0.12), 0 3px 5px rgba(0,0,0,0.3);
    cursor:pointer;
    font-family: 'EB Garamond', serif;

}
button:active
{
    box-shadow:0 0 black;
    transform:scale(0.84);
}
#x {
    color:white;
    background-color:#00C4C4;
}
#result {
    margin:0; padding:0;
    display:block ;
    position:relative ;
    margin:auto;
    text-align:center;
}
#result > div {
    display:inline-block;
    font-family: 'Raleway', sans-serif;    
}
#res2{
    margin-left:65px;
}
#sym1 {    color:lightgreen;  
           font-family: 'Raleway', sans-serif;      
}
#sym2 {    color:#FF0066;    
font-family: 'Raleway', sans-serif;
}

#resultBoard {
    display:block ;
    position:absolute ;
    top:100px; left:0; right:0;
    margin:auto; text-align:center;
    width:290px; padding:15px;
    background-color:#1C252E;
    font-size:30px;
    border:3px solid white;
    border-radius:8px;
    visibility:hidden ;
    font-family: 'Merienda', cursive; 
}
#resultBoard > button {
    display:inline-block ;
    font-size:18px;
    width:40%;
    margin:20px 10px 5px 10px;
}
#reset {
    background-color:tomato;
    background-image:none;
}

@keyframes pop
{
    0%
    { transform:scale(0.6); }
    34%
    { transform:scale(1); }
    66%
    { transform:scale(0.84); }
    100%
    { transform:scale(1); }
    
}
#levelView {
    width:100%; text-align:center;
    margin-top:10px;
}

            </style>
     <!--  Header -->
     <header>
         <h1>Tic Tac Toe</h1>
     
     
     <div id="closeMenu" onclick="closeMenu()"></div>
     <div id="openMenu" onclick="openMenu()" >
         <span></span>
         <span></span>
         <span></span>
     </div></header> 
     <div id="menuHolder">
     <nav id='home'><i class="fas fa-home"></i> HOME</nav>
     <nav id = 'inst' onclick='inst()'><i class="fas fa-book"></i> GUIDE</nav>  
     <nav id="sett"><i class="fas fa-cog"></i> SETTING</nav>
     <nav id='about' onclick='about()'><i class="fas fa-info-circle"></i> ABOUT</nav>
     </div>
     
    <div id="HOME"  class="tab">
        
        <!-- table for tic tac toe -->
<div id="result">
    <div><span>You</span>(<span id="sym1">X</span>) : <span id="res1">0</span></div>
    <div><span id="res2">0</span> : <span id="user">AI</span>(<span id="sym2">O</span>)</div>
</div>
       <table>
            <tr>
                <td>
      <div class="pad" id="0"></div>
                </td>
                 <td>
      <div class="pad" id="1"></div>
                 <td>
      <div class="pad" id="2"></div>                    
                  </td>
            </tr>
            <tr>
                <td>
      <div class="pad" id="3"></div>
                </td>
                 <td>
      <div class="pad" id="4"></div>
                 <td>
      <div class="pad" id="5"></div>                    
                  </td>
            </tr>
            <tr>
                <td>
      <div class="pad" id="6"></div>
                </td>
                 <td>
      <div class="pad" id="7"></div>
                 <td>
      <div class="pad" id="8"></div>                    
                  </td>
            </tr>
        </table>
   <div id="levelView">Level : Medium</div>
   <!-- Result board -->  
   <div id="resultBoard"  >
       <div id="finalResult">None</div> 
       <button id="tryAgain" onclick="playAgain() ">Try Again</button>
         <button id="reset" onclick="startGame() " >RESET</button>
   </div> 
        
    </div>
    <div id="INST"  class="tab">
   <center> <img src="https://dl.dropbox.com/s/92s8cl0ioijfrz0/TicTacToe.jpg?dl=0" alt="gameImage" /></center>
   <p> <span>Step 1 :</span>
        In Tic-Tac-Toe, two players try to line up three symbols in a vertical, horizontal or diagonal row. 
<br><br>
<span>Step 2 : </span> You have the first turn to play i.e you are either (X or O) then the bot will play. <br><br>
    <span>Step 3 : </span> Hit RESET to play again. <br><br>
    <span>Step 4 :</span> In two player mode, after either win,lose or draw the first will vary alternately.
  <br><br>  <span>NOTE : </span> check <i>settings</i> in the menu, to play two player or change your playing symbol .
</p> 

    </div>
    <div id="SETT" class="tab">
        <span>1. Choose your symbol :</span><br>
    <div id="opt" >
        <div id="x" class="block" onclick='setPlayer("X")'>X</div>
        <div id="o" class="block" onclick="setPlayer('O')">O</div>
    </div>
    <br>  
    
     <span>2. Choose player : </span>
     <Select id="player" oninput="setType()">
    <span></span>
    <Option value="AI">AI</Option>
    <Option value="twoPlayer">Two Player</option>

    </select> <br>
    
     <span id="level0">3. Choose Difficulty : </span>
     <Select id="level" oninput="startGame()">
    <Option value="easy">EASY</Option>    

    <Option value="medium" selected>MEDIUM</option>
    <Option value="hard">HARD</option>

    </select>
   <button onclick="settGame()">Play</button>
    
    </div>
    <div id="ABOUT"  class="tab">
          <p>
   <span>Name :</span> Tic Tac Toe <br> 
   <span>Author: </span>Madhav <br />
   <span>Version : </span>2.5.0 <br />
  <span>Created on:</span> 5<sup>th</sup>,March;2019
     <br /><br>
    <span><u>Version Update :</u></span> <br><span>1.3.0</span><br>
    --A simple AI added to play with<br><br>
        
    <span>2.2.1</span><br>
    --A complex Ai i.e MinMax feature added<br><br>
    <span>2.5.0</span><br>
    --setting tab and option for two player game added.<br>
    --some minor bugs fixed and UI changes.<br>
    --Score board tan added to popUp on win,lose or draw .<br>
    --Medium level introduced .<br>
    --Game made public.<br>
    
          </p>
       
    </div>
 <script>
     //some variables 
var cell,originalBoard;
var playerType = "AI";
var level = "easy";
const winCombos = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [6, 4, 2]
]
var player2 = "X";
var player1 = (player2=="X")?"O":"X";
var user,sym1,res1,sym2,res2;
var temp = player2 ;
var resultBoard ;    


//Main function that will start the game
function startGame() {

//initializing level
level = document.getElementById("level").value;
document.getElementById("levelView").innerHTML = "Level : " + level;
res1 = 0;  res2 = 0; sym1 = player2 ;
sym2 = player1 ;
user = (playerType == "AI")?"AI":"Friend";


//Initializing the array
originalBoard = [0,1,2,3,4,5,6,7,8];
        //each box
         cell = document.getElementsByClassName("pad");  
 //event for on click
     for(let i=0;i<cell.length;i++) {
    cell[i].innerText = "";
    cell[i].style.backgroundColor = "#00C4C4";              cell[i].addEventListener("click",turnClick,false);
     
    } updateScore();
resultBoard = document.getElementById("resultBoard");    
resultBoard.style.visibility = "hidden";
resultBoard.style.animation = "";    
}


//to fill the the boxes
function turnClick(box) {

 if(typeof(originalBoard [box.target.id])=="number") { 
    turn(box.target.id,temp);
 
//to give Turn to the AI as per level
  if(playerType == "AI") {
     if(isWinning(originalBoard,player2)===false) {
     if(level=="easy") {
        simpleAi();
    } else if(level=="hard")  {
        complexAi();
    } else if(level=="medium"){
        mediumAi();
    }
  }} else {
     swapPlayer() ;
  }
 }  
}

//function to change color of cells and simple number
function turn(num,val) {
    
    if(num!=undefined) {
    originalBoard[num] = val;
    cell[num].innerText = val;
    cell[num].style.backgroundColor = "#1C252E";   
    }
    
    //to check if player is wininning
    var isWon = isWinning(originalBoard,val);
    if(isWon != false) {
       
       if(val==player1) {
           res2++; updateScore();
       }else {
           res1++; updateScore();
       }
       endGame(val,isWon);
     }  
     
    //in case if draw
    if(emptySquares(originalBoard).length==0&&!isWon) {
        endGame("none",null);
    }
}
    

//A simple AI to play with
function simpleAi() {
    let empty = emptySquares(originalBoard) ;
    let ran = Math.floor(Math.random()*(empty.length-1));

        turn(empty[ran],player1);    
}

//medium Ai
function mediumAi() {
    
    let check,num;
      for(var i=0;i<winCombos.length;i++) {    let check,num;
        check = 0 ;
        for(var j=0;j<3;j++) {
            if(originalBoard [winCombos[i][j]]==player1){
                check++;
            } else {
                num = j;
            } 
        }
        if(check==2&&typeof(originalBoard [winCombos[i][num]])=="number"){
        turn(winCombos[i][num],player1);  
        return null;
        }
    }
    
    for(var i=0;i<winCombos.length;i++) {    let check,num;
        check = 0 ;
        for(var j=0;j<3;j++) {
            if(originalBoard [winCombos[i][j]]==player2){
                check++;
            } else {
                num = j;
            } 
        }
        if(check==2&&typeof(originalBoard [winCombos[i][num]])=="number"){
        turn(winCombos[i][num],player1);  
        return null;
        }
    } simpleAi()  ;
    
}

//compled AI i.e minmax method
function complexAi() {
     turn(minimax(originalBoard, player1).index,player1); 
}

//to check if any box is empty
function emptySquares(board) {
    let emptySquares = [] ;
    for(let i=0;i<board.length;i++) {
       if(typeof(board[i])=="number"){        
          emptySquares.push(i);
        }
    } 
    return emptySquares;
    
}

//check win combos
function isWinning (board,player) {
    var check;
    for(let i=0;i<winCombos.length;i++) {   check = 0 ;
        for(let j=0;j<3;j++) {
            if(board[winCombos[i][j]]==player){
                check++;
            } 
        }
        if(check==3){
            return winCombos[i];
        }
    } return false;
}

//ending the game
function endGame (val,isWon) {

let finalResult = document.getElementById("finalResult");
    
//removing eventlistener from cells
 for(let i=0;i<cell.length;i++) {
        cell[i].removeEventListener("click",turnClick,false);
  }
   if(val == player2 ) {
       finalResult.innerText = "You Won !";
       finalResult.style.color ="lime";
       resultBoard.style.visibility = "visible";
       resultBoard.style.animation = "pop .7s linear";
              
   } else if(val == player1 ) {
       finalResult.innerText = "You Lost !";
       finalResult.style.color ="tomato";
       resultBoard.style.visibility = "visible";
       resultBoard.style.animation = "pop .7s linear";
   } else if(isWon == null ) {
       finalResult.innerText = "Draw !!";
       finalResult.style.color ="cyan";
       resultBoard.style.visibility = "visible";
       resultBoard.style.animation = "pop .7s linear";
   }
//coloring winning combo cell    
    let color = (val==player2)?"lightgreen":"white";

    if(isWon != null)  {
       for(let i=0;i<isWon.length;i++)  
       {
  cell[isWon[i]].style.backgroundColor =color;
       }
    } 
}

function minimax(newBoard, player) {

    var availSpots = emptySquares(originalBoard);

    if (isWinning(newBoard,player2)!=false){
    
        return {score: -10};
    } else if (isWinning(newBoard, player1)!=false) {

        return {score: 10};
    } else if (availSpots.length === 0) {
        return {score: 0};   }
        
    var moves = [];
    for (var i = 0; i < availSpots.length; i++) {

        var move = {};
        move.index = newBoard[availSpots[i]];
        newBoard[availSpots[i]] = player;

        if (player == player1) {

            var result = minimax(newBoard, player2);
            move.score = result.score;

        } else {
            var result = minimax(newBoard, player1);
            move.score = result.score;
        }
        newBoard[availSpots[i]] = move.index;
        moves.push(move);
    }


    var bestMove;
    if(player === player1) {

        var bestScore = -10000;
        for(var i = 0; i < moves.length; i++) {
            if (moves[i].score > bestScore) {
                bestScore = moves[i].score;
                bestMove = i;
            }
        }
    } else {
        var bestScore = 10000;
        for(var i = 0; i < moves.length; i++) {

            if (moves[i].score < bestScore) {
               bestScore = moves[i].score;
                bestMove = i;
            }
        }
    }
    return moves[bestMove];
}

function swapPlayer() {
    if(temp==player1) {
        temp = player2 ;
    } else {
        temp = player1 ;
    }
}

//to update score
function updateScore() {
 document.getElementById("res1").innerText = res1; document.getElementById("res2").innerText = res2; document.getElementById("sym1").innerText = sym1;
document.getElementById("sym2").innerText = sym2; document.getElementById("user").innerText = user;
}

//for playing again
function playAgain() {

resultBoard.style.visibility = "hidden";
resultBoard.style.animation = "";
    //Initializing the array
originalBoard = [0,1,2,3,4,5,6,7,8];
        //each box
         cell = document.getElementsByClassName("pad");  
 //event for on click
     for(let i=0;i<cell.length;i++) {
    cell[i].innerText = "";
    cell[i].style.backgroundColor = "#00C4C4";              cell[i].addEventListener("click",turnClick,false);
     
    } updateScore();
}


/*
Every thing related to setting and stuff below
*/

function setPlayer(a) {
    player2 = a;
    temp = a;
    player1 = (player2=="X")?"O":"X";
    let x = document.getElementById("x");
    let o = document.getElementById("o");
    if(a=="X") {
        x.style.backgroundColor = "#00C4C4";
       x.style.color = "white"; 
        o.style.backgroundColor = "white";
        o.style.color = "#FF0066";
    } else {
        o.style.backgroundColor = "#00C4C4";
        o.style.color = "white"; 
        x.style.backgroundColor = "white";
        x.style.color = "#FF0066";
    } startGame(); updateScore();
}

function setType() {
    
    playerType = document.getElementById("player").value;   
   let a = document.getElementById("level") ;
   let b = document.getElementById("level0") ;
    if(playerType =="AI") {
       a.style.display = "block";
       b.style.display = "block";
    }else {
      a.style.display = "none";
       b.style.display = "none";
    }
    startGame(); updateScore();
}

function settGame() {
        var HOME = document.getElementById("HOME");
    fillColor(home,HOME);
    document.getElementsByTagName("h1")[0]
.innerHTML = 'Tic Tac Toe';

document.body.scrollTop = 0; 
document.documentElement.scrollTop = 0; 
    
startGame();
}
/*
Every thing related to menu and animation stuff below
*/

var span,close,holder,home,inst,about,sett;
var tab;


window.onload = function() {

//for menu bar
 span = document.getElementsByTagName("span");
 close = document.getElementById("closeMenu");
 holder = document.getElementById("menuHolder");
 home = document.getElementById("home");
 inst = document.getElementById("inst");
 about = document.getElementById("about");
 sett = document.getElementById("sett"); 
    home.onclick = function () {
    var HOME = document.getElementById("HOME");
    fillColor(home,HOME);
    document.getElementsByTagName("h1")[0]
.innerHTML = 'Tic Tac Toe';

if( emptySquares(originalBoard).length < 8 ) {
    resultBoard.style.visibility = "visible";
}
closeMenu();
    }
    inst.onclick = function (){ 
    var INST = document.getElementById("INST");
    fillColor(inst,INST);
    document.getElementsByTagName("h1")[0]
.innerHTML = 'Guide <i class="fas fa-book"></i>';

closeMenu();
    }
    about.onclick = function (){ 
        var ABOUT = document.getElementById("ABOUT");
    fillColor(about,ABOUT);
    document.getElementsByTagName("h1")[0]
.innerHTML = 'About <i class="fas fa-info-circle"></i>';

closeMenu();
    }  
    sett.onclick = function (){ 
        var SETT = document.getElementById("SETT");
    fillColor(sett,SETT);
    document.getElementsByTagName("h1")[0]
.innerHTML = 'Setting <i class="fas fa-cog"></i>';

closeMenu();
    }    

//To start the Game onload
startGame() ;
    
}


/* function to control menu bar */
function openMenu() {

//to control animation     span[0].style.transformOrigin="18px";
     span[0].style.transform = "translateY(10px)rotate(-45deg)";
     span[1].style.transformOrigin="18px";
     span[1].style.transform = "rotate(45deg)";
    
     span[2].style.opacity = "0";
     span[2].style.transform = "translateY(10px)";
     
     close.style.zIndex= "1";
     holder.style.left = "0";
     
    }
function closeMenu() {

//to control animation
span[0].style.transformOrigin="18px";
     span[0].style.transform = "translateY(0)rotate(0)";
     span[1].style.transformOrigin="18px";
     span[1].style.transform = "rotate(0)";
    
     span[2].style.opacity = "1";
     span[2].style.transform = "translateY(0)";
     
     close.style.zIndex= "-1";   
     holder.style.left = "-100%";
        
}

function fillColor(a,b) {
    
    home.style.backgroundColor = "transparent";
    inst.style.backgroundColor = "transparent";
    about.style.backgroundColor = "transparent";
    sett.style.backgroundColor = "transparent";
    HOME.style.visibility= "hidden";
INST.style.visibility= "hidden";
ABOUT.style.visibility= "hidden";
SETT.style.visibility= "hidden";

b.style.visibility= "visible";
    a.style.backgroundColor = "#1C252E";
    
    
resultBoard.style.visibility = "hidden";
resultBoard.style.animation = "";     
}

//for swiping actions
window.addEventListener('touchstart', handleTouchStart, false);

window.addEventListener('touchmove', handleTouchMove, false); 

var xDown = null, yDown = null;
 
function getTouches(evt) { 
    return evt.touches  ||  
    evt.originalEvent.touches;
    } 

function handleTouchStart(evt) { 
    const firstTouch = getTouches(evt)[0]; 
    xDown = firstTouch.clientX; 
    yDown = firstTouch.clientY; 
    }
    
function handleTouchMove(evt)   { 
    
    if ( ! xDown || ! yDown ) 
    {  return;  } 
        
    var xUp = evt.touches[0].clientX; 
    var yUp = evt.touches[0].clientY; 
    var xDiff = xDown - xUp; 
    var yDiff = yDown - yUp; 
    
    if ( Math.abs( xDiff ) > Math.abs( yDiff ) )     {
    
    /*Response part*/ 
    
        if ( xDiff>0) {
            /* left swipe */ 
            document.body.scrollTop = 0; 
    document.documentElement.scrollTop = 0; 
           closeMenu();
       } else if ( xDiff<0) { 
           /* right swipe */ 
          document.body.scrollTop = 0; 
    document.documentElement.scrollTop = 0;  
          openMenu();
       } 
    } 
    
 /* reset values */ 
 xDown = null; yDown = null; 
}    

     </script>
    </body>
</html>

4. By GamerB

Made by GamerB. A simple Tic Tac Toe game that uses AI and keeps track of all the wins and loses. ( Source )

<html>
  <head>
   <title>Tic Tac Toe</title>
  </head>
	<body>  
        <style>
            body{
	background-color: #1D1D1D;
  
}

.L1,.L2,.L3
{
  background-color:#1D1D1D;
  border:none;
  height:50px;
  width: 70px;
  font-size: 40;
  text-align: center;
  color: white;
  font-family:Forte,Stencil Std,Calibri;
  position: relative;
  top:20%;
  left:15%;
  
}


.L1:focus,.L2:focus,.L3:focus
{
  outline: none;
}


#d
{
  border-top: 1px solid white;
  border-bottom: 1px solid white;
}

#b
{
  border-bottom: 1px solid white; 
  border-left: 1px solid white; 
  border-right: 1px solid white;
}
#c,#f
{
  border-bottom: 1px solid white;
 
}
#e
{
  border-left: 1px solid white;
  border-right: 1px solid white;
  border-bottom: 1px solid white;
}
#h
{
  border-left: 1px solid white;
  border-right: 1px solid white;
}



#Res

{
	margin: 0 40px;
	height: 35px;
	line-height: 17px;
	width: 150px;
	font-family:'Luckiest Guy', Arial, Helvetica, sans-serif;
	font-size: 12;
	color: #05750A;;
	background-color:#F6FAF1;
	border: 2px solid #9CC784;
	position: fixed;
	top: -10%;
	left: 0%;
	right:0%;
	margin:auto;
	text-align: center;
	box-shadow: 5px 7px 35px 10px black;

	
}
  #Score
{
	
	height: 30px;
	line-height: 30px;
	width: 300px;
	font-family:'Luckiest Guy', Arial, Helvetica, sans-serif;
	font-size: 18;
	color: #05750A;;
	background-color:#F6FAF1;
	border: 2px solid #9CC784;
	position: fixed;
	bottom: 2%;
	left: 0%;
	right: 0%;
	margin: auto;
	text-align: center;
	box-shadow: 5px 7px 35px 10px black;

}


            </style>
		<div id="Res" align="center">Congratulations!<br/>You Won!</div> 
		<div id="Score" align="center">WON- 0 : 0 -LOST</div> 
   
		<input class="L1" id="a" type="Button" value=" " onclick="ClickOnButton('L1',0)"/>
		<input class="L1" id="b" type="Button" value=" " onclick="ClickOnButton('L1',1)"/>
		<input class="L1" id="c" type="Button" value=" " onclick="ClickOnButton('L1',2)"/>
		<br/>
		
		<input class="L2" id="d" type="Button" value=" " onclick="ClickOnButton('L2',0)" />
		<input class="L2" id="e" type="Button" value=" " onclick="ClickOnButton('L2',1)"/>
		<input class="L2" id="f" type="Button" value=" " onclick="ClickOnButton('L2',2)"/>
		<br/>
		
		<input class="L3" id="g" type="Button" value=" " onclick="ClickOnButton('L3',0)" />
		<input class="L3" id="h" type="Button" value=" " onclick="ClickOnButton('L3',1)"/>
		<input class="L3" id="i" type="Button" value=" " onclick="ClickOnButton('L3',2)"/>
	<script>
        var Won=0,Lost=0;
var GameOver=false;
var U=document.getElementsByClassName("L1");
var M=document.getElementsByClassName("L2");
var L=document.getElementsByClassName("L3");

var ReachedPos=-10;
var Reached=false;
var ReachedEver=false;
var n=0;
function ClickOnButton(ClassName,Index)
{
   var Button=document.getElementsByClassName(ClassName);
   if(Button[Index].value==" " &&!GameOver)
	{
		Button[Index].value="O";
		Result();
		if(GameOver==false)
			{
				ComputerPlays();
			}	  
	}
   
}
function ComputerPlays()
{


	if(U[0].value=="X" && U[1].value=="X" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[0].value=="X" && U[2].value=="X" && U[1].value==" ")
		{
			U[1].value="X";
		}
	else if(U[1].value=="X" && U[2].value=="X" && U[0].value==" ")
		{
			U[0].value="X";
		}
	//Second Line
	else if(M[0].value=="X" && M[1].value=="X" && M[2].value==" ")
		{
			M[2].value="X";
		}
	else if(M[0].value=="X" && M[2].value=="X" && M[1].value==" ")
		{
			M[1].value="X";
		}
	else if(M[1].value=="X" && M[2].value=="X" && M[0].value==" ")
		{
			M[0].value="X";
		}
	//third line
	else if(L[0].value=="X" && L[1].value=="X" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[0].value=="X" && L[2].value=="X" && L[1].value==" ")
		{
			L[1].value="X";
		}
	else if(L[1].value=="X" && L[2].value=="X" && L[0].value==" ")
		{
			L[0].value="X";
		}


	//vertically First Line
	else if(U[0].value=="X" && M[0].value=="X" && L[0].value==" ")
		{
			L[0].value="X";
		}
	else if(L[0].value=="X" && M[0].value=="X" && U[0].value==" ")
		{
			U[0].value="X";
		}
	else if(U[0].value=="X" && L[0].value=="X" && M[0].value==" ")
		{
			M[0].value="X";
		} 
	//vertically Second Line
	else if(U[1].value=="X" && M[1].value=="X" && L[1].value==" ")
		{
			L[1].value="X";
		}
	else if(L[1].value=="X" && M[1].value=="X" && U[1].value==" ")
		{
			U[1].value="X";
		}
	else if(U[1].value=="X" && L[1].value=="X" && M[1].value==" ")
		{
			M[1].value="X";
		}
	//vertically Third Line
	else if(U[2].value=="X" && M[2].value=="X" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[2].value=="X" && M[2].value=="X" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[2].value=="X" && L[2].value=="X" && M[2].value==" ")
		{
			M[2].value="X";
		}
	
		



	else if(U[0].value=="X" && M[1].value=="X" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[2].value=="X" && M[1].value=="X" && U[0].value==" ")
		{
			U[0].value="X";
		}
	else if(U[0].value=="X" && L[2].value=="X" && M[1].value==" ")
		{
			M[1].value="X";
		}



	else if(U[2].value=="X" && M[1].value=="X" && L[0].value==" ")
		{
			L[0].value="X";
		}
	else if(L[0].value=="X" && M[1].value=="X" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[2].value=="X" && L[0].value=="X" && M[1].value==" ")
		{
			M[1].value="X";
		}
   
	//Codes to Defend
	else if(U[0].value=="O" && U[1].value==" "&&U[2].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[0].value==" "&&L[1].value==" "&&L[2].value==" ")
		{
			M[1].value="X";
		}
	else if(U[2].value=="O" && U[1].value==" "&&U[0].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[0].value==" "&&L[1].value==" "&&L[2].value==" ")
		{
			M[1].value="X";
		}
	else if(L[0].value=="O" && U[0].value==" "&& U[1].value==" "&&U[2].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[1].value==" "&&L[2].value==" ")
		{
			M[1].value="X";
		}
	else if(L[2].value=="O" && U[0].value==" "&&U[1].value==" " && U[2].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[0].value==" "&&L[1].value==" ")
		{
			M[1].value="X";
		}
	else if(M[1].value=="O" &&  U[0].value==" "&&U[1].value==" " && U[2].value==" "&&M[0].value==" "&&M[2].value==" "&&L[0].value==" "&&L[1].value==" " &&L[2].value==" " )
		{
			var Number= RandomWithRange(0,3);
			if(Number==0)
				{
					U[0].value="X";
				}
			else if(Number==1)
				{
					U[2].value="X";
				}
			else if(Number==2)
				{
					L[0].value="X";
				}
			else if(Number==3)
				{
					L[2].value="X";
				}
		}
	else if(U[1].value=="O" && U[0].value==" " && U[2].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[0].value==" "&&L[1].value==" "&&L[2].value==" " )
		{
			M[1].value="X";
		}
	else if(L[1].value=="O" && U[0].value==" " && U[1].value==" " && U[2].value==" "&&M[0].value==" "&&M[1].value==" "&&M[2].value==" "&&L[0].value==" " &&L[2].value==" " )
		{
			M[1].value="X";
		}
	//First Line
	else if(U[0].value=="O" && U[1].value=="O" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[0].value=="O" && U[2].value=="O" && U[1].value==" ")
		{
			U[1].value="X";
		}
	else if(U[1].value=="O" && U[2].value=="O" && U[0].value==" ")
		{
			U[0].value="X";
		}
	//Second Line
	else if(M[0].value=="O" && M[1].value=="O" && M[2].value==" ")
		{
			M[2].value="X";
		}
	else if(M[0].value=="O" && M[2].value=="O" && M[1].value==" ")
		{
			M[1].value="X";
		}
	else if(M[1].value=="O" && M[2].value=="O" && M[0].value==" ")
		{
			M[0].value="X";
		}
	//third line
	else if(L[0].value=="O" && L[1].value=="O" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[0].value=="O" && L[2].value=="O" && L[1].value==" ")
		{
			L[1].value="X";
		}
	else if(L[1].value=="O" && L[2].value=="O" && L[0].value==" ")
		{
			L[0].value="X";
		}


	//vertically First Line
	else if(U[0].value=="O" && M[0].value=="O" && L[0].value==" ")
		{
			L[0].value="X";
		}
	else if(L[0].value=="O" && M[0].value=="O" && U[0].value==" ")
		{
			U[0].value="X";
		}
	else if(U[0].value=="O" && L[0].value=="O" && M[0].value==" ")
		{
			M[0].value="X";
		} 
	//vertically Second Line
	else if(U[1].value=="O" && M[1].value=="O" && L[1].value==" ")
		{
			L[1].value="X";
		}
	else if(L[1].value=="O" && M[1].value=="O" && U[1].value==" ")
		{
			U[1].value="X";
		}
	else if(U[1].value=="O" && L[1].value=="O" && M[1].value==" ")
		{
			M[1].value="X";
		}
	//vertically Third Line
	else if(U[2].value=="O" && M[2].value=="O" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[2].value=="O" && M[2].value=="O" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[2].value=="O" && L[2].value=="O" && M[2].value==" ")
		{
			M[2].value="X";
		}
	
		



	else if(U[0].value=="O" && M[1].value=="O" && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[2].value=="O" && M[1].value=="O" && U[0].value==" ")
		{
			U[0].value="X";
		}
	else if(U[0].value=="O" && L[2].value=="O" && M[1].value==" ")
		{
			M[1].value="X";
		}



	else if(U[2].value=="O" && M[1].value=="O" && L[0].value==" ")
		{
			L[0].value="X";
		}
	else if(L[0].value=="O" && M[1].value=="O" && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[2].value=="O" && L[0].value=="O" && M[1].value==" ")
		{
			M[1].value="X";
		}



	else if(M[2].value==" " && M[1].value=="X" && M[0].value==" ")
		{
			M[2].value="X";
		}
	else if(M[0].value=="X" && M[1].value==" " && M[2].value==" ")
		{
			M[2].value="X";
		}
	else if(M[2].value=="X" && M[1].value==" " && M[0].value==" ")
		{
			M[0].value="X";
		}
	
		



	else if(U[2].value==" " && U[1].value=="X" && U[0].value==" ")
		{
			U[2].value="X";
		}
	else if(U[0].value=="X" && U[1].value==" " && U[2].value==" ")
		{
			U[2].value="X";
		}
	else if(U[2].value=="X" && U[1].value==" " && U[0].value==" ")
		{
			U[0].value="X";
		}
	
	else if(L[2].value==" " && L[1].value=="X" && L[0].value==" ")
		{
			L[2].value="X";
		}
	else if(L[0].value=="X" && L[1].value==" " && L[2].value==" ")
		{
			L[2].value="X";
		}
	else if(L[2].value=="X" && L[1].value==" " && L[0].value==" ")
		{
			L[0].value="X";
		}




	else if(M[0].value=="O"  && U[0].value==" " && U[1].value==" " && U[2].value==" " && M[2].value==" " && M[1].value==" " && L[0].value==" " && L[1].value==" " && L[2].value==" ")
		{
			U[0].value="X";

		}
	else if(M[2].value=="O"  && U[0].value==" " && U[1].value==" " && U[2].value==" " && M[0].value==" " && M[1].value==" " && L[0].value==" " && L[1].value==" " && L[2].value==" ")
		{
			U[2].value="X";
		}

	 
	
	else
		{
			var Num=RandomWithRange(0,8)
			if(Num==0 &&U[0].value==" ")
				{
					U[0].value="X";
				}
			else if(Num==1 &&U[1].value==" ")
				{
					U[1].value="X";
				}
			else if(Num==2  && U[2].value==" ")
				{
					U[2].value="X";
				}
			else if(Num==3  && M[0].value==" ")
				{
					M[0].value="X";
				}
			else if(Num==4  && M[1].value==" ") 
				{
					M[1].value="X";
				}
			else if(Num==5  && M[2].value==" ")
				{
					M[2].value="X";
				}
			else if(Num==6   && L[0].value==" ")
				{
					L[0].value="X";
				}
			else if(Num==7   && L[1].value==" ")
				{
					L[1].value="X";
				}
			else if(Num==8   && L[2].value==" ")
				{
					L[2].value="X";
				}
			else 
				{
					if(U[0].value==" ")
						{
							U[0].value="X";
						}
					else if(U[1].value==" ")
						{
							U[1].value="X";
						}
					else if(U[2].value==" ")
						{
							U[2].value="X";
						}
					else if(M[0].value==" ")
						{
							M[0].value="X";
						}
					else if(M[1].value==" ")
						{
							M[1].value="X";
						}
					else if(M[2].value==" ")
						{
							M[2].value="X";
						}
					else if(L[0].value==" ")
						{
							L[0].value="X";
						}
					else if(L[1].value==" ")
						{
							L[1].value="X";
						}
					else if(L[2].value==" ")
						{
							L[2].value="X";
						}
				}
		}
	Result();
}



function RandomWithRange(Min,Max)
{
	return parseInt(Math.random()*(Max-Min)+Min)
}
function Result()
{

	if(U[0].value=="X" && U[1].value=="X" && U[2].value=="X")
		{
			U[0].style.color="#24B73D";
			U[1].style.color="#24B73D";
			U[2].style.color="#24B73D";
			Lose();
		}
	else if(U[0].value=="O" && U[1].value=="O" && U[2].value=="O")
		{
			U[0].style.color="#24B73D";
			U[1].style.color="#24B73D";
			U[2].style.color="#24B73D";
			Win();
		}
	else if(M[0].value=="X" && M[1].value=="X" && M[2].value=="X")
		{
			M[0].style.color="#24B73D";
			M[1].style.color="#24B73D";
			M[2].style.color="#24B73D";
			Lose();
		}
	else if(M[0].value=="O" && M[1].value=="O" && M[2].value=="O")
		{
			M[0].style.color="#24B73D";
			M[1].style.color="#24B73D";
			M[2].style.color="#24B73D";
			Win();
		}
	else if(L[0].value=="X" && L[1].value=="X" && L[2].value=="X")
		{
			L[0].style.color="#24B73D";
			L[1].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Lose();
		}
	else if(L[0].value=="O" && L[1].value=="O" && L[2].value=="O")
		{
			L[0].style.color="#24B73D";
			L[1].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Win();
		}




	else if(U[0].value=="X" && M[0].value=="X" && L[0].value=="X")
		{
			U[0].style.color="#24B73D";
			M[0].style.color="#24B73D";
			L[0].style.color="#24B73D";
			Lose();
		}
	else if(U[0].value=="O" && M[0].value=="O" && L[0].value=="O")
		{
			U[0].style.color="#24B73D";
			M[0].style.color="#24B73D";
			L[0].style.color="#24B73D";
			Win();
		}
	else if(U[1].value=="X" && M[1].value=="X" && L[1].value=="X")
		{
			U[1].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[1].style.color="#24B73D";
			Lose();
		}
	else if(U[1].value=="O" && M[1].value=="O" && L[1].value=="O")
		{
			U[1].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[1].style.color="#24B73D";
			Win();
		}
	else if(U[2].value=="X" && M[2].value=="X" && L[2].value=="X")
		{
			U[2].style.color="#24B73D";
			M[2].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Lose();
		}
	else if(U[2].value=="O" && M[2].value=="O" && L[2].value=="O")
		{
			U[2].style.color="#24B73D";
			M[2].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Win();
		}
	else if(U[0].value=="X" && M[1].value=="X" && L[2].value=="X")
		{
			U[0].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Lose();
		}
	else if(U[0].value=="O" && M[1].value=="O" && L[2].value=="O")
		{
			U[0].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[2].style.color="#24B73D";
			Win();
		}
	else if(U[2].value=="X" && M[1].value=="X" && L[0].value=="X")
		{
			U[2].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[0].style.color="#24B73D";
			Lose();
		}
	else if(U[2].value=="O" && M[1].value=="O" && L[0].value=="O")
		{
			U[2].style.color="#24B73D";
			M[1].style.color="#24B73D";
			L[0].style.color="#24B73D";
			Win();
		}
	else if(!GameOver && U[0].value!=" " && U[1].value!=" " && U[2].value!=" "&&  M[0].value!=" " && M[1].value!=" " && M[2].value!=" " &&  L[0].value!=" " && L[1].value!=" " && L[2].value!=" " )
		{
			GameOver=true;
			document.getElementById("Res").style="color:#05750A;background-color:#F6FAF1;"
			document.getElementById("Res").innerHTML="Well tried!<br/>It's a draw!";
			Reached=true;
		}
}


function Win()
{
  GameOver=true;
  document.getElementById("Res").innerHTML="Congratulations!<br/>You Won!";
  document.getElementById("Res").style="color:#05750A;background-color:#F6FAF1;"
  Won++;
  Reached=true;
  UpdateScore();

}
function Lose()
{
   GameOver=true;
   document.getElementById("Res").innerHTML="Ooops, Bad Luck!<br/>You Lost!";
   document.getElementById("Res").style="background-color:#BF5B5B;color:black;"
   Lost++;
   Reached=true;
   UpdateScore();

}
function Reset()
{
	 U[0].value=" ";
	 U[1].value=" ";
	 U[2].value=" ";
	 M[0].value=" ";
	 M[1].value=" ";
	 M[2].value=" ";
	 L[0].value=" ";
	 L[1].value=" ";
	 L[2].value=" ";


	 for(var i=0;i<=2;i++)
		{
			U[i].style.color="white";
			M[i].style.color="white";
			L[i].style.color="white";

		}
	 GameOver=false;
}


function AnimateReached()
{
	if(Reached)
		{
			var i=  document.getElementById("Res");
			
			if(ReachedPos<2 &&!ReachedEver )
				{
					 ReachedPos++;				   
				}
			else if(!ReachedEver)
				{
					 n++; 
					 if(n>=80)
						{
							ReachedEver=true;
						}								   
				}
			if(ReachedEver)
				{
					ReachedPos--;
					if(ReachedPos==-10)
						{
							Reached=false;
							ReachedEver=false;
							n=0;
							Reset();
							
						}
				}
					  i.style.top=ReachedPos+'%';
			
		   
		}
	   
	
}
function UpdateScore()
{
	document.getElementById("Score").innerHTML="WON- "+Won+" : " +Lost+" -LOST";
}

setInterval(AnimateReached,20);
        </script>
	</body>
</html>

5. By Mitali

Made by Mitali. A two player tic tac toe game with restart button. ( Source )

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Tic Tac Toe</title>
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:[email protected]&family=Raleway:[email protected]&display=swap"
      rel="stylesheet"
    />
  </head>
  <body>
      <style>
              
 * {
        -webkit-box-sizing: border-box;
                box-sizing: border-box;
        padding: 0;
        margin: 0;
        font-family: "Raleway", sans-serif;
      }
      body {
        height: 100vh;
        background: -o-linear-gradient(315deg, #8052ec, #d161ff);
        background: linear-gradient(135deg, #8052ec, #d161ff);
      }
      html {
        font-size: 16px;
      }
      .box {
        padding: 1.5em 0;
        position: absolute;
        -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
                transform: translate(-50%, -50%);
        left: 50%;
        top: 50%;
      }
      .wrapper {
        position: relative;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
            -ms-flex-direction: column;
                flex-direction: column;
      }
      .container {
        width: 80vmin;
        height: 80vmin;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -ms-flex-wrap: wrap;
            flex-wrap: wrap;
        gap: 2vmin;
      }
      .button-option {
        background-color: #ffffff;
        height: 25vmin;
        width: 25vmin;
        font-size: 12vmin;
        border: none;
        -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
                box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
        border-radius: 8px;
        color: #d161ff;
      }
      #restart {
        margin-top: 1em;
        padding: 0.7em 0;
        background-color: #0a0027;
        color: #ffffff;
        font-size: 1.3em;
        border-radius: 5px;
        border: none;
      }
      .popup.hide {
        display: none;
      }
      .popup {
        height: 100vh;
        width: 100vw;
        position: absolute;

        background: -o-linear-gradient(315deg, #8052ec, #d161ff);

        background: linear-gradient(135deg, #8052ec, #d161ff);
        z-index: 2;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-align: center;
            -ms-flex-align: center;
                align-items: center;
        -webkit-box-pack: center;
            -ms-flex-pack: center;
                justify-content: center;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
            -ms-flex-direction: column;
                flex-direction: column;
        gap: 1em;
        font-size: 12vmin;
      }
      #new-game {
        padding: 0.5em 1em;
        background-color: #0a0027;
        color: #ffffff;
        font-size: 0.6em;
        border-radius: 0.2em;
        border: none;
      }
      #message {
        color: #ffffff;
        text-align: center;
        font-size: 1em;
      }
      a {
        font-size: 1.3em;
        background-color: #ffffff;
        display: block;
        text-align: center;
        text-decoration: none;
        padding: 0.6em 0;
        border-radius: 5px;
        color: #d161ff;
        letter-spacing: 0.05em;
        margin-top: 1em;
      }
          </style>
    <div class="box">
      <div class="wrapper">
        <div class="container">
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
          <button class="button-option"></button>
        </div>
        <button id="restart">Restart</button>
      </div>

      <a href="https://youtu.be/al_AgC2NSCo" target="_blank"
        >My Youtube Channel</a
      >
    </div>
    <div class="popup hide">
      <p id="message"></p>
      <button id="new-game">New Game</button>
    </div>

    <script>
  let btnRef = document.querySelectorAll(".button-option");
let popupRef = document.querySelector(".popup");
let newgameBtn = document.getElementById("new-game");
let restartBtn = document.getElementById("restart");
let msgRef = document.getElementById("message");
//Winning Pattern Array
let winningPattern = [
  [0, 1, 2],
  [0, 3, 6],
  [2, 5, 8],
  [6, 7, 8],
  [3, 4, 5],
  [1, 4, 7],
  [0, 4, 8],
  [2, 4, 6],
];
//Player 'X' plays first
let xTurn = true;
let count = 0;

//Disable All Buttons
const disableButtons = () => {
  btnRef.forEach((element) => (element.disabled = true));
  //enable popup
  popupRef.classList.remove("hide");
};

//Enable all buttons (For New Game and Restart)
const enableButtons = () => {
  btnRef.forEach((element) => {
    element.innerText = "";
    element.disabled = false;
  });
  //disable popup
  popupRef.classList.add("hide");
};

//This function is executed when a player wins
const winFunction = (letter) => {
  disableButtons();
  if (letter == "X") {
    msgRef.innerHTML = "&#x1F389; <br> 'X' Wins";
  } else {
    msgRef.innerHTML = "&#x1F389; <br> 'O' Wins";
  }
};

//Function for draw
const drawFunction = () => {
  disableButtons();
  msgRef.innerHTML = "&#x1F60E; <br> It's a Draw";
};

//New Game
newgameBtn.addEventListener("click", () => {
  count = 0;
  enableButtons();
});
restartBtn.addEventListener("click", () => {
  count = 0;
  enableButtons();
});

//Win Logic
const winChecker = () => {
  //Loop through all win patterns
  for (let i of winningPattern) {
    let [element1, element2, element3] = [
      btnRef[i[0]].innerText,
      btnRef[i[1]].innerText,
      btnRef[i[2]].innerText,
    ];
    //Check if elements are filled
    //If 3 empty elements are same and would give win as would
    if (element1 != "" && (element2 != "") & (element3 != "")) {
      if (element1 == element2 && element2 == element3) {
        //If all 3 buttons have same values then pass the value to winFunction
        winFunction(element1);
      }
    }
  }
};

//Display X/O on click
btnRef.forEach((element) => {
  element.addEventListener("click", () => {
    if (xTurn) {
      xTurn = false;
      //Display X
      element.innerText = "X";
      element.disabled = true;
    } else {
      xTurn = true;
      //Display Y
      element.innerText = "O";
      element.disabled = true;
    }
    //Increment count on each click
    count += 1;
    if (count == 9) {
      drawFunction();
    }
    //Check for win on every click
    winChecker();
  });
});
//Enable Buttons and disable popup on page load
window.onload = enableButtons;
    </script>
  </body>
</html>

6. By πŸ‘‘ Prometheus πŸ‡ΈπŸ‡¬

Made by πŸ‘‘ Prometheus πŸ‡ΈπŸ‡¬. ( Source )

<!DOCTYPE html>
<html>
    <head>
        <title>Tic Tac Toe</title>
    </head>
    <body style="background:linear-gradient(100deg,black,grey,white)">
        <style>
            #board{
    position:absolute;
    height:256px;
    width:250px;
    top:20px;
    left:40px;
    border:2px solid;
    background-color:#e3e3e3;
}
.cell{
    position:absolute;
    height:70px;
    width:70px;
    background-color:white;
    border:4px solid;
}
.row{
    position:relative;
    height:70px;
    width:70px;
    margin-top:10px;
}
.c1{
    left:6px;
}
.c2{
    left:86px;
}
.c3{
    left:166px;
}
#c3{
    background-color:blue;
}
button{
    background:linear-gradient(135deg, red,orange,yellow);
    color:grey;
}
            </style>
        <div id="board">
            <div class="row">
                <div onclick="tap(this)" class="cell c1" id="c1"></div>
                <div onclick="tap(this)" class="cell c2" id="c2"></div>
                <div onclick="tap(this)" class="cell c3" id="c3"></div>
            </div>
            <div class="row">
                <div onclick="tap(this)" class="cell c1" id="c4"></div>
                <div onclick="tap(this)" class="cell c2" id="c5"></div>
                <div onclick="tap(this)" class="cell c3" id="c6"></div>
            </div>
            <div class="row">
                <div onclick="tap(this)" class="cell c1" id="c7"></div>
                <div onclick="tap(this)" class="cell c2" id="c8"></div>
                <div onclick="tap(this)" class="cell c3" id="c9"></div>
            </div>
        </div>
    <button style="position:absolute;top:300px;left:128px;font-size:20px" onclick="startagain()">Restart</button>
    <button style="position:absolute;top:330px;left:128px;font-size:21px;" onclick="inform()">Details</button>
    <script>
        var aiselected=[3];
var plselected=new Array();
var wins=[[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]];
function startagain(){
    for (let m of document.getElementsByClassName("cell")){
        if (m.id!='c3'){
            m.style.backgroundColor='white';
        }
    }
    aiselected=[3]
    plselected=[];
}
function inform(){
    alert("This is my first ever attempt at making a web game. I made this tic-tac-toe game with a lot of fixed variables, mainly the AI always starts and is always choosing the top right corner square.")
}
function add(no){
    aiselected.push(no);
    return no;
}
function won(arr){
    for (let x of wins){
        if (x.every(p=>arr.includes(p))){
            return true;
        }
    }
    return false;
}
function tap(a){
    if ((aiselected+plselected).includes(+a.id[1])){
        return;
    }
    a.style.backgroundColor='red';
    plselected+=+(a.id[1]);
    let res=ai();
    document.getElementById('c'+res).style.backgroundColor='blue';
    if (won(aiselected)){
        alert("The AI won!");
    }
    else if (won(plselected)){
        alert("It can't be... You won my AI!");
    }
    else if((aiselected.length+ plselected.length)==9){
        alert("Good game! It was a draw!");
    }
}
function ai(){
    used=aiselected+plselected;
    if (aiselected.toString()=="3"){
        move1=plselected[0]
        if (move1==6 || move1==9){
            return add(1);
        }
        return add(9);
    }
    if (aiselected.toString()=="3,1"){
        if (!plselected.includes(2)){
            return add(2);
        }
        else if (!plselected.includes(7)){
            return add(7);
        }
    }
    else if (aiselected.toString()== "3,1,7"){
        if (!plselected.includes(4)){
            return add(4);
        }
        if (!plselected.includes(5)){
            return add(5);
        }
    }
    if (aiselected.toString()=="3,9"){
        if (!plselected.includes(6)){
            return add(6);
        }
        if (plselected.includes(1)){
            return add(7);
        }
        if (plselected.includes(7)){
            return add(1);
        }
        if (plselected.toString()=="46"){
            return add(5);
        }
        if (plselected.toString()=="56"){
            return add(4);
        }
        if (plselected.includes(2)||plselected.includes(8)){
            return add(5);
        }
    }
    if (aiselected.toString()=="3,9,5"){
        if (!plselected.includes(1)){
            return add(1);
        }
        return add(7);
    }
    if (aiselected.toString()=="3,9,4"){
        if (plselected.includes(2)){
            return add(8);
        }
        return add(2);
    }
    if (aiselected.toString()=="3,9,4,2"){
        if (plselected.includes(1)){
            return add(7);
        }
        return add(1);
    }
    if (aiselected.toString()=="3,9,4,8"){
        if (plselected.includes(7)){
            return add(1);
        }
        return add(7);
    }
    if (aiselected.toString()=="3,9,7"){
        if (plselected.includes(8)){
            return add(5);
        }
        return add(8);
    }
    if (aiselected.toString()=="3,9,1"){
        if (plselected.includes(2)){
            return add(5);
        }
        return add(2);
    }
}
function type(a){
    //-1 if edge
    //0 if centre
    //1 if corner
    if (+(a)==5)return 0;
    if (+(a)%2==1)return 1;
    return -1
}
        </script>
    </body>
</html>

7. By Anuran Pal

Made by Anuran Pal. The game lets you choose whether you want to use the first move or let the AI do it, and also lets you choose the symbol you want. It also uses a little bit of animation. ( Source )

<!DOCTYPE html>
<html>
    <head>
        <title>Tic Tac Toe in htmlcanvas</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" type="text/javascript"></script>
    </head>
    <body>
        <style>
            @import url('https://fonts.googleapis.com/css2?family=Balsamiq+Sans:[email protected]&family=Potta+One&display=swap');

html{
  font-family: 'Balsamiq Sans', cursive;
  font-weight: 800;  
}

h1, h2{  
  text-transform: uppercase;
  background: -webkit-linear-gradient(#e60000, #ff0000,#ff6600);;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;  
}
h1{
  line-height: 40px;
  font-size:40px;
}
h2 {
  line-height: 25px;
  font-size:25px;
}

.width-medium{
  max-width:250px;
}
.align-center {    
  text-align: center;
}
.flex-center{
  display:flex;
  justify-content:center;
  align-items: center;
}

.flex-space-around{
  justify-content:space-around!important;
}

.flex-column{
  flex-direction:column;
}

.margin {
  margin: 20px;
}
.margin-small{
  margin:12px;
}
.margin-left-small{
  margin-left:2px;
}
.no-margin-bottom{
  margin-bottom:0px!important
}
.no-margin-horizontal{
  margin-left:0px!important;
  margin-right:0px!important;
}
.margin-auto {
  margin: auto;
}
button {
  display:flex;
  align-items:center;
  justify-content:center;
  font-family: inherit; 
  box-shadow:1px 2px #919191;
  background-image: linear-gradient(to right, #a6a6a6, #c7c3c3, #e0dcdc, #ebe8e8);
  font-weight: 800;  
  border: 0px;
  height: 40px;
  width:115px;
  padding: 5px;
  border-radius: 20px;
  letter-spacing: 1.5px;
  font-size: 18px;
  text-align: center;
  cursor: pointer;
  outline: none;
  text-transform: uppercase; 
}
button:hover{
  background-image: linear-gradient(to right, #a6a6a6, #c7c3c3, #e0dcdc, #cccccc);
}
button:hover > svg circle{
  stroke: blue;
}
button:hover > svg path{
  fill: red;
}
button svg{
  margin-right:5px;
}
.symbol{
  cursor: pointer;
}
.symbol:hover{
  background-color:#F0F0F0;
  border-radius:6px;
}
.symbol.active{
  background-color:#cccccc;
  border-radius:6px;
}

.checkbox{
  -webkit-appearance: none;
  -moz-appearance: none;
  display: inline-block;
  height:16px;
  width:16px;
  margin-bottom:-1px;
  background: white;
  border: 2px solid red;
  border-radius: 4px;
  cursor: pointer;
  outline: 0;
}
.checkbox:checked{
 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='15' width='15'%3E%3Cpath d='M2 5 L5 10 L10 3' stroke='blue' stroke-width='2' stroke-linecap='round' fill='none' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
}
            </style>
        <div id="divUserInputs" class="align-center">
        <div class="align-center width-medium margin-auto">
            <h1>Choose</h1>
            <div class="flex-center flex-space-around">
                <svg id="1" height="70" width="70" class="symbol active">
                    <circle cx="35" cy="35" r="24" stroke="blue" stroke-width="10" fill="none" />
                </svg>
                <h2> OR </h2>
                <svg id="2" height="70" width="70" class="symbol">
                    <line x1="13" y1="13" x2="57" y2="57" stroke="blue" stroke-width="10" stroke-linecap="round" />
                    <line x1="57" y1="13" x2="13" y2="57" stroke="blue" stroke-width="10" stroke-linecap="round" />
                </svg>
            </div>
            <div class="flex-center flex-column">
                <div class="margin no-margin-horizontal no-margin-bottom">
                    <input id="checkFirstMove" type="checkbox" class="checkbox" checked /><span class="margin-left-small">Check to make the first move</span>
                </div>
                <button id="btnPlay" class="margin-small">
                    <svg height="24" width="24">
                        <circle cx="12" cy="12" r="10" stroke-width="3" fill="none" stroke="red" />
                        <path d="M8 6 L19 12 L8 18 Z" fill="blue" />
                    </svg>
                    Play
                </button>
            </div>
        </div>
    </div>
    <div id="tic-tac-toe-board" class="align-center">
    </div>
    <div id="win" class="align-center" style="position:relative;display:none;">
        <canvas id="burst" height="300" width="300"></canvas>
        <div style="background-color:rgba(255,255,255,0.7);position:absolute;top:50%;left:50%;transform: translate(-50%,-50%);padding:5px;">
            <h1>You won..</h1>
        </div>
    </div>
    <div id="loss" class="align-center" style="position:relative;display:none;">
        <div style="background-color:rgba(255,255,255,0.7);">
            <h1>Better luck next time..</h1>
        </div>
    </div>
    <div id="draw" class="align-center" style="position:relative;display:none;">
        <div style="background-color:rgba(255,255,255,0.7);">
            <h1>Well tried! It's a draw..</h1>
        </div>
    </div>
    <script>
        const SYMBOL = {
    CIRCLE: 1,
    CROSS: 2
};

var Symbol = (function () {
    var _default = {
        size: 24,
        color: "blue",
        strokeWidth: 4
    };

    var _symbol = function (type, options) {
        if (!type) throw new Error("type of Symbol must be defined.");
        this.type = type;
        this.options = $.extend({}, _default, options);        
    };

    _symbol.prototype.getSize = function () {
        return this.options.size;
    };

    _symbol.prototype.create = function () {
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        var size = this.options.size,
            color = this.options.color,
            lineWidth = this.options.strokeWidth;
        // Set actual size in memory (scaled to account for extra pixel density).
        var scale = window.devicePixelRatio; // <--- Change to 1 on retina screens to see blurry canvas.
        canvas.width = size * scale;
        canvas.height = size * scale;
        canvas.height = canvas.width = size;
        ctx.strokeStyle = color;
        ctx.lineWidth = lineWidth;
        switch (this.type) {
            case SYMBOL.CIRCLE:
                var offset = 4;
                    center = [size / 2, size / 2],
                    radius = size / 2 - lineWidth / 2 - offset;
                console.log(center + "," + radius);
                ctx.beginPath();
                ctx.arc(center[0], center[1], radius, 0, 2 * Math.PI);
                ctx.stroke();
                ctx.closePath();
                break;
            case SYMBOL.CROSS:
                var offset = 12;
                ctx.lineCap = "round";
                ctx.beginPath();
                ctx.moveTo(offset, offset);
                ctx.lineTo(size - offset, size - offset);
                ctx.stroke();
                ctx.closePath();
                ctx.beginPath();
                ctx.moveTo(size - offset, offset);
                ctx.lineTo(offset, size - offset);
                ctx.stroke();
                ctx.closePath();
                break;
        }
        return canvas;
    };

    return _symbol;
})();

var Evented = {
    on: function (eventName, callback, domElement) {
        $(domElement || this).on(eventName, callback);
    },

    off: function (eventName, callback, domElement) {
        $(domElement || this).off(eventName, callback);
    },

    trigger: function (eventName, params, domElement) {
        $(domElement || this).trigger(eventName, params);
    }
}

var Cell = (function () {
    var id = 0;
    var _cell = function (options, playBoard) {

        if (!(playBoard instanceof PlayBoard)) {
            throw new Error("PlayBoard must be initialized.");
        }

        var startPos = this.startPos = options.startPos; // top-left corner
        var size = this.size = options.size;
        var strokeWidth = this.strokeWidth = options.strokeWidth;
        var endPos = [startPos[0] + size[0], startPos[1] + size[1]]; // bottom-right corner
        this.id = ++id;
        this.playBoard = playBoard;
        this.isEmpty = true;
        var playBoardSize = playBoard.getSize();
        this._bounds = {
            topLeft: startPos,
            bottomRight: endPos
        };
        var drawBounds = this._drawBounds = {
            topLeft: [(startPos[0] !== 0 ? (startPos[0] + strokeWidth / 2) : startPos[0]), (startPos[1] !== 0 ? (startPos[1] + strokeWidth / 2) : startPos[1])],
            bottomRight: [(Math.floor(playBoardSize[0] - endPos[0]) !== 0 ? (endPos[0] - strokeWidth / 2) : endPos[0]), (Math.floor(playBoardSize[1] - endPos[1]) !== 0 ? (endPos[1] - strokeWidth / 2) : endPos[1])]
        };
        this.center = [(drawBounds.topLeft[0] + drawBounds.bottomRight[0]) / 2, (drawBounds.topLeft[1] + drawBounds.bottomRight[1]) / 2];
    };

    $.extend(_cell.prototype, Evented);

    var _onMouseOver = function () {
        var canvas = this.playBoard.getContainer();
        var ctx = this.playBoard.getCtx();
        canvas.style.cursor = "pointer";
        var startPos = this._drawBounds.topLeft;
        var width = this._drawBounds.bottomRight[0] - startPos[0];
        var height = this._drawBounds.bottomRight[1] - startPos[1];
        ctx.fillStyle = "#F0F0F0";
        ctx.fillRect(startPos[0], startPos[1], width, height);
    };

    var _onMouseOut = function () {
        var canvas = this.playBoard.getContainer();
        var ctx = this.playBoard.getCtx();
        canvas.style.cursor = "default";
        var startPos = this._drawBounds.topLeft;
        var width = this._drawBounds.bottomRight[0] - startPos[0];
        var height = this._drawBounds.bottomRight[1] - startPos[1];
        ctx.clearRect(startPos[0], startPos[1], width, height);
    };

    _cell.prototype.contains = function (point) {
        var topLeft = this._drawBounds.topLeft;
        var bottomRight = this._drawBounds.bottomRight;
        var containsAlongX = point[0] >= topLeft[0] && point[0] <= bottomRight[0];
        var containsAlongY = point[1] >= topLeft[1] && point[1] <= bottomRight[1];
        return containsAlongX && containsAlongY;
    };

    _cell.prototype.attachListeners = function () {
        this.on("mouseover", _onMouseOver.bind(this));
        this.on("mouseout", _onMouseOut.bind(this));
    };

    _cell.prototype.removeListeners = function () {
        this.off("mouseover");
        this.off("mouseout");
    };

    _cell.prototype.drawSymbol = function (type) {
        if (!this.isEmpty)
            return;
        var bounds = this._drawBounds;
        var symbol = new Symbol(type, {
            size: Math.min(bounds.bottomRight[0] - bounds.topLeft[0], bounds.bottomRight[1] - bounds.topLeft[1]),
            strokeWidth: 8
        });
        var image = symbol.create();
        var ctx = this.playBoard.getCtx();
        ctx.clearRect(bounds.topLeft[0], bounds.topLeft[1], bounds.bottomRight[0] - bounds.topLeft[0], bounds.bottomRight[1] - bounds.topLeft[1]);
        ctx.drawImage(image, bounds.topLeft[0], bounds.topLeft[1], image.width, image.height);
        this.isEmpty = false;
        this.symbol = symbol;
        if (this.playBoard.lastHoveredCell === this)
            this.playBoard.lastHoveredCell = null;
    }

    return _cell;
}());

var PlayBoard = (function () {

    var _defaultOptions = {
        width: 300,
        height: 300,
        style: {
            color: "red",
            strokeWidth: 8
        }
    };

    var _playBoard = function (options) {
        this._cells = [];        
        this.options = $.extend({}, _defaultOptions, options);
        this._container = document.createElement("canvas");
        this._container.height = this.options.height;
        this._container.width = this.options.width;
        this._ctx = this._container.getContext("2d");
        this.style = this.options.style;
        this._interactiveLayer = this._container;

        
        _buildReferences.call(this);
        this.attachListeners();
    };

    $.extend(_playBoard.prototype, Evented);

    var _buildReferences = function () {
        var rows = this.rows = [];
        var columns = this.columns = [];
        var diagonals = this.diagonals = [[], []];
        var cellWidth = this.options.width / 3;
        var cellHeight = this.options.height / 3;

        for (var i = 0, i1=0; i < this._container.height; i += cellHeight, i1++) {
            row = rows[rows.length] = [];
            for (var j = 0, j1=0 ; j < this._container.width; j += cellWidth, j1++) {
                if (i1 === 0) {
                    columns[j1] = [];
                }
                var options = {
                    startPos: [j, i],
                    size: [cellWidth, cellHeight],
                    strokeWidth: this.style.strokeWidth
                };
                cell = new Cell(options, this)
                this._cells.push(cell);
                row.push(cell);
                columns[j1].push(cell);
                if (i1 === j1) {
                    diagonals[0].push(cell);
                }
                if (i1 + j1 == 2)
                    diagonals[1].push(cell);
            }
        }
    };

    var _onMouseMove = function (event) {
        var dimension = this._container.getBoundingClientRect();
        var pos = [event.clientX - dimension.left, event.clientY - dimension.top];
        var cell = null;
        for (var i = 0, iL = this._cells.length; i < iL; i++) {
            if (this._cells[i].contains(pos)) {
                cell = this._cells[i];
                break;
            }
        }

        if (cell) {
            if (!cell.isEmpty) {
                this.lastHoveredCell = null;
                return;
            }
            if (this.lastHoveredCell == cell)
                return;
            else {
                if (this.lastHoveredCell)
                    this.lastHoveredCell.trigger("mouseout");
                this.lastHoveredCell = cell;
                cell.trigger("mouseover");
            }
        } else {
            if (this.lastHoveredCell)
                this.lastHoveredCell.trigger("mouseout");
            this.lastHoveredCell = null;
        }

        return cell;
    };

    var _onClick = function (event) {
        var dimension = this._container.getBoundingClientRect();
        var pos = [event.clientX - dimension.left, event.clientY - dimension.top];
        var cell = null;
        for (var i = 0, iL = this._cells.length; i < iL; i++) {
            if (this._cells[i].contains(pos)) {
                cell = this._cells[i];
                break;
            }
        }
        if (cell) {
            if (!cell.isEmpty)
                return;
            else
                this.trigger("click", [cell]);
        }
        
    };

    _playBoard.prototype.draw = function (container) {
        var d = $.Deferred();
        var _draw = function () {
            var canvas = this._container;
            var ctx = this._ctx;
            var cellWidth = this.options.width / 3;
            var cellHeight = this.options.height / 3;
            var h = canvas.height,
                w = canvas.width;
            // draw squared blocks
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.strokeStyle = this.style.color;
            ctx.lineWidth = this.style.strokeWidth;
            ctx.lineCap = "round";
            for (var i = cellWidth, j = cellHeight; i < canvas.width && j < canvas.height; i += cellWidth, j += cellHeight) {
                // draw vertical line
                ctx.beginPath();
                ctx.moveTo(i, 0);
                ctx.lineTo(i, h);
                ctx.stroke();
                ctx.closePath();

                // draw horizontal line
                ctx.beginPath();
                ctx.moveTo(0, j);
                ctx.lineTo(w, j);
                ctx.stroke();
                ctx.closePath();
            }
            $(container).append(canvas);
            d.resolve();
        }.bind(this);
        setTimeout(_draw, 0);
        return d.promise();
    };
  
    _playBoard.prototype.getSize = function () {
        return [this.options.width, this.options.height];
    };

    _playBoard.prototype.getContainer = function () {
        return this._container;
    }

    _playBoard.prototype.getCtx = function () {
        return this._ctx;
    }

    _playBoard.prototype.attachListeners = function () {
        this._cells.forEach(function (cell) {
            cell.attachListeners();
        });

        this.on("mousemove", _onMouseMove.bind(this), this._interactiveLayer);
        this.on("click", _onClick.bind(this), this._interactiveLayer);
    };

    _playBoard.prototype.removeListeners = function () {
        this._cells.forEach(function (cell) {
            cell.removeListeners();
        });

        this.off("mousemove");
        this.off("click");
    };


    _playBoard.prototype.getEmptyCells = function () {
        return this._cells.filter(function (cell) { return cell.isEmpty; })
    }
   
    return _playBoard;

}())

var User = (function () {
    var _user = function (chosenSymbolType, playboard, userName, autoPlay) {
        if (!chosenSymbolType)
            throw new Error("User must have a symbol.");
        if (!playboard)
            throw new Error("User needs a playboard.")
        this.chosenSymbolType = chosenSymbolType;
        this.playBoard = playboard;
        this.autoPlay = !!autoPlay;
        this.userName = userName || 'User';
        this.cellsVisited = [];
    };

    var _getRandomInt = function (min, max) {
        return min + Math.floor((max - min) * Math.random());
    }

    var _animate = function (cells) {
        var d = $.Deferred();
        var x1 = cells[0].center[0],
            y1 = cells[0].center[1],
            x0 = x1,
            y0= y1,
            x2 = cells[cells.length - 1].center[0],
            y2 = cells[cells.length - 1].center[1];
        var ctx = this.playBoard.getCtx();
        var gradient = ctx.createLinearGradient(0, 0, 300, 0);
        var _self = this;
        // Add three color stops
        gradient.addColorStop(0, 'red');
        gradient.addColorStop(0.5, 'orange');
        gradient.addColorStop(1, 'blue');
        var fragmentSizeX = (x2 - x1) / 100;
        var fragmentSizeY = (y2 - y1) / 100;    
        x2 = fragmentSizeX * 100 + x1;
        y2 = fragmentSizeY * 100 + y1;
        
        ctx.lineWidth = 10;
        ctx.strokeStyle = gradient;
        ctx.lineCap = "round";
        ctx.globalAlpha = 0.5;
        var _draw = function () {
            var x3 = x1 + fragmentSizeX;
            var y3 = y1 + fragmentSizeY;
            ctx.moveTo(x1, y1);
            ctx.beginPath();
            ctx.lineTo(x3, y3);
            ctx.stroke();
            x1 = x3;
            y1 = y3;
            if (Math.abs(x1 - x2) > Math.abs(fragmentSizeX) || Math.abs(y1 - y2) > Math.abs(fragmentSizeY))
                requestAnimationFrame(_draw);
            else {
                d.resolve();                
            }
        } 
        requestAnimationFrame(_draw);
        return d.promise();
    };


    _user.prototype.getSuggestion = function () {        
        var rows = this.playBoard.rows,
            columns = this.playBoard.columns,
            diagonals = this.playBoard.diagonals,
            symbol = this.chosenSymbolType,
            matched = [],
            attentionRequired = [];
            alternateSuggestions=[];

        // Check for row match
        for (var i = 0, iL = rows.length, row, opponentSymbols; i < iL; i++) {
            row = rows[i];
            matched = [];
            emptyCells = [];
            opponentSymbols = [];
            for (var c = 0, cL = row.length; c < cL; c++) {
                if (row[c].symbol) {
                    if (row[c].symbol.type == symbol)
                        matched.push(row[c]);
                    else
                        opponentSymbols.push(row[c]);
                }
                if (row[c].isEmpty)
                    emptyCells.push(row[c]);
                
            }
            if (matched.length === 2 && emptyCells.length == 1) {
                return row.find(function (cell) { return cell.isEmpty; });
            }
            if (matched.length == 1 && emptyCells.length == 2) {
                emptyCells.forEach(function (cell) { alternateSuggestions.push(cell); });
            }

            if (opponentSymbols.length == 2 && emptyCells.length == 1) {
                attentionRequired.push(emptyCells[0]);
            }
        }

        // Check for column match
        for (var j = 0, jL = columns.length, column, opponentSymbols; j < jL; j++) {
            column = columns[j];
            matched = [];
            emptyCells = [];
            opponentSymbols = [];
            for (var c = 0, cL = column.length; c < cL; c++) {
                if (column[c].symbol) {
                    if (column[c].symbol.type == symbol)
                        matched.push(column[c]);
                    else
                        opponentSymbols.push(column[c]);
                }
               
                if (column[c].isEmpty)
                    emptyCells.push(column[c]);
            }
            if (matched.length === 2 && emptyCells.length == 1) {
                return column.find(function (cell) { return cell.isEmpty; });
            }
            if (matched.length == 1 && emptyCells.length == 2) {
                emptyCells.forEach(function (cell) { alternateSuggestions.push(cell); });
            }
            if (opponentSymbols.length == 2 && emptyCells.length == 1) {
                attentionRequired.push(emptyCells[0]);
            }
        }

        // Check for diagonal match
        for (var k = 0, kL = diagonals.length, diagonal, opponentSymbols; k < kL; k++) {
            diagonal = diagonals[k];
            matched = [];
            emptyCells = [];
            opponentSymbols = [];
            for (var c = 0, cL = diagonal.length; c < cL; c++) {
                if (diagonal[c].symbol) {
                    if (diagonal[c].symbol.type == symbol)
                        matched.push(diagonal[c]);
                    else
                        opponentSymbols.push(diagonal[c]);
                }
                
                if (diagonal[c].isEmpty)
                    emptyCells.push(diagonal[c]);
            }
            if (matched.length === 2 && emptyCells.length == 1)
                return diagonal.find(function (cell) { return cell.isEmpty; });
            if (matched.length == 1 && emptyCells.length == 2) {
                emptyCells.forEach(function (cell) { alternateSuggestions.push(cell); });
            }
            if (opponentSymbols.length == 2 && emptyCells.length == 1) {
                attentionRequired.push(emptyCells[0]);
            }
        }

        var hardLevel = 0.96;
        if (attentionRequired.length == 2) {
            return attentionRequired[_getRandomInt(0, attentionRequired.length - 1)];
        }
        var random = Math.random();

        if (attentionRequired.length && random < hardLevel) {
            return attentionRequired[_getRandomInt(0, attentionRequired.length - 1)];
        }

        if (alternateSuggestions.length) 
            return alternateSuggestions[_getRandomInt(0, alternateSuggestions.length - 1)];
        return null;
       
    };

    _user.prototype.playMove = function (event, cell) {
        if (this.autoPlay) {
            var emptyCells = this.playBoard.getEmptyCells();
            if (emptyCells.length) {
                if (this.cellsVisited.length >= 1)
                    cell = this.getSuggestion();
                if (!cell) {
                    var nextMove = _getRandomInt(0, emptyCells.length - 1);
                    cell = emptyCells[nextMove];
                }                
            }
        } 

        if (cell) {
            this.playBoard.off("click");
            this.playBoard.removeListeners();
            cell.drawSymbol(this.chosenSymbolType);
            this.cellsVisited.push(cell);
            var _rs = this.getResult();
            if (_rs) {
                var _reset = function () {
                    $("#tic-tac-toe-board").empty();
                    $("#loss,#win,#draw").hide();
                    $("#divUserInputs").show();
                };
                if (_rs.result === "win") {
                    _animate.call(this, _rs.pattern).done(function () {
                        var _self = this;
                        if (_self.userName == "You") {
                            $("#tic-tac-toe-board").empty();
                            $("#win").show();
                            setTimeout(_reset, 3000);
                        } else {
                            $("#loss").show();
                            setTimeout(_reset, 1000);
                        }
                    }.bind(this));
                }
                else {
                    $("#draw").show();
                    setTimeout(_reset, 1000);
                }
                return;
            }            
            var opponent = this.opponent;
            if (opponent) {
                if (opponent.autoPlay) {
                    setTimeout(function () {
                        opponent.playMove();
                    }, 300);
                } else {
                    this.playBoard.attachListeners();
                    this.playBoard.on("click", opponent.playMove.bind(opponent));   
                }
            }
        }
        
    };

    _user.prototype.getResult = function () {
        var rows = this.playBoard.rows,
            columns = this.playBoard.columns,
            diagonals = this.playBoard.diagonals,
            symbol = this.chosenSymbolType,
            matched = false;
        var emptyCells = this.playBoard.getEmptyCells();
        if (emptyCells.length === 0) {
            return {
                result: "draw",
            };
        }

        // Check for row match
        for (var i = 0, iL = rows.length, row; i < iL; i++) {
            row = rows[i];
            matched = true;
            for (var c = 0, cL = row.length; c < cL; c++) {
                if ((!row[c].symbol) || (row[c].symbol.type !== symbol)) {
                    matched = false;
                    break;
                }
            }
            if (matched === true) {
                return {
                    result: "win",
                    pattern: row
                };
            }
        }

        // Check for column match
        for (var j = 0, jL = columns.length, column; j < jL; j++) {
            column = columns[j];
            matched = true;
            for (var c = 0, cL = column.length; c < cL; c++) {
                if ((!column[c].symbol) || (column[c].symbol.type !== symbol)) {
                    matched = false;
                    break;
                }
            }
            if (matched === true) {
                return {
                    result: "win",
                    pattern: column
                };
            }
        }

        // Check for diagonal match
        for (var k = 0, kL = diagonals.length, diagonal; k < kL; k++) {
            diagonal = diagonals[k];
            matched = true;
            for (var c = 0, cL = diagonal.length; c < cL; c++) {
                if ((!diagonal[c].symbol) || (diagonal[c].symbol.type !== symbol)) {
                    matched = false;
                    break;
                }
            }
            if (matched === true) {
                return {
                    result: "win",
                    pattern: diagonal
                };
            }
        }

        return null;
    };

    _user.prototype.setOpponent = function (opponent) {
        if (!(opponent instanceof User)) {
            throw new Error("Opponent must be a instance of User Class");
        }
        this.opponent = opponent;
    };

    return _user;
}())


$(function () {
    var $divUserInputs = $("#divUserInputs");
    var symbols = $(".symbol");
    symbols.click(function () {
        if (!$(this).hasClass("active")) {
            symbols.removeClass("active");
            $(this).addClass("active");
        }
    });

    var playButton = $("#btnPlay");
    var $playboardContainer = $("#tic-tac-toe-board");
    var $checkFirstMove = $("#checkFirstMove");

    playButton.click(function () {
        var chosenSymbol = symbols.filter(function () {
            return $(this).hasClass("active");
        }).attr("id");
        var hasCheckedFirstMove = $checkFirstMove.is(":checked");
        $divUserInputs.hide();
        var playBoard = new PlayBoard();
        var user = new User(+chosenSymbol, playBoard, "You");
        var computer = new User((chosenSymbol % 2) + 1, playBoard, "computer", true);
        user.setOpponent(computer);
        computer.setOpponent(user);
        playBoard.draw($playboardContainer).done(function () {
            if (!hasCheckedFirstMove)
                setTimeout(computer.playMove.bind(computer), 500);
            else
                playBoard.on("click", user.playMove.bind(user));
        });
        
    });

    function getColor() {
        var colors = ["red", "green", "blue", "yellow", "chartreuse", "CornflowerBlue", "Crimson", "DarkMagenta", "ForestGreen", "Gold", "LawnGreen", "OrangeRed", "Turquoise", "Violet"];
        var idx = Math.random() * (colors.length - 1);
        return colors[Math.floor(idx)];
    }

    var canvas = document.getElementById("burst");
    var ctx = canvas.getContext("2d");
    var Circle = function (cx, cy, r, color, life) {
        this.cx = cx;
        this.cy = cy;
        this.radius = r;
        this.color = color || getColor();
        this.life = life || 100;
        this.update = function () {
            if (this.life > 0) {
                this.life -= 10;
            } else {
                this.cx = Math.random() * canvas.width;
                this.cy = Math.random() * canvas.height;
                this.life = 100;
                this.color = getColor();
            }
        }
        this.draw = function () {
            ctx.fillStyle = this.color;
            ctx.globalAlpha = this.life / 100;
            ctx.beginPath();
            ctx.arc(this.cx, this.cy, this.radius, 0, 2 * Math.PI);
            ctx.fill();
            ctx.globalAlpha = 1;
        }
    }

    var circles = [];
    for (var i = 0; i < 500; i++) {
        var posX = Math.random() * canvas.width;
        var posY = Math.random() * canvas.height;
        var radius = Math.random() * 5;
        var color = getColor();
        var life = Math.random() * 100;
        circles.push(new Circle(posX, posY, radius, color, life));
    }

    var _burst = function () {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (var i = 0, iL = circles.length; i < iL; i++) {
            circles[i].draw();
            circles[i].update();
        }

        requestAnimationFrame(_burst);
    }
    requestAnimationFrame(_burst);    
});

        </script>
    </body>
</html>

8. By Dapper Mink

Made by Dapper Mink. This is a JavaScript Tic Tac Toe game made using the minimax algorithm. The AI automatically checks all the possibilities of the game and, therefore cannot loose! Good luck :^. ( Source )

<!DOCTYPE html>
<html>
    <head>
        <style>
        body {
    background-color: #333;
    font-size: 40px;
    color: #FFF;
}
table {
    border-collapse: collapse;
}
td {
    border: 1px solid #000;
    width: 100px;
    height: 100px;
    background-color: #FFF;
    font-size: 40px;
    font-family: Monospace;
    text-align: center;
    color: #000;
}
button {
    padding: 5px 15px;
    background: #0C9;
    color: #FFF;
    border: 0px none;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    margin: 5px;
    font-family: Arial;
}
        </style>
        <title>Tic Tac Toe</title>
        <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
    </head>
    <body>
        <script>
alert("This is a Tic Tac Toe game using the minimax algorithm.\nThe AI automatically checks all the possibilities of the game and, therefore cannot loose!\n\nGood luck :^)");
    $(function(){
var game, gameEnd;
var win = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
var startGame = function(){
    game = [];
    gameEnd = false;
    document.body.innerHTML = '';
    var table = $('<table>');
    for(var i = 0; i < 3; i++){
        var tr = $('<tr>');
        for(var j = 0; j < 3; j++){
            game.push('');
            var td = $('<td>').click(function(){
                if(this.innerHTML == '' && !gameEnd){
                    play($('td').index(this),'o');
                }
            });
            $(tr).append(td);
        }
        $(table).append(tr);
    }
    $('body').append(table);
}
var play = function(which,what){
    $($('td')[which]).text(what);
    game[which] = what;
    if(checkEnd(game)[0]){
        var p = $('<p>').text((checkEnd(game)[1] == 1) ? 'Tie! ' : 'You lost! ');
        var but = $('<button>').text('Restart');
        $(but).click(startGame);
        $('body').append(p.append(but));
        gameEnd = true;
    }
    if(what == 'o' && !gameEnd){
        var allCases = minimax(game,0);
        play(allCases.indexOf(allCases.filter(function(n){return n != undefined;}).reduce(function(a,b){return Math.max(a,b);})),'x');
    }
}
var checkEnd = function(a){
    var signs = ['o','x'];
    for(var j in signs){
        for(var i in win){
            if(a[win[i][0]] == signs[j] && a[win[i][1]] == signs[j] && a[win[i][2]] == signs[j]){
                return [true,2*j];
            }
        }
    }
    return [a.every(function(e){return e != ''}),1];
}
var minimax = function(g,turn){
    var arr = [];
    for(var k in g){
        if(new Set(arr).has([2,0][turn])){
            break;
        }else if(g[k] == ''){
            var g2 = g.slice();
            g2[k] = ['x','o'][turn];
            if(checkEnd(g2)[0]){
                arr.push(checkEnd(g2)[1]);
            }else{
                arr.push(minimax(g2,[1,0][turn]).filter(function(n){return n != undefined;}).reduce(function(a,b){return ([1,0][turn]) ? Math.min(a,b) : Math.max(a,b);}));
            }
            continue;
        }
        arr.push(undefined);
    }
    return arr;
}
startGame();
});
    </script>
    </body>
</html>

9. By Richard Myatt

Made by Richard Myatt. A game of tic tac toe. The main web application uses Vue.js and the game logic is a combination of strategy
presented in the Wikipedia article https://en.wikipedia.org/wiki/Tic-tac-toe and an implementation of the minimax algorithm. ( Source )

<!-- 
     Made: 9 April 2018
     Revised: 5 July 2018
-->


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Tic Tac Toe</title>
  <style>
      @import url('https://fonts.googleapis.com/css?family=Indie+Flower');
@import url('https://fonts.googleapis.com/css?family=Indie+Flower');

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

body {
  background-color: #eee;
}

.title {
  font-family: 'Indie Flower', cursive;
  font-size: 1.5vw;
  text-align: center;
  width: 28vw;
  padding: 0.1vw;
  color: #6b6d85;
  margin: 2vw auto;
}

#app {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  width: 28vw;
  height: 30vw;
  background-color: lightyellow;
  border-radius: 1vw;
  margin: 2.5vw auto;
  -webkit-box-shadow: -5px -5px 10px rgba(0, 0, 0, 0.4) inset,
                      5px 5px 10px rgba(0, 0, 0, 0.1) inset,
                      5px 5px 20px rgba(0, 0, 0, 0.7);
          box-shadow: -5px -5px 10px rgba(0, 0, 0, 0.4) inset,
                      5px 5px 10px rgba(0, 0, 0, 0.1) inset,
                      5px 5px 20px rgba(0, 0, 0, 0.7);
}

.top-panel {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  font-size: 1vw;
}

.bottom-panel {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  font-size: 1em;
}

.player-one, .player-two {
  padding-bottom: 0.5em;
}

.player-one {
  margin-left: 20px;
}

.player-two {
  margin-right: 20px;
}

.green-one, .green-two {
  border-bottom: 4px solid green;
}

.top-panel, .bottom-panel {
  width: 24vw;
  height: 3vw;
}

.game {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
  width: 24vw;
  height: 24vw;
  color: #fff;
  font-family: 'Indie Flower', cursive;
  background: -webkit-radial-gradient(#6b6d85, #373d2d);
  background: -o-radial-gradient(#6b6d85, #373d2d);
  background: radial-gradient(#6b6d85, #373d2d);
  -webkit-box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.7) inset;
          box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.7) inset;
}

.board {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr 1fr;
      grid-template-columns: 1fr 1fr 1fr;
  -ms-grid-rows: 1fr 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr;
  width:inherit;
  height: inherit;
}

.square {
  font-size: 4vw;
  font-weight: bold;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  border: 2px solid #fff;
}

.green {
  color: green;
}

.game h2 {
  font-size: 2vw;
}

.game p {
  font-size: 1vw;
}

.wording {
  text-align: center;
  padding: 2vw;
}

.btns {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack:distribute;
      justify-content:space-around;
  padding: 1.5vw 3vw 0 3vw;

}

button {
  background-color: orange;
  border-radius: 50%;
  color: #fff;
  font-size: 1.2em;
  padding: 0.5em;
  border-radius: 50%;
}

.reset, .again {
  width: 7.8vw;
  font-size: 1vw;
  padding: 0.3em;
  color: #000;
  background-color: lightblue;
}

.reset {
  margin-right: 20px;
}

.again {
  margin-left: 20px;
}


/* custom alert box */

.alert-container {
  position: fixed;
  top: 40%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
      -ms-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
  text-align: center;
  font-size: 20px;
  width: 320px;
  height: auto;
  margin: 0px auto;
  padding: 10px 20px 5px 20px;
  -webkit-box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
          box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
  -webkit-transition: all .3s ease;
  -o-transition: all .3s ease;
  transition: all .3s ease;
  border-radius: 20px;
  background-color: lightyellow;
  border: 2px solid black;
}

.alert-footer {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: end;
      -ms-flex-pack: end;
          justify-content: flex-end;
}

.alert-default-button {
  font-size: 0.8em;
  color: #000;
  background-color: lightblue;
  border-radius: 50%;
  padding: 10px;
  margin: 10px;
}

#show-alert {
  font-size: 20px;
  padding: 10px;
  border-radius: 10px;
  background-color: orange;
}

.alert-header {
  font-size: 20px;
  font-family: 'Indie Flower', cursive;
  color: #6b6d85;
}


@media only screen and (max-width:1400px) {
  /* For mobile phones: (x1.5)*/
  .title {
    font-size: 2.25vw;
    width: 42vw;
  }

  #app {
    width: 42vw;
    height: 45vw;
  }

  .game {
    width: 36vw;
    height: 36vw;
  }

  .game h2 {
    font-size: 3vw;
  }

  .game p {
    font-size: 1.5vw;
  }

  .square {
    font-size: 6vw;
  }

  .top-panel {
    font-size: 1.5vw;
  }

  .top-panel, .bottom-panel {
    width: 36vw;
    height: 4.5vw;
  }

  .btns {
    padding: 2.25vw;

  }

  button {
    font-size: 2.1vw;
  }

  .reset, .again {
    width: 11.7vw;
    font-size: 1.5vw;
  }

}

@media only screen and (max-width:620px) {
  /* For mobile phones: (x2.8)*/
  .title {
    font-size: 4.2vw;
    width: 67vw;
  }

  #app {
    width: 78vw;
    height: 84vw;
  }

  .game {
    width: 67vw;
    height: 67vw;
  }

  .game h2 {
    font-size: 5.6vw;
  }

  .game p {
    font-size: 2.8vw;
  }

  .square {
    font-size: 11.2vw;
  }

  .top-panel {
    font-size: 2.8vw;
  }

  .top-panel, .bottom-panel {
    width: 67vw;
    height: 8.4vw;
  }

  .btns {
    padding: 4.2vw;

  }

  button {
    font-size: 3.9vw;
  }

  .reset, .again {
    width: 21.8vw;
    font-size: 2.8vw;
  }

}

      </style>
</head>
<body>

  <div class="title">
    <h1>Tic Tac Toe</h1>
  </div>

  <div id="app">

    <div class="outer">
      <div class="top-panel">
        <div v-show="showPlayers" class="player-one" :class="{ 'green-one': oneIsActive }">({{ tokenone }}) {{ playerone }} | {{ scoreone }}</div>
        <div v-show="showPlayers" class="player-two" :class="{ 'green-two': twoIsActive }">({{ tokentwo }}) {{ playertwo }} | {{ scoretwo }}</div>
      </div>
      <div class="game">

        <component :is="component"
                   :board="board"
                   :win="win"
                   @play="playNext"
                   @player="setPlayer"
                   @token="setTokens"
                   ></component>


      </div>
      <div class="bottom-panel">
        <button class="again" @click="again" v-show="false">Play again</button>
        <button class="reset" @click="reset">Reset</button>
      </div>
    </div>

    <customalert v-if="showAlert"
                  @close="close"
                  :msg="message"></customalert>

  </div>


  <template id="screen1">
    <div>
      <div class="wording">
        <h2>How do you want to play?</h2>
      </div>

      <div class="btns">
        <button class="one-player" @click="$emit('player', 1)">One Player</button>
        <button class="two-players" @click="$emit('player', 2)">Two Players</button>
      </div>
    </div>
  </template>

  <template id="screen2">
    <div>
      <div class="wording">
        <h2>Would you like to be X or O?</h2>
        <p>(X plays first)</p>
      </div>

      <div class="btns">
        <button class="token-x" @click="$emit('token', 'X')">X</button>
        <button class="token-o" @click="$emit('token', 'O')">O</button>
      </div>
    </div>
  </template>

  <template id="screen3">
    <div>
      <div class="wording">
        <h2>Would you like to be X or O?</h2>
        <p>(X plays first)</p>
      </div>

      <div class="btns">
        <button class="token-x" @click="$emit('token', 'X')">X</button>
        <button class="token-o" @click="$emit('token', 'O')">O</button>
      </div>
    </div>
  </template>


  <template id="screen4">
    <div class="board">
      <div class="square" :class="{ green: win[0] }" @click="$emit('play', 0)">{{ board[0] }}</div>
      <div class="square" :class="{ green: win[1] }" @click="$emit('play', 1)">{{ board[1] }}</div>
      <div class="square" :class="{ green: win[2] }" @click="$emit('play', 2)">{{ board[2] }}</div>
      <div class="square" :class="{ green: win[3] }" @click="$emit('play', 3)">{{ board[3] }}</div>
      <div class="square" :class="{ green: win[4] }" @click="$emit('play', 4)">{{ board[4] }}</div>
      <div class="square" :class="{ green: win[5] }" @click="$emit('play', 5)">{{ board[5] }}</div>
      <div class="square" :class="{ green: win[6] }" @click="$emit('play', 6)">{{ board[6] }}</div>
      <div class="square" :class="{ green: win[7] }" @click="$emit('play', 7)">{{ board[7] }}</div>
      <div class="square" :class="{ green: win[8] }" @click="$emit('play', 8)">{{ board[8] }}</div>
    </div>
  </template>

  <template id="alert-template">
    <div class="alert-container">

      <div class="alert-header">
        <h3>Tic Tac Toe</h3>
      </div>

      <div class="alert-body">
       <p>{{ msg }}</p>
      </div>

      <div class="alert-footer">
          <button class="alert-default-button" @click="$emit('close')">
            OK
          </button>
      </div>
    </div>
  </template>

  <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

  <script>
      
     /* Author: Richard Myatt
   Date: 9 April 2018

   A game of tic tac toe being a challenge set by freecodecamp.  The main web
   application uses Vue.js and the game logic is a combination of strategy
   presented in the wikipedia article https://en.wikipedia.org/wiki/Tic-tac-toe
   and an implementation of the minimax algorithm.

*/

Vue.component("screen-one", {
  template: "#screen1"
});

Vue.component("screen-two", {
  template: "#screen2"
});

Vue.component("screen-three", {
  template: "#screen3"
});

Vue.component("screen-four", {
  template: "#screen4",
  props: ["board", "win"]
});

Vue.component('customalert', {
  props: ["msg"],
  template: '#alert-template'
});


var main = new Vue({
  el: "#app",
  data: {
    autoPlayAgain: true,
    playAgainEnabled: false,
    resetEnabled: true,
    singlePlayer: true,
    playerone: "Player 1",
    playertwo: "",
    tokenone: "",
    tokentwo: "",
    scoreone: 0,
    scoretwo: 0,
    oneIsActive: false,
    twoIsActive: false,
    showPlayers: false,
    board: ["", "", "", "", "", "", "", "", ""],
    win: [false, false, false, false, false, false, false, false, false],
    component: "screen-one",
    message: "",
    showAlert: false
  },
  methods: {
    reset: function() {
      if(this.resetEnabled === true) {
        this.playAgainEnabled = false;
        this.resetEnabled = true;
        this.singlePlayer = true;
        this.playertwo = "";
        this.tokenone = "";
        this.tokentwo = "";
        this.scoreone = 0;
        this.scoretwo = 0;
        this.oneIsActive = false;
        this.twoIsActive = false;
        this.showPlayers = false;
        this.board = ["", "", "", "", "", "", "", "", ""];
        this.win = [false, false, false, false, false, false, false, false, false];
        this.component = "screen-one";
      }
    },
    again: function() {
      if(this.playAgainEnabled) {
        for(var i = 0; i < 9; i++) {
          this.$set(this.board, i, "");
          this.$set(this.win, i, false);
        }

        if(this.tokenone === "X") {
          this.oneIsActive = true;
          this.playAgainEnabled = false;
        } else if(this.tokenone === "O" && this.playertwo === "Computer") {
          this.twoIsActive = true;
          this.playAgainEnabled = false;
          setTimeout(function() { playComputer(); }, 1000);
        } else {
          this.twoIsActive = true;
          this.playAgainEnabled = false;
        }
      }
    },
    setPlayer: function(arg) {
      if(arg === 1) {
        this.singlePlayer = true;
        this.playertwo = "Computer";
        this.component = "screen-two";
      } else if(arg === 2) {
        this.singlePlayer = false;
        this.playertwo = "Player 2";
        this.component = "screen-three";
      }
    },
    setTokens: function(token) {
      if(token === "X") {
        this.tokenone = "X";
        this.tokentwo = "O";
        this.oneIsActive = true;
      } else if(token === "O") {
        this.tokenone = "O";
        this.tokentwo = "X";
        this.twoIsActive = true;
      }
      this.component = "screen-four";
      this.showPlayers = true;
      if(this.singlePlayer && this.twoIsActive) {
        setTimeout(function() { playComputer(); }, 1000);
      }
    },
    playNext: function(i) {
      var tempBoard = new Board(brd=this.board);
      if(this.singlePlayer && tempBoard.isAvailable(i + 1) && this.playAgainEnabled === false) {
        if(this.oneIsActive === true) {
          var token = this.tokenone;
          this.$set(this.board, i, token);
          var temp = new Board(brd = this.board);
          if(temp.isWin() || temp.isDraw()) {
            handleWinOrDraw(temp);
            toggleActivePlayer();
            return;
          }
          toggleActivePlayer();
          setTimeout(function() { playComputer(); }, 1000);
        }
      } else if(!this.singlePlayer) {        // two individual players
        // check that square is available
        //var tempBoard = new Board(brd=this.board);
        if(tempBoard.isAvailable(i + 1) && this.playAgainEnabled === false) {
          // get next move number
          var nextMoveNum = tempBoard.getNextMoveNum();
          if(nextMoveNum % 2 === 0) {
            this.$set(this.board, i, "O");
            checkBoardState();

          } else {
            this.$set(this.board, i, "X");
            checkBoardState();
          }
        }
      }
    },
    close: function() {
      this.message = "";
      this.showAlert = false;
      this.playAgainEnabled = true;
      this.resetEnabled = true;
      this.again();
    }
  }
  });


// function to handle computers moves
function playComputer() {
  if(main.twoIsActive === true) {
    var tempBoard = new Board(brd=main.board);
    var nextMove  = tempBoard.getNextMoveNum();

    switch(nextMove) {
      case 1:
        main.$set(main.board, 4, "X");
        break;
      case 2:
        if(tempBoard.isAvailable(5)) {
          main.$set(main.board, 4, "O");
        } else {
          main.$set(main.board, randCornerIndex(), "O");
        }
        break;
      case 3:
        var result = cornerContains(tempBoard.board, "O");
        if(nextMove === 3 && result !== -1) {
          switch(result) {
            case 0:
              main.$set(main.board, 8, "X");
              break;
              case 2:
                main.$set(main.board, 6, "X");
                break;
              case 6:
                main.$set(main.board, 2, "X");
                break;
              case 8:
                main.$set(main.board, 0, "X");
                break;
          }
          break;
        } else if (nextMove === 3 && result === -1) {
          main.$set(main.board, randCornerIndex(), "X");
          break;
        }
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:
      case 9:
        var move = tempBoard.selectBestMove();
        main.$set(main.board, move, main.tokentwo);
        if(tempBoard.isWin() || tempBoard.isDraw()) {
          handleWinOrDraw(tempBoard);
        } else {
        }
        break;
      }
  }
  toggleActivePlayer();
}


// helper method to return a random corner index
function randCornerIndex() {
  var corner = [0, 2, 6, 8];
  var choice = Math.floor(Math.random() * 4);
  return corner[choice];
}


// helper function to determine if the corner of the board is occupied
function cornerContains(brd, token) {
  var corner = [0, 2, 6, 8];
  for(var i = 0; i < corner.length; i++) {
    if(token === brd[corner[i]]) {
      return corner[i];
    }
  }
  return -1;
}


// function to check the state of the board and prepare for the next move
function checkBoardState() {
  var tempBoard = new Board(brd=main.board);
  if(tempBoard.isWin() || tempBoard.isDraw()) {
    handleWinOrDraw(tempBoard);
    toggleActivePlayer();
  } else {
    toggleActivePlayer();
  }
}

// function to handle a win or draw
function handleWinOrDraw(brd) {
  // identify current player
  var currentPlayer;
  if(main.oneIsActive === true) {
    currentPlayer = main.playerone;
  } else {
    currentPlayer = main.playertwo;
  }

  // check for win or draw
  if(brd.isWin()) {
    var row = brd.getWinningRow();
    for(var i = 0; i < row.length; i++) {
      main.$set(main.win, row[i], true);
    }
    // increment score
    if(currentPlayer === main.playerone) {
      main.scoreone += 1;
    } else {
      main.scoretwo += 1;
    }
    if(currentPlayer === "Computer") {
      var str = "Ooops.. " + currentPlayer + " wins!!!";
      main.message = str;
      callCustomAlert();
    } else {
      var str = "Congratulations " + currentPlayer + " you win!";
      main.message = str;
      callCustomAlert();
    }

  } else if(brd.isDraw()) {
    var str = "A Draw";
    main.message = str;
    callCustomAlert();
  }

  // remove the status bar
    main.oneIsActive = true;
    main.twoIsActive = true;
}

// function to introduce a delay into the calling of the final custom alert
function callCustomAlert() {
  setTimeout(function() {
    main.showAlert = true;
    main.resetEnabled = false;
  }, 1300);
}

// function to toggle active player status
function toggleActivePlayer() {
  main.oneIsActive = !main.oneIsActive;
  main.twoIsActive = !main.twoIsActive;
}


/* Author: Richard Myatt
   Date: 9 April 2018

   A game of tic tac toe being a challenge set by freecodecamp.  The main web
   application uses Vue.js and the game logic is a combination of strategy
   presented in the wikipedia article https://en.wikipedia.org/wiki/Tic-tac-toe
   and an implementation of the minimax algorithm.

*/


// constructor for the board
function Board(arr) {
  if(arr === undefined) {
    this.board = ["", "", "", "", "", "", "", "", ""];
  }else {
    this.board  = arr;
  }

}


// method returns the array of rows for the board
Board.prototype.getRows = function() {
  this.row1   = [this.board[0], this.board[1], this.board[2]];
  this.row2   = [this.board[3], this.board[4], this.board[5]];
  this.row3   = [this.board[6], this.board[7], this.board[8]];
  this.col1   = [this.board[0], this.board[3], this.board[6]];
  this.col2   = [this.board[1], this.board[4], this.board[7]];
  this.col3   = [this.board[2], this.board[5], this.board[8]];
  this.diag1  = [this.board[0], this.board[4], this.board[8]];
  this.diag2  = [this.board[2], this.board[4], this.board[6]];
  this.rows   = [this.row1, this.row2, this.row3, this.col1, this.col2,
                  this.col3, this.diag1, this.diag2];

  return this.rows;
};


// method that returns the rows for a given index - no tests
Board.prototype.getRowsForIndex = function(index) {
  this.getRows();
  switch(index) {
    case 0:
      return [this.row1, this.col1, this.diag1];
    case 1:
      return [this.row1, this.col2];
    case 2:
      return [this.row1, this.col3, this.diag2];
    case 3:
      return [this.row2, this.col1];
    case 4:
      return [this.row2, this.col2, this.diag1, this.diag2];
    case 5:
      return [this.row2, this.col3];
    case 6:
      return [this.row3, this.col1, this.diag2];
    case 7:
      return [this.row3, this.col2];
    case 8:
      return [this.row3, this.col3, this.diag1];
  }
};


// method to return the cross row which applies when an edge is played
Board.prototype.getCrossRow = function(index) {
  this.getRows();
  switch(index) {
    case 1:
      return this.col2;
    case 3:
      return this.row2;
    case 5:
      return this.row2;
    case 7:
      return this.col2;
  }
};


// method checks if the current board position is a win. Returns true or false
Board.prototype.isWin = function() {
  this.getRows();
  for(var i = 0; i < 8; i++) {
    if(arraysEqual(this.rows[i], ["X", "X", "X"]) || arraysEqual(this.rows[i], ["O", "O", "O"])) {
      return true;
    }
  }
  return false;
};


// method returns an array of indecies for the winning row.  If there is no winning
// row -1 is returned
Board.prototype.getWinningRow = function() {
  this.getRows();
  if(this.isWin()) {
    for(var i = 0; i < 8; i++) {
      if(arraysEqual(this.rows[i], ["X", "X", "X"]) || arraysEqual(this.rows[i], ["O", "O", "O"])) {
        switch(i) {
          case 0:
            return [0, 1, 2];
          case 1:
            return [3, 4, 5];
          case 2:
            return [6, 7, 8];
          case 3:
            return [0, 3, 6];
          case 4:
            return [1, 4, 7];
          case 5:
            return [2, 5, 8];
          case 6:
            return [0, 4, 8];
          case 7:
            return [2, 4, 6];
        }
      }
    }
  } else {
    return -1;
  }
};


// method to determine if the position is a draw
Board.prototype.isDraw = function() {
  if(this.isWin() === false && this.getNextMoveNum() === -1) {
    return true;
  } else {
    return false;
  }
};


// method which returns the number of the next move
Board.prototype.getNextMoveNum = function() {
  // count number of available position
  var num = 0;
  for(var i = 0; i < 9; i++) {
    if(this.board[i] === "") {
      num += 1;
    }
  }
  if(num === 0) {
    return -1;
  } else {
    return 9 - num + 1;
  }
};


// method check if the specified board position is available and returns true or
// false.  pos takes values from 1 to 9.
Board.prototype.isAvailable = function(pos) {
  if(this.board[pos - 1] === "") {
    return true;
  } else {
    return false;
  }
};


// method returns an array indexes of positions which are currently available
Board.prototype.available = function() {
  var result = [];
  for(var i = 0; i < 9; i++) {
    if(this.board[i] === "") {
      result.push(i);
    }
  }
  return result;
};


// method which returns the next token to play assuming X always starts the game
Board.prototype.getNextTokenToPlay = function() {
  var nextMoveNum = this.getNextMoveNum();
  if(nextMoveNum % 2 === 0) {
    return "O";       // "O" plays on all even moves
  } else {
    return "X";       // "X" plays on all odd moves
  }
};


// method to return all possible boards given a board position
// this assumes that X always starts the game
Board.prototype.getAllPosBoards = function() {
  var result = [];
  var tempBoard = this.board.slice();
  var possiblePositions = this.available();
  var token             = this.getNextTokenToPlay();
  for(var i = 0; i < possiblePositions.length; i++) {
    var newBoard = tempBoard.slice();
    newBoard[possiblePositions[i]] = token;
    result.push(newBoard);
  }
  return result;
};


// method to rank the move specified by pos which takes an integer 1 - 9.
Board.prototype.rankMove = function(pos) {
  var token       = this.getNextTokenToPlay();
  var tempBoard   = this.board.slice();
  if(this.isAvailable(pos)) {
    tempBoard[pos - 1] = token;
  } else {
    console.log("position already taken");
  }
  var tempBrd = new Board(tempBoard);

  if(tempBrd.isWin()) {
    return 10;
  } else {
    brds = [tempBrd.board];
    return analyseLevels(brds, 2);
  }
};


// method which returns an analysis of the Moves available at the current board
// position.  Returns an array of arrays providing the index and the rank of the
// move
Board.prototype.analyseMovesFor = function() {
  var result = [];          // holds the result
  var tempBoard = this.board.slice(); // copy present board
  var choices   = this.available();   // get a list of available indecies
  for(var i = 0; i < choices.length; i++) {
    var tempBoardObj = new Board(tempBoard);
    var index = choices[i];
    var rank = tempBoardObj.rankMove(index + 1);
    //newBoard = tempBoard;
    result.push([index, rank]);
  }
  return result;
};


// method to select the best move based on analyseMovesFor()
// returns the best move in the form index
Board.prototype.selectBestMove = function() {
  var token = this.getNextTokenToPlay();
  var selection = this.selectTopRankedMovesFor();
  // check for posibility of a fork
  for(var i = 0; i < selection.length; i++) {
    if(this.isFork(selection[i][0])) {
      // play at this position
      return selection[i][0];
    }
  }
  // can the opponent form a fork?
  for(var l = 0; l < selection.length; l++) {
    if(this.isOpponentFork(selection[l][0])) {
      if(this.isCorner(selection[l][0])) {
        // look for an edge play which will force a defense
        for(var m = 0; m < selection.length; m++) {
          if(this.isEdge(selection[m][0])) {
            var crossRow = this.getCrossRow(selection[m][0]);
            // does this row contain an opponent token
            if(token === "X") {
              opponentToken = "O";
            } else {
              opponentToken = "X";
            }
            if(crossRow.indexOf(opponentToken) === -1) {
              return selection[m][0];
            }
          }
        }
      }
    }
  }
  // no fork return first top ranked move then check for possibility of play at
  // a corner
  for(var k = 0; k < selection.length; k++) {
    if(this.isCorner(selection[k][0])) {
      return selection[k][0];
    }
  }
  // if neither a fork or a corner is available to play then return the first
  // top ranked move
  return selection[0][0];
};


// helper function to return value of largest rank as an integer given an array
// containing the analysed moves for this position
function getFirstLargestSelection(moves) {
  var selection = moves[0];
  var largest = moves[0][1];
  for(var i = 0; i < moves.length; i++) {
    if(largest < moves[i][1]) {
      largest = moves[i][1];
      selection = moves[i];
    }
  }
  return selection;
}


// method returns an array  of top ranked moves
Board.prototype.selectTopRankedMovesFor = function() {
  var result = [];
  var movesFromAnalysis = this.analyseMovesFor();
  var selection = getFirstLargestSelection(movesFromAnalysis);
  var topRank   = selection[1];
  for(var i = 0; i < movesFromAnalysis.length; i++) {
    if(movesFromAnalysis[i][1] === topRank) {
      result.push(movesFromAnalysis[i]);
    }
  }
  return result;
};


// method that determines if a selected play produces a fork.  Returns true if
// a fork can be created from that position, otherwise false
Board.prototype.isFork = function(index) {
  var token = this.getNextTokenToPlay();
  var rows = this.getRowsForIndex(index);
  var prospect = 0;       // a prospect contains one token and two spaces
  for(var i = 0; i < rows.length; i++) {

    if(rows[i].indexOf(token) !== -1) {   // row contains at least one tokenn
      // count spaces
      var spaces = 0;
      for(var k = 0; k < 3; k++) {
        if(rows[i][k] === "") {
          spaces += 1;
        }
      }
      if(spaces > 1) {
        prospect += 1;
      }
    }
  }
  if(prospect >= 2) {
    return true;
  } else {
    return false;
  }
};


// method to return the prospect of the opponent playing a fork.
Board.prototype.isOpponentFork = function(index) {
  var token = this.getNextTokenToPlay();
  if(token === "X") {
    token = "O";
  } else {
    token = "X";
  }
  var rows = this.getRowsForIndex(index);
  var prospect = 0;       // a prospect contains one token and two spaces
  for(var i = 0; i < rows.length; i++) {

    if(rows[i].indexOf(token) !== -1) {   // row contains at least one tokenn
      // count spaces
      var spaces = 0;
      for(var k = 0; k < 3; k++) {
        if(rows[i][k] === "") {
          spaces += 1;
        }
      }
      if(spaces > 1) {
        prospect += 1;
      }
    }
  }
  if(prospect >= 2) {
    return true;
  } else {
    return false;
  }
};


// method that determines if a selected play produces a corner move.  Returns
// true or false
Board.prototype.isCorner = function(index) {
  var cornerIndexes = [0, 2, 6, 8];
  if(cornerIndexes.indexOf(index) !== -1) {
    return true;
  } else {
    return false;
  }
};


// method that determines if a selected play produces an edge move.  Returns
// true or false
Board.prototype.isEdge = function(index) {
  var edgeIndexes = [1, 3, 5, 7];
  if(edgeIndexes.indexOf(index) !== -1) {
    return true;
  } else {
    return false;
  }
};


// helper function for rankMove to analyse each level given an array of boards
// and the level
function analyseLevels(brds, lvl) {
  // get an array of boards for this level
  var newBoards = [];         // holds all posible boards for this level
  for(var i = 0; i < brds.length; i++) {
    var tempBoard = new Board(brds[i]);
    var collection = tempBoard.getAllPosBoards();
    for(var j = 0; j < collection.length; j++) {
      newBoards.push(collection[j]);
    }
  }
  for(var k = 0; k < newBoards.length; k++) {
    var firstBoard = new Board(newBoards[0]);
    if(newBoards.length === 1 && firstBoard.isWin()) {
      return -10;
    } else if(newBoards.length === 1 && firstBoard.isDraw()) {
      return 0;
    }else {
      if(incTerminalState(newBoards)) {
        if(lvl % 2 === 0) {
          return -(12 - lvl);
        } else {
          return (11 - lvl);
        }
      } else {
        return analyseLevels(newBoards, lvl + 1);
      }
    }
  }
}


// helper method to check the equality of arrays arr1, and arr2.  Returns
// true or false
function arraysEqual(arr1, arr2) {
  if (arr1 === arr2) return true;
  if (arr1 == null || arr2 == null) return false;
  if (arr1.length != arr2.length) return false;

  for (var i = 0; i < arr1.length; ++i) {
    if (arr1[i] !== arr2[i]) return false;
  }
  return true;
}


// helper method to check the equality of nested arrays arr1, and arr2.  Returns
// true or false.  Deals with two dimensional arrays only
function nestedArraysEqual(arr1, arr2) {
  if (arr1 === arr2) return true;
  if (arr1 == null || arr2 == null) return false;
  if (arr1.length != arr2.length) return false;

  for (var i = 0; i < arr1.length; ++i) {
    if (!arraysEqual(arr1[i], arr2[i])) return false;
  }
  return true;
}


// function which takes an array of boards and checks to determine if a terminal
// state is present in the array, either a win or a draw
function incTerminalState(boards) {
  for(var i = 0; i < boards.length; i++) {
    var tempBoard = new Board(boards[i]);
    //console.log(tempBoard);
    if(tempBoard.isWin() || tempBoard.isDraw()) {
      return true;
    }
  }
  return false;
}

      
  </script>


</body>
</html>

10. By Dream

Made by Dream. Simple JavaScript Tic Tac Toe game with three modes. ( Source )

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="game.css">
<style>
    body {
    box-sizing: border-box;
    display: flex;
    height: 100vh;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-family: Oswald;
    background-color: #5cc;
    margin: 0;
  }
  
  .overlay {
    display: none;
    position: absolute;
    width: 100%;
    height: 85vh;
    top: 0;
  }
  .overlay.show {
    display: block;
  }
  
  .msg {
    display: none;
    position: absolute;
    width: 100%;
    height: 85vh;
    top: 0;
    font-size: 12vh;
    overflow: hidden;
  }
  .msg span {
    display: none;
    position: absolute;
    width: 100%;
    height: 100%;
    background: rgba(85, 204, 204, 0.8);
    left: 0;
    text-align: center;
    line-height: 80vh;
  }
  .msg span.show {
    display: block;
  }
  
  .tic-tac-toe {
    position: relative;
    display: grid;
    grid-template-rows: repeat(3, 25vh);
    grid-template-columns: repeat(3, 33.3%);
    width: 75vh;
  }
  .tic-tac-toe .box {
    display: block;
    position: relative;
  }
  .tic-tac-toe .box:nth-of-type(1), .tic-tac-toe .box:nth-of-type(2), .tic-tac-toe .box:nth-of-type(4), .tic-tac-toe .box:nth-of-type(5), .tic-tac-toe .box:nth-of-type(7), .tic-tac-toe .box:nth-of-type(8) {
    border-right: 3px solid #388;
  }
  .tic-tac-toe .box:nth-of-type(2), .tic-tac-toe .box:nth-of-type(3), .tic-tac-toe .box:nth-of-type(5), .tic-tac-toe .box:nth-of-type(6), .tic-tac-toe .box:nth-of-type(8), .tic-tac-toe .box:nth-of-type(9) {
    border-left: 3px solid #388;
  }
  .tic-tac-toe .box:nth-of-type(4), .tic-tac-toe .box:nth-of-type(5), .tic-tac-toe .box:nth-of-type(6), .tic-tac-toe .box:nth-of-type(7), .tic-tac-toe .box:nth-of-type(8), .tic-tac-toe .box:nth-of-type(9) {
    border-top: 3px solid #388;
  }
  .tic-tac-toe .box:nth-of-type(1), .tic-tac-toe .box:nth-of-type(2), .tic-tac-toe .box:nth-of-type(3), .tic-tac-toe .box:nth-of-type(4), .tic-tac-toe .box:nth-of-type(5), .tic-tac-toe .box:nth-of-type(6) {
    border-bottom: 3px solid #388;
  }
  .tic-tac-toe .box.show-circle .circle {
    display: block;
  }
  .tic-tac-toe .cross {
    display: none;
    position: relative;
    width: 100%;
    height: 100%;
  }
  .tic-tac-toe .cross::before,
  .tic-tac-toe .cross::after{
      content: "";
      display: block;
      position: absolute;
      width: 80%;
      height: 6px;
      top: 50%;
      left: 50%;
      margin-top: -3px;
      margin-left: -40%;
      background-color: black;
  }
  .tic-tac-toe .cross:before {
    transform: rotate(45deg);
  }
  .tic-tac-toe .cross:after {
    transform: rotate(135deg);
  }
  .tic-tac-toe .circle{
      display: none;
      box-sizing: border-box;
      position: absolute;
      width: 16vh;
      height: 16vh;
      top: 50%;
      margin-top: -8vh;
      left: 50%;
      margin-left: -8vh;
      border-radius: 50%;
      border: 6px solid white;
  }
  .tic-tac-toe input{
      display: none;
      position: absolute;
      top: 0;
  }

  .tic-tac-toe input:checked ~ .cross{
      display: block;
  }
  a .replay{
      color: black;
      font-size: 6vh;
      margin: 5vh auto 0;
      color: white;
      background-color: #388;
      padding: 1.6vh 4.8vh 1.8vh;
      line-height: 1em;
      text-decoration: none;
      transform: color 0.4s;
  }
  a .replay:hover{
      background-color: #166;
  }
  .controls{
      position: absolute;
      top: -3vh;
      right: -32vh;
  }
  .controls a{
      display: block;
      color: #388;
      font-size: 6vh;
      text-decoration: none;
      margin: 2vh auto;
      transform: color 0.4s;
  }
  .controls a:hover{
      color: #144;
  }
  .controls a.active{
      color: #144;
  }
.replay{
    padding: 14px;
    text-decoration: none;
    background-color: white;
    color: black;
}
  

    </style>
</head>
<body>
     
<div class="tic-tac-toe normal">
    <label class="box box-1">
      <input type="checkbox" onchange="changed(this)" data-num="1"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-2">
      <input type="checkbox" onchange="changed(this)" data-num="2"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-3">
      <input type="checkbox" onchange="changed(this)" data-num="3"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-4">
      <input type="checkbox" onchange="changed(this)" data-num="4"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-5">
      <input type="checkbox" onchange="changed(this)" data-num="5"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-6">
      <input type="checkbox" onchange="changed(this)" data-num="6"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-7">
      <input type="checkbox" onchange="changed(this)" data-num="7"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-8">
      <input type="checkbox" onchange="changed(this)" data-num="8"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <label class="box box-9">
      <input type="checkbox" onchange="changed(this)" data-num="9"/>
      <div class="cross"></div>
      <div class="circle"></div>
    </label>
    <div class="controls"><a class="easy" href="javascript:lvl(0);">EASY</a><a class="normal active" href="javascript:lvl(1);">NORMAL</a><a class="impossible" href="javascript:lvl(2);">IMPOSSIBLE</a></div>
  </div>
  <div class="overlay"></div>
  <div class="msg">
      <span class="win">YOU WIN!</span>
      <span class="lost">YOU LOST!</span>
      <span class="draw">DRAW!</span></div>
      <a class="replay" href="javascript:replay();">REPLAY</a>
      <!-- now add javascript code -->
      <script>
        const boxes = document.querySelectorAll('.box');
let seq = { 1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '' };
let gameEnd = false;

const $ = el => document.querySelector(el);

function changed(el) {
  if (el.checked) {
    el.disabled = true;
    let n = parseInt(el.getAttribute('data-num'));
    seq[n] = 'x';
    checkWin();
    if (Object.values(seq).filter(Boolean).length < 9 && !gameEnd) {
      calculateNextPosition();
    }
  }
}

const checkInclude = player => (...indices) => indices.every(i => seq[i] === player);
const checkIncludeX = checkInclude('x');
const checkIncludeO = checkInclude('o');

function checkWin() {
  const gameWon = player => ( checkInclude(player)(1, 2, 3) ||
                              checkInclude(player)(4, 5, 6) ||
                              checkInclude(player)(7, 8, 9) ||
                              checkInclude(player)(1, 4, 7) ||
                              checkInclude(player)(2, 5, 8) ||
                              checkInclude(player)(3, 6, 9) ||
                              checkInclude(player)(1, 5, 9) ||
                              checkInclude(player)(3, 5, 7) )

  if (gameWon('x') || gameWon('o')) {
    const playerWon = gameWon('x') ? '.win' : '.lost';
    boxes.forEach(box => box.querySelector('input').disabled = true);
    $('.msg').style.display = 'block';
    $(playerWon).classList.add('show');
    gameEnd = true;
  } else if (Object.values(seq).filter(Boolean).length === 9) {
    $('.msg').style.display = 'block';
    $('.draw').classList.add('show');
  }
}

const addCircle = boxNumber => {
  seq[boxNumber] = 'o';
  $('.overlay').classList.add('show');

  setTimeout(()=> {
    $('.box-'+boxNumber).classList.add('show-circle');
    $('.box-'+boxNumber).querySelector('input').disabled = true;
    $('.overlay').classList.remove('show');
    checkWin();
  }, 400);
}

function calculateNextPosition() {  
  let tar = Math.ceil(Math.random()*9);
  const xo_includes = _tar => checkIncludeO(_tar) || checkIncludeX(_tar);
  const isValidNextPosition = newPos => !xo_includes(newPos) ? tar = newPos : null

  while (checkIncludeO(tar) || checkIncludeX(tar)) {
    tar = Math.ceil(Math.random()*9);
  }
  if (!$('.tic-tac-toe').classList.contains('easy')) {
    for (let x = 1; x < 10; x++) {
      if (checkIncludeX(x, x+1)) {
        // x x _ / _ x x
        if ([1, 4, 7].includes(x)) {
          isValidNextPosition(x+2);
        } else if ([2, 5, 8].includes(x)) {
          isValidNextPosition(x-1)
        }
      }
      if (checkIncludeX(x, x+2) && [1, 4, 7].includes(x)) {
        // x _ x
        isValidNextPosition(x+1)
      }
      if (checkIncludeX(x, x+3) && x <= 6) {
        // x _ _ / _ x _ / _ _ x
        // x _ _ / _ x _ / _ _ x
        const _tar = (x+6 > 9) ? x-3 : x+6;
        isValidNextPosition(_tar)
      }
      if ( [1, 3].includes(x) && checkIncludeX(x, 5) ) {
        // x _ _ / _ _ x
        // _ x _ / _ x _
        // _ _ _ / _ _ _
        const _tar = (x == 1) ? 9 : 7;
        isValidNextPosition(_tar)
      }
      if ( [7, 9].includes(x) && checkIncludeX(x, 5) ) {
        // _ _ _ / _ _ _
        // _ x _ / _ x _
        // _ _ x / x _ _
        const _tar = (x == 7) ? 3 : 1;
        isValidNextPosition(_tar)
      }
      if ($('.tic-tac-toe').classList.contains('impossible')) {   
        if (checkIncludeX(x, x+6) && x <= 3) {
          // x _ _ / _ x _ / _ _ x
          // _ _ _ / _ _ _ / _ _ _
          // x _ _ / _ x _ / _ _ x
          isValidNextPosition(x+3)
        }   
        if ( (x == 1 && checkIncludeX(x, x+8)) || (x == 3 && checkIncludeX(x, x+4)) ) {
          // x _ _ / _ _ x
          // _ _ _ / _ _ _
          // _ _ x / x _ _
          isValidNextPosition(5)
        }
      }
    }
  }
  addCircle(tar);
}

function replay() {
  seq = {};
  boxes.forEach(box => {
    box.querySelector('input').disabled = false;
    box.querySelector('input').checked = false;
    box.classList.remove('show-circle');
  })
  $('.msg').style.display = "none";
  $('.win').classList.remove('show');
  $('.lost').classList.remove('show');
  $('.draw').classList.remove('show');
  gameEnd = false;
}

lvl = idx => {
  const lvls = ['easy', 'normal', 'impossible'];
  lvls.forEach(level => {
    $('.tic-tac-toe').classList.remove(level);
    $('.controls .'+level).classList.remove('active');
  })
  $('.tic-tac-toe').classList.add(lvls[idx]);
  $('.controls .'+lvls[idx]).classList.add('active');
}
      </script>
</body>
</html>

11. By SRoy

Made by SRoy. AI Tic tac Toe game. You can choose the first move or pass it to the AI, to start the game click the ‘Start’ button. ( Source )

<html>
    <head>
        <style>
            body {
    background: linear-gradient(magenta, orange, purple);
    color: cyan;
    text-shadow: 0pt 0pt 20pt blue;
}

button {
    font-size: 20pt;
    height: 50pt;
    width: 50pt;
    background: radial-gradient(magenta, purple);
    color: yellow;
    text-shadow: 0pt 0pt 3pt black;
}
            </style>
    </head>
<body>
<center><pre>

<h1>TIC TAC TOE</h1>
<button id="a00" onclick="f(0,0)"> </button><button id="a01" onclick="f(0,1)"> </button><button id="a02" onclick="f(0,2)"> </button>
<button id="a10" onclick="f(1,0)"> </button><button id="a11" onclick="f(1,1)"> </button><button id="a12" onclick="f(1,2)"> </button>
<button id="a20" onclick="f(2,0)"> </button><button id="a21" onclick="f(2,1)"> </button><button id="a22" onclick="f(2,2)"> </button><br>
<button id="gmb" onclick="gcntrl()" style="background: red; color: white; font-size: 15pt; height: 25pt; width: 60pt">START</button>

<h2 id=status></h2></pre>
</center>
<script>
    var trn=0;    // No. of turns
var ch1,ch2;    // Characters 'x' & 'o'
var g=false;    // Whether the game is being played
var win=0;    // Decides who won
var a=new Array();    // The gameboard
a[0]=new Array();
a[1]=new Array();
a[2]=new Array();

function f(r,c)    // For user's turn
{
    if(g)
        if(a[r][c]==0)
        {
            a[r][c]=1;
            trn++;
            set();
            check();
            if(g)
                autogame();
        }
}

function set()    // Draws the gameboard
{
     for(i=0;i<3;i++)
        for(j=0;j<3;j++)
            if(a[i][j]==1)
                document.getElementById("a"+i+j).innerHTML=ch1;
            else if(a[i][j]==-1)
                document.getElementById("a"+i+j).innerHTML=ch2;
            else
                document.getElementById("a"+i+j).innerHTML=" ";
}

function autogame()    // CPU's turn
{
    var r,c,i,j;
    var x;
    for(i=0;i<3;i++)        // Rows
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[i][j];
        if(x==-2)
            for(j=0;j<3;j++)
                if(a[i][j]==0)
                {
                    a[i][j]=-1;
                    trn++;
                    set();
                    check();
                    return;
                }
    }
    for(i=0;i<3;i++)        // Columns
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[j][i];
        if(x==-2)
            for(j=0;j<3;j++)
                if(a[j][i]==0)
                {
                    a[j][i]=-1;
                    trn++;
                    set();
                    check();
                    return;
                }
    }
    x=0;
    for(i=0;i<3;i++)        // Diagonal 1
        x=x+a[i][i];
    if(x==-2)
        for(i=0;i<3;i++)
            if(a[i][i]==0)
            {
                a[i][i]=-1;
                trn++;
                set();
                check();
                return;
            }
    x=0;
    for(i=0;i<3;i++)        // Diagonal 2
        x=x+a[i][2-i];
    if(x==-2)
        for(i=0;i<3;i++)
            if(a[i][2-i]==0)
            {
                a[i][2-i]=-1;
                trn++;
                set();
                check();
                return;
            }
    // Check User's
    for(i=0;i<3;i++)        // Rows
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[i][j];
        if(x==2)
            for(j=0;j<3;j++)
                if(a[i][j]==0)
                {
                    a[i][j]=-1;
                    trn++;
                    set();
                    check();
                    return;
                }
    }
    for(i=0;i<3;i++)        // Columns
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[j][i];
        if(x==2)
            for(j=0;j<3;j++)
                if(a[j][i]==0)
                {
                    a[j][i]=-1;
                    trn++;
                    set();
                    check();
                    return;
                }
    }
    x=0;
    for(i=0;i<3;i++)        // Diagonal 1
        x=x+a[i][i];
    if(x==2)
        for(i=0;i<3;i++)
            if(a[i][i]==0)
            {
                a[i][i]=-1;
                trn++;
                set();
                check();
                return;
            }
    x=0;
    for(i=0;i<3;i++)        // Diagonal
        x=x+a[i][2-i];
    if(x==2)
        for(i=0;i<3;i++)
            if(a[i][2-i]==0)
            {
                a[i][2-i]=-1;
                trn++;
                set();
                check();
                return;
            }
    r=(Math.floor(Math.random()*10))%3;
    c=(Math.floor(Math.random()*10))%3;
    if(a[r][c]==0)
    {
        a[r][c]=-1;
        trn++;
    }
    else
        autogame();
    set();
    check();
}

function check()        // Checks if anybody won
{
    var i,j;
    var x;
    for(i=0;i<3;i++)        // Rows
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[i][j];
        if(x==3)
        {
            win=1;
            gcntrl();
        }
        else if(x==-3)
        {
            win=2;
            gcntrl();
        }
    }
    for(i=0;i<3;i++)        // Columns
    {
        x=0;
        for(j=0;j<3;j++)
            x=x+a[j][i];
        if(x==3)
        {
            win=1;
            gcntrl();
        }
        else if(x==-3)
        {
            win=2;
            gcntrl();
        }
    }
    x=a[0][0]+a[1][1]+a[2][2];        // Diagonal 1
    if(x==3)
    {
        win=1;
        gcntrl();
    }
    else if(x==-3)
    {
        win=2;
        gcntrl();
    }
    x=a[0][2]+a[1][1]+a[2][0];        // Diagonal 2
    if(x==3)
    {
        win=1;
        gcntrl();
    }
    else if(x==-3)
    {
        win=2;
        gcntrl();
    }
    if(trn==9)
        gcntrl();
}

function gcntrl()        // Function of the red button, controls the game
{
    if(!g)
    {
    a=[[0,0,0],[0,0,0],[0,0,0]];
    set();
    document.getElementById("status").innerHTML="";
    var x=confirm("Do you want to take the first move?\nIf yes, press \"OK\"\nPress \"Cancel\" to pass the move.");
        var pr;
        if(x)
        {
            ch1="x";
            ch2="o";
            pr="yours";
        }
        else
        {
            ch2="x";
            ch1="o";
            pr="mine";
            autogame();
        }
        alert("First move is "+pr+"\nYour symbol "+ch1+"\nMy symbol "+ch2+"\nPress \"OK\"");
        document.getElementById("gmb").innerHTML="RESET";
        g=true;
    }
    else
    {
        document.getElementById("gmb").innerHTML="START";
        if(win==0)
        {
            if(trn==9)
                document.getElementById("status").innerHTML="Game tied!";
            else
                document.getElementById("status").innerHTML="Game terminated!";
        }
        else if(win==1)
            document.getElementById("status").innerHTML="Congratulations! you won!";
        else
            document.getElementById("status").innerHTML="You lost!";
        win=0;
        g=false;
        trn=0;
    }
}

alert("Please upvote it if you like it...\n\nPress \"OK\", then press the \"START\" (red) button to play...")

    </script>
</body>
</html>

12. By M Bima Y

Made by M Bima Y. A simple 2 Player tic tac toe game, the game also keep tracks of the previous wins. ( Source )

<!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">
  <title>Tic Tac Toe Game</title>
  <!-- Sweetalert2 -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js" integrity="sha256-2iFgzMziCroYT0IkthOS8usgi+KXxOiA5tvNCMyh984=" crossorigin="anonymous"></script>
  <!-- CSS bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <!-- JavaScript Bootstrap -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="style.css">
  <link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon" />
<style>
    .game-container {
  grid-template-columns: auto auto auto;
  max-width: 400px;
}

.game {
  border: 1px solid #000;
  height: 110px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.x-shape, .o-shape {
  position: absolute;
  font-size: 45px;
  font-weight: 300;
}

.x-shape {
  color: #FF3C3C;
}

.o-shape {
  color: #3C4FFF;
}

.turn-text {
  font-size: 20px;
}

.turn-value {
  font-size: 25px;
}

.score {
  font-size: 24px;
}

.score span {
  padding: 0 4px;
}

    </style>
</head>
<body>
  <div class="title-container container-fluid p-2 mt-4 mb-4 d-flex justify-content-center">
    <h1 class="title">Tic Tac Toe (2 Player)</h1>
  </div>
  <div class="score-container container-fluid d-flex justify-content-center">
    <div class="score container-sm d-flex justify-content-center">
      <span class="red-score value-score text-danger">0</span>
      <span>:</span>
      <span class="blue-score value-score text-primary">0</span>
    </div>
  </div>
  <div class="main-container container-fluid mt-5 mb-5">
    <div class="game-container container-sm d-grid">
      <div class="game game-1"></div>
      <div class="game game-2"></div>
      <div class="game game-3"></div>
      <div class="game game-4"></div>
      <div class="game game-5"></div>
      <div class="game game-6"></div>
      <div class="game game-7"></div>
      <div class="game game-8"></div>
      <div class="game game-9"></div>
    </div>
    <div class="btn-container d-flex justify-content-center mt-5 mb-5">
      <button class="reset-btn btn btn-warning text-white">Reset</button>
    </div>
  </div>
  <div class="info-container container-fluid pt-2 pb-2">
    <div class="turn-container container"><span class="turn-text">Turn: </span><span class="turn-value"></span></div>
  </div>
  <script>
const score = {
  htmls: document.querySelectorAll(".value-score"),
  red: 0,
  blue: 0,
  add(winner=""){
    if(!winner) return;
    this[winner]++;
    this.display();
  },
  
  display(){
    let scores = [this.red, this.blue];
    this.htmls.forEach((html, i) => {
      html.innerHTML = scores[i];
    });
  }
};

const turn = {
  html: document.querySelector(".turn-value"),
  color: {
    red: "#FF3C3C",
    blue: "#3C4FFF"
  },
  options: {
    style: {
      color: ""
    },
    innerHTML: ""
  },
  
  getColor(value=""){
    let color = value === "x" ? this.color.red :
    value === "o" ? this.color.blue : "#000";
    return color;
  },
  
  getOpposite(value=""){
    let opposite = value === "x" ? "o" :
    value === "o" ? "x" : "";
    return opposite;
  },
  
  set(value=""){
    let color = this.getColor(value);
    this.options.style.color = color
    this.options.innerHTML = value;
    this.display();
  },
  
  change(value=""){
    let opposite = this.getOpposite(value);
    let color = this.getColor(opposite);
    this.options.style.color = color;
    this.options.innerHTML = opposite;
    this.display();
  },
  
  display(){
    this.html.style.color = this.options.style.color;
    this.html.innerHTML = this.options.innerHTML;
  }
};

// Main object
const game = {
  squares: document.querySelectorAll(".game"),
  fields: [],
  value: "x",
  winner: "",
  paused: false,
  display(){
    this.squares.forEach((square, i) => {
      let field = this.fields[i];
      square.innerHTML = this.getShape(field);
    });
  },
  
  async displayAlert(title="", text="", icon=""){
    await Swal.fire({
      title,
      text,
      icon
    });
  },
  
  getWinner(value="", fields=[]){
    let filtered = fields.filter((field, i) => {
      return value === field;
    });
    let minimumPassed = filtered.length >= 3;
    if(!(value && minimumPassed)){
      return false;
    }
    
    const getIndexes = (value="", fields=[]) => {
      let output = [];
      fields.forEach((field, i) => {
        if(value === field){
          output.push(i);
        }
      });
      return output;
    };
    
    const includeAll = (indexes=[], array=[]) => {
      for(let i = 0; i < array.length; i++){
        let nums = [];
        for(let j = 0; j < array[i].length; j++){
          let found = indexes.findIndex((n) => {
            return n === array[i][j];
          });
          let bool = found !== -1;
          nums.push(Number(bool));
        }
        let foundZero = nums.findIndex(n => n === 0);
        if(foundZero !== -1){
          continue;
        }
        return true;
      }
      return false;
    };
    
    const checkWinner = (value="") => {
      let winnerPosition = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6]
      ];
      let indexes = getIndexes(value, fields);
      let isIncludeAll = includeAll(indexes, winnerPosition);
      return isIncludeAll ? this.getColorName(value) : "";
    };
    
    return checkWinner(value)
  },
  
  getColorName(value=""){
    return value === "x" ? "Red" :
    value === "o" ? "Blue" : "";
  },
  
  getShape(value){
    let xShapeClassName = "x-shape";
    let oShapeClassName = "o-shape";
    
    let xShape = `<span class="${xShapeClassName}">x</span>`;
    let oShape = `<span class="${oShapeClassName}">o</span>`;
    
    return value === "x" ? xShape
    : value === "o" ? oShape
    : "";
  },
  
  isDraw(){
    let filteredFields = this.fields.filter((field, i) => {
      return field != undefined;
    });
    return filteredFields.length === 9;
  },
  
  async add(value, position){
    if(this.fields[position] || this.paused){
      return false;
    }
    this.fields[position] = value;
    turn.change(this.value);
    this.display();
    this.winner = this.getWinner(this.value, this.fields);
    if(this.winner){
      this.paused = true;
      score.add(this.winner.toLowerCase());
      await this.displayAlert(`${this.winner} won!`, "", "success");
      return false;
    }
    if(this.isDraw()){
      this.paused = true;
      await this.displayAlert("Draw!");
      return false;
    }
    this.value = this.value === "x" ? "o" : "x";
  },
  
  reset(){
    if(!this.fields.length) return;
    this.fields = [];
    this.value = "x";
    this.winner = "";
    this.paused = false;
    turn.set(this.value);
    this.display();
  },
  
  init(){
    const resetBtn = document.querySelector(".reset-btn");
    
    resetBtn.addEventListener("click", () => {
      this.reset();
    });
    
    this.squares.forEach((square, i) => {
      square.addEventListener("click", () => {
        this.add(this.value, i);
      });
    });
  }
};

window.addEventListener("load", () => {
  game.init();
  turn.set("x");
});

  </script>
</body>
</html>

13. By Micah Meadows

Made by Micah Meadows. Two player Tic tac Toe game. ( Source )

<!DOCTYPE html>
<html>
	<head>
		<title>Page Title</title>
        <style>
            body {
	background-color: grey;
	max-height: 100%;
	max-width: 100%;
}

table button{
	background-color: white;/* Green */
	border: none;
	color: black;
	
	text-decoration: none;
	display: inline-block;
	font-size: 40px;
	width: 100px;
	height: 100px;
	text-align: center;
}

#resetbtn, button
{
	
	background-color: white;/* Green */
	border: none;
	color: black;
	
	text-decoration: none;
	display: inline-block;
	font-size: 35px;
	width: 200px;
	height: 50px;
	text-align: center;
	border: 3px solid black;
	position: relative;
	
}

#resetbtn h1{
	
	
}

.btnbox{
	
	position: relative;
	margin-left: 100px;
}

table{
	position: relative;
	max-height: 100%;
	height: auto;
	top: 0px;
	margin-left: 40px;
	background-color: black;
}

h1{
	position: relative;
	top: 10px;
	text-align: center;
}
            </style>
	</head>
	<body onload="onStart()">
	
	<table>
		<tr id="top-row">
			<td onclick="chose(0)">
			<button id="tl">tl</button></td>
			
			<td onclick="chose(1)">
			<button id="tc">tc</button></td>
			
			<td onclick="chose(2)">
			<button id="tr">tr</button></td>
		</tr>
		
		<tr id="mid-row">
			<td onclick="chose(3)">
			<button id="ml">ml</button></td>
			
			<td onclick="chose(4)">
			<button id="mc">mc</button></td>
			
			<td onclick="chose(5)">
			<button id="mr">mr</button></td>
		</tr>
		
		<tr id="bot-row">
			<td onclick="chose(6)">
			<button id="bl">bl</button></td>
			
			<td onclick="chose(7)">
			<button id="bc">bc</button></td>
			
			<td onclick="chose(8)">
			<button id="br">br</button></td>
		</tr>
		
	</table>
	
	<h1 id="result"> Player 1 Wins! </h1>
	<div class="btnbox">
	<button id="resetbtn" onclick="resetGame()">RESET</button>
	</div>
    <script>
        var player = 1;
var token = ["x", "o"];
var winner = '';
var alerted = 0;

var resultTxt;

var topL;
var topC;
var topR;
var midL;
var midC;
var midR;
var botL;
var botC;
var botR;

var resetBtn;

var board = ["", "", "", "", "", "", "", "", ""];

var numblank = board.length;

var solution = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[6,4,2]];
/*
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
*/

function onStart()
{
	resetBtn = document.getElementById('resetbtn');
	resultTxt = document.getElementById('result');
	topL = document.getElementById('tl');
	topC = document.getElementById('tc');
	topR = document.getElementById('tr');
	
	midL = document.getElementById('ml');
	midC = document.getElementById('mc');
	midR = document.getElementById('mr');
	
	botL = document.getElementById('bl');
	botC = document.getElementById('bc');
	botR = document.getElementById('br');
	
	topL.innerHTML = "";
	topC.innerHTML = "";
	topR.innerHTML = "";
	
	midL.innerHTML = "";
	midC.innerHTML = "";
	midR.innerHTML = "";
	
	botL.innerHTML = "";
	botC.innerHTML = "";
	botR.innerHTML = "";
	
	resultTxt.innerHTML = "";
	resetBtn.style.visibility ='hidden';
}

function chose(selection)
{
	if(board[selection] == ''){
		board[selection] = token[player-1];
		
	}
	if(alerted)
	{
		return;
	}
	switch (selection){
		case 0:
			if(topL.innerHTML == ''){
				topL.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 1:
			if(topC.innerHTML == ''){
				topC.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 2:
			if(topR.innerHTML == ''){
				topR.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 3:
			if(midL.innerHTML == ''){
				midL.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 4:
			if(midC.innerHTML == ''){
				midC.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 5:
			if(midR.innerHTML == ''){
				midR.innerHTML = token[player-1];
				numblank--
				checkWin();
				swap();
			}
			break;
			
		case 6:
			if(botL.innerHTML == ''){
				botL.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 7:
			if(botC.innerHTML == ''){
				botC.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
			
		case 8:
			if(botR.innerHTML == ''){
				botR.innerHTML = token[player-1];
				numblank--;
				checkWin();
				swap();
			}
			break;
	}
	
}

function swap(){
	if(player == 1)
	{
		player = 2;
	}
	else if(player == 2)
	{
		player = 1;
	}
}

function checkWin()
{
	var a = 0;
	var b = 0;
	var c = 0;
	
	
	for(i = 0; i < solution.length; i++)
	{
		a = solution[i][0];
		b = solution[i][1];
		c = solution[i][2];
	
	if(board[a] == board[b] && board[a] == board[c])
	{
		if(board[a] != '' &&
		 board[b] != '' &&
		  board[c] != '')
		  { 
		  	if(player == 1){
		  		winner = 'X';
		  	}
		  	else{
		  		winner = 'O';
		  	}
			//alert("game over " +winner+ " won ");
			resultTxt.innerHTML = "Player " + player + " won the game!";
			resetBtn.style.visibility='visible';
			alerted = 1;
			}
	}
	}
	
	if(numblank <= 0 && alerted == 0)
	{
		//alert("Cat!");
		resultTxt.innerHTML = "Tied :("
		resetBtn.style.visibility='visible';
		alerted = 1;
	}
	
}

function resetGame(){
	alerted = 0;
	player = 1;
	topL.innerHTML = "";
	topC.innerHTML = "";
	topR.innerHTML = "";
	
	midL.innerHTML = "";
	midC.innerHTML = "";
	midR.innerHTML = "";
	
	botL.innerHTML = "";
	botC.innerHTML = "";
	botR.innerHTML = "";
	
	board = ["", "", "", "", "", "", "", "", ""];
	
	resultTxt.innerHTML = "";	
	resetBtn.style.visibility = 'hidden'
	numblank = 9;
}
        </script>
	</body>
</html>

14. By SR

Made by SR. A two by two tic tac toe game made using JavaScript. ( Source )

<!-- for fun only -->
<html>
    <head>
        <style>
            *{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    border: 1px solid black;
}

body {
    background: #E9F7CA;
    font-size: 50px;
}

#board {
    position: absolute;
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: table;
    width: 200px;
    height: 200px;
}

#board > div {
    display: table-row;
}
/*selection of child of child of board*/
#board > div > div {
    display: table-cell;
    background: #F7D488;
    text-align: center;
    vertical-align: middle;
    width:100px;
    height:100px;
}

            </style>
    </head>
    <body>
<div id="board">
    <div>
        <div></div>
        <div></div>
    </div>
    <div>
        <div></div>
        <div></div>
    </div>
</div>
<script>
    //going to beat minimax algo 

// whn documnt is ready
window.onload =() =>{
// all 4 tiles/div.
    cells = document.querySelectorAll("#board >div>div");
    //first player is cpu;
    player = "cpu";
    // 4 div elements 0-3
    cell_index = [0, 1, 2 , 3];
    //counting moves
    moveCount = 0;
    
//when game ends
const end = ()=>{
    console.log("game over, x wins")
    //remove event listener from all 4 divs
     for( let i of cells){
        i.removeEventListener("click", playermove);
           }}
// cpu move
    const move =()=>{
    //to select from cell_index array 
        rand = Math.floor(Math.random() * cell_index.length);
        // html div object/a cell from cells 
        mark = cells[cell_index[rand]];
          //if cou's turn and place(div) we picked us not already marked
        if(player == "cpu" && mark.innerText ==''){
            mark.innerText = "x";
            //now set value for next move (users)
            player = "user"
            //remove index after writing to tht area
            cell_index.splice(rand,1);
            moveCount++;
            }else if(moveCount<2){
                cell_index.splice(rand,1)
                move();}
                //we ll not check if this or that is winner as cpu is sleys going to win, lol 
       if(moveCount >=2){
           end()
          }   
    }
    //player move ehn click on..
    const playermove = (e) =>{
            if(e.target.innerText == '' && player == "user"){
                e.target.innerText = 0;
                player = "cpu";
                move();
                }}
    // adding evnt listelner to all tiles
    for( let i of cells){
        i.addEventListener("click", playermove)
    }
    // to init first move by cpu
    setTimeout( move, 300);     
}
    </script>
    </body>
    <html>

15. By Alquen

Made by Alquen. ( Source )

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Tic Tac Toe</title>
    <link rel="stylesheet" href="style.css" />
    <link href="https://fonts.googleapis.com/css?family=Rock+Salt" rel="stylesheet">
    <script src="app.js"></script>
    <style>
        *{
  margin: 0;
  padding: 0;
}

body{
  background-color: papayawhip;
}

.box{
  width: 33.33%;
  height: 100%;
  text-align: center;
  font-size: 120px;
  border: solid;
}

#main{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: grey;
  margin: 20px auto 0 auto;
  font-family: 'Rock Salt', cursive;
}

.column{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 33.33%;
  flex-direction: row;
}

#sup{
  margin: 50px auto 0 auto;
  left: 0;
  right: 0;
  text-align: center;
  background-color: rgba(255, 100, 0, 0.7);
  position: absolute;
  padding: 20px;
  font-family: Arial, Helvetica, sans-serif;
  display: none;
  color: white;
}

#restart{
  text-align: center;
  margin-bottom: 30px;
  padding: 10px;
  background-color: burlywood;
}

#score{
  text-align: center;
}

input{
  margin: 10px;
  width: 50px;
  height: 20px;
  text-align: center;
  font-size: 12pt;
}
        </style>
  </head>
  <body>
    <div id="score">
      Win: <input id="win" value="0" disabled />
      Loss: <input id="loss" value="0" disabled />
      Tie: <input id="tie" value="0" disabled />
    </div>
    <div id="sup">
      <button id="restart">Restart</button>
      <p id="disp"></p>
    </div>
    <div id="main">
      <div class="column">
        <div id="0" class="box"></div>
        <div id="1" class="box"></div>
        <div id="2" class="box"></div>
      </div>
      <div class="column">
        <div id="3" class="box"></div>
        <div id="4" class="box"></div>
        <div id="5" class="box"></div>
      </div>
      <div class="column">
        <div id="6" class="box"></div>
        <div id="7" class="box"></div>
        <div id="8" class="box"></div>
      </div>
    </div>
    <script>
        "use strict"
const human = "O";
const enemy = "X";
let firstMover;
//Create an array that contains 0 to 8
let globalBoard = [0,1,2,3,4,5,6,7,8];
let gameCounter = 0;
const winCombination = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [6, 4, 2]
]

window.onload = function() {
  alert("It's lag at first move because of too much recursion, and this will be fix soon")

  //Setting the size of the main box by globally adjusting if phone or desktop.
  const winWidth = window.innerWidth;
  const winHeight = window.innerHeight;
  const boxClass = document.getElementsByClassName("box");

  //If the window's width is larger, the main box should depend on the window's height to properly fit;
  if (winWidth >= winHeight){
    document.getElementById("main").style.width = (winHeight * 0.8) + "px"; 
    document.getElementById("main").style.height = (winHeight * 0.8) + "px";
    Array.prototype.forEach.call(boxClass, function(e){ e.style.fontSize = (winHeight * 0.11) + "px"});
    document.getElementById("sup").style.width = (winHeight * 0.3) + "px";
    document.getElementById("sup").style.height = (winHeight * 0.2) + "px";
    document.getElementById("sup").style.fontSize = (winHeight * 0.04) + "pt";
    document.getElementById("restart").style.width = (winHeight * 0.15) + "px";
    document.getElementById("restart").style.height = (winHeight * 0.08) + "px";
  }
  else{
    //Beware of the spelling of width
    document.getElementById("main").style.width = (winWidth * 0.8) + "px";
    document.getElementById("main").style.height = (winWidth * 0.8) + "px";
    Array.prototype.forEach.call(boxClass, function(e){ e.style.fontSize = (winWidth * 0.11) + "px"});
    document.getElementById("sup").style.width = (winWidth * 0.3) + "px";
    document.getElementById("sup").style.height = (winWidth * 0.2) + "px";
    document.getElementById("sup").style.fontSize = (winWidth * 0.04) + "pt";
    document.getElementById("restart").style.width = (winWidth * 0.20) + "px";
    document.getElementById("restart").style.height = (winWidth * 0.08) + "px";
  }

  //Add click listener to the restart button
  document.getElementById("restart").addEventListener("click", startGame)
  startGame();

  function startGame(){
    //Run through all the cells and add click listeners
    Array.prototype.forEach.call(boxClass, function(e){
      e.addEventListener("click", playerTurn);
      e.innerText = "";
      e.style.backgroundColor = "white";
    });
    //Reset the declaration of winners
    document.getElementById("sup").style.display = "none";
    //Reset the globalBoard to an array from 0-8
    globalBoard = [0,1,2,3,4,5,6,7,8];
    //Determine who to move first
    firstMove()
    gameCounter++;
  }
  
  function playerTurn(cell){
    //Called the turn function with the index of cell and the player
    turn(cell.target.id, human);
    if(!winCheck(globalBoard, human) && !tieCheck()){
      turn(enemyMove(), enemy);
    }
  }

  function randomMove(length){
    return Math.floor(Math.random() * length)
  }

  function firstMove(){
  //If gameCounter is odd, the enemy attack first
  if(gameCounter % 2 == 1){
    firstMover = enemy;
    //The first move is random to avoid long recursion (at minimax)
    turn(randomMove(globalBoard.length), enemy);
  }
  else{
    firstMover = human;
  }
}

  function turn(cellID, player){
    //Set the player's character to the globalBoard and set the main box according to the move
    globalBoard[cellID] = player;
    document.getElementById(cellID).innerText = player;
    document.getElementById(cellID).removeEventListener("click", playerTurn);
    //Get the state of winning or tie
    let winState = winCheck(globalBoard, player);
    let tieState = tieCheck();
    if(winState) gameOver(winState);
    else if(tieState) gameOver(tieState);
  }

  function winCheck(board, player){
    //The collection of player's moves
    let combination = [];
    for(let i = 0; i < board.length; i++){
      if(board[i] === player){
        combination.push(i);
      }
    }
    //Run through the winCombination and check if all elements are present via Array.prototype.every() function
    for(let j = 0; j < winCombination.length; j++){
      if(winCombination[j].every(function(comb){
        return combination.indexOf(comb) != -1;
      })){
        return {toBeDisplay: winCombination[j], player: player, message: player + " wins"}
      }
    }
    return false;
  }

  function gameOver(state){
    //Get the winner's combination and the winner as arguments then display
    let color;
    //Human wins
    if(state.player == human){
      color = "red";
      document.getElementById("win").value++;
    }
    //Enemy wins
    else if(state.player == enemy){
      color = "blue";
      document.getElementById("loss").value++;
    }
    //Tie
    else{
      color = "green";
      document.getElementById("tie").value++;
    }
    Array.prototype.forEach.call(state.toBeDisplay, function(e){ document.getElementById(e).style.backgroundColor = color })
    //Remove the listener to make unclickable
    Array.prototype.forEach.call(boxClass, function(e){
      e.removeEventListener("click", playerTurn);
    });
    //Declare winners
    document.getElementById("sup").style.display = "block";
    document.getElementById("disp").innerText = state.message;
  }

  function emptyCells(){
    let tempBoard = [];
    let i = 0;
    //If the type of the cell is still a number (no player move in that cell), collect it as empty cells
    while(i < globalBoard.length){
      if(typeof globalBoard[i] === "number"){
        tempBoard.push(globalBoard[i])
      }
      i++;
    }
    return tempBoard;
    //Higher order function implementation
    //return globalBoard.filter(function(s){return typeof s === "number"});
  }

  
  function tieCheck(){
    if(emptyCells().length == 0){
      return {toBeDisplay: [0,1,2,3,4,5,6,7,8], player: undefined, message: "It's a tie"};
    }
    return false;
  }

  function enemyMove(){
    //Just a random mover enemy
    //return emptyCells()[Math.floor(Math.random() * emptyCells().length)];
    return minimax(globalBoard, enemy).index;
  }

  function minimax(newBoard, player){
    //Check for available spots
    let availableSpots = emptyCells();

    //Terminal State
    if(winCheck(newBoard, human)){
      return {score : -10};
    }
    else if(winCheck(newBoard, enemy)){
      return {score: 10};
    } 
    else if(tieCheck()){
      return {score : 0};
    }

    //Loop through all available spots 
    let moves = [];
    for(let i = 0; i < availableSpots.length; i++){
      let move = {};
      move.index = newBoard[availableSpots[i]];
      //Assign the spots to the player
      newBoard[availableSpots[i]] = player

      //If the mover is the enemy, the human should move after
      if(player == enemy){
        move.score = minimax(newBoard, human).score;
      }
      else if(player === human){
        move.score = minimax(newBoard, enemy).score;
      }
      //Return to the normal state without assigning
      newBoard[availableSpots[i]] = move.index
      //Collect the score and the index
      moves.push(move);
    }

    let bestMove;
    //If the player is enemy get the biggest score
    if(player == enemy){
      let bestScore = -Infinity;
      for(let i = 0; i < moves.length; i++){
        if(moves[i].score > bestScore){
          bestScore = moves[i].score;
          bestMove = i;
        }
      }
    }
    //If the player is human get the lowest score
    else if(player == human){
      let bestScore = Infinity;
      for(let i = 0; i < moves.length; i++){
        if(moves[i].score < bestScore){
          bestScore = moves[i].score;
          bestMove = i;
        }
      }
    }
    return moves[bestMove];
  }
}
        </script>
  </body>
</html>

16. By Rull Deef 🐺

Made by Rull Deef 🐺. Two player game that runs only once, so you need to run the program again to play another game. ( Source )

<!DOCTYPE html>
<html>
  <head>
    <title>Tic tac toe - React practice</title>
    <script nomodule src="https://unpkg.com/browser-es-module-loader/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader"></script>
  <style>
      #root, .game {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

h1 {
    text-align: center;
    color: #333;
}

.cell {
    width: 25vmin;
    height: 25vmin;
    margin: 1px;
    border: 1px solid #aaa;
    border-radius: 5px;
    box-sizing: border-box;
    box-shadow: 0 0 2px 1px #ddd;
    font-family: monospace;
    font-size: 15vmin;
    display: inline-flex;
    justify-content: center;
    align-items: center;
}

.board {
    display: grid;
    grid-template: ". . ." ". . ." ". . .";
}

.info {
    margin-top: 5vmin;
}
      </style>
        </head>
  <body>
    <div id="root"></div>
    <script>
        //</script><script type="module">

import htm from 'https://unpkg.com/htm?module'
import { React, ReactDOM } from 'https://unpkg.com/es-react-production'
const html = htm.bind(React.createElement)

function Cell(props) {
  return html`<div className="cell"
    onClick=${props.onClick}>${props.value}</div>`
}

class Board extends React.Component {
  handleClick(i) {
    const cells = this.props.cells.slice()
    cells[i] = this.props.nextX? "X" : "O"
  }
  render() {
    const cells = this.props.cells.map((cell, i) => {
      return html`<${Cell} key=${i} 
        value=${this.props.cells[i]}
        onClick=${()=>this.props.handle(i)}/>`
    })
    return html`<div className="board">${cells}</div>`
  }
}

class Game extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      cells: new Array(9).fill(null),
      nextX: true, winner: null
    }
  }
  getWinner() {
    const winpos = [
      [0,1,2],[3,4,5],[6,7,8],[0,3,6],
      [1,4,7],[2,5,8],[0,4,8],[2,4,6]]
    const cells = this.state.cells
    for(let pos of winpos) {
      let a, b, c; [a, b, c] = pos
      if(cells[a] && cells[a] == cells[b]
                  && cells[a] == cells[c])
        return cells[a]
    }
    return null
  }
  handleClick(i) {
    const cells = this.state.cells.slice()
    if(cells[i]) return
    const w = this.getWinner()
    if(!w) {
      cells[i] = this.state.nextX? "X" : "O"
      this.setState({cells, nextX: !this.state.nextX})
      setTimeout(() => {
        const u = this.getWinner()
        if(u) this.setState({winner: u})
      }, 1)
    } else this.setState({winner: w})
  }
  render() {
    let info = (this.state.nextX? "X" : "O")
      + "'s turn now!"
    if(this.state.winner)
      info = this.state.winner + " won!"
    return html`<div className="game">
      <h1>TIC TAC TOE GAME</h1>
      <${Board} cells=${this.state.cells} 
        nextX=${this.state.nextX} 
        handle=${this.handleClick.bind(this)}/>
      <small className="info">${info}</small>
    </div>`
  }
}

ReactDOM.render(
  html`<${Game}/>`,
  document.querySelector("#root")
)
        </script>
  </body>
</html>

17. By Nikky Amresh

Made by Nikky Amresh. The game has two modes, human vs human or human vs computer. ( Source )

<!DOCtype html>
<html>
    <head>
        <title>Tic Tac Toe</title>
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <style>
        body {
    background-color:#000;
}
h1{
   color:#4CAF50; 
  text-align:center;
  text-decoration:underline ;
}
.h1{
    position:fixed;
    top:180px;
    align:center;
}
#tt{
    position:fixed;
    color:#4CAF50;
    left:40%;
    top:330px;
}
#screen{
   position:fixed;
    width:100%;
    height:1000px;
    background-color:#0f0f0f;
    z-index:1;
    align:center;
}
select{
    background-color: #4CAF50;
    border: none;
    color: white;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
    position:absolute;
    top:300px;
    left:30%;
    height:40px;
    width:40%;
}
input{
    width:80px;
    height:80px;
    background-color:#4CAF50;
    color:#fff;
    font-size:50px;
}
#reset{
    position:fixed;
    width:100%;
    opacity:0;
    display:none;
    background-color:#000;
    height:1000px;
}
.vote{
    color:#fff;
    position:fixed;
    bottom:15px;
    font-size:20px;
    font-style: oblique;
}
.btn{
    border: none;
    position:fixed;
    color: white;
    left:30%;
    display:none;
    padding: 15px 32px;
    width:150px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
    height:40px;
    font-size:20px;
}
.w1{
    top:350px;
    background-color: #0cf;
    color:#000;
   width:200px;   
   left:20%;
}
.p1{
position:fixed;
 color:#4CAF50;
 left:10px;
 top:330px;
 display:none;
} 
.p2{
    position:fixed;
    color:#4CAF50;
    right:10px;
    top:330px;
}
.r{
     z-index:1;
    top:400px;
    background-color: #4CAF50;
}
.l{
    top:350px;
    background-color: red;
} 
.w{
    top:350px;
    background-color: #0cf;
      color:#000;
}
.vote a{
    color:#4CAF50;
}
.d{
    z-index:1;
    top:350px;
    background-color: #fff;
    color:#000;
}
        </style>
    </head>
    <body onload="mode();"> 
     <div id="screen">
         <h1 class="h1" align="center">Please Choose Game Mode</h1>
         <select id="mode">
               <option Selected>Choose Mode</option>
               <option value="1">Computer Vs Human</option>
               <option value="2">Human Vs Human</option>
               <option disabled value="3">Computer Vs Computer (comming soon)</option>
            </select>
    </div>
    <h1>Tic Tac Toe </h1>
    <div id="reset"></div>
   <button class="btn d" id="draw">Draw!</button>
    <button class="btn l" id="loss">You Lost!</button>
     <button class="btn w" id="win">You Won!</button>
       <button class="btn w1" id="p2win">Player 1 (O)Won!</button>
       <button class="btn w1" id="p1win">Player 2 (X)Won!</button>
    <button class="btn r" id="resetbtn" onclick="resetclick()">Reset</button>    
    <div id="turn" style="display:none;">
    <span id="p1" class="p1">Player2's (X)Turn</span>
    <span id="p2" class="p2">Player1's (O)Turn</span></div>
    <div id="turnc" style="display:none;">
    <span id="ct" class="p1">Computer's' Turn</span>
    <span id="yt" class="p2">Your Turn</span></div>
    <span id="tt"></span>
   <form  align="center" >
<input type="button"  id="b1" value="     " onclick="btn1(mode)">
<input  type="button" id="b2" value="     " onclick="btn2(mode)">
<input type="button" id="b3"  value="     " onclick="btn3(mode)"><br />
<input type="button" id="b4"  value="     " onclick="btn4(mode)">
<input type="button" id="b5"  value="     " onclick="btn5(mode)">
<input type="button" id="b6"  value="     " onclick="btn6(mode)"><br />
<input type="button"  id="b7"  value="     " onclick="btn7(mode)">
<input type="button"  id="b8"  value="     " onclick="btn8(mode)">
<input type="button" id="b9"   value="     " onclick="btn9(mode)">
</form>
<marquee direction="left" scrollamount="9" class="vote">if you really enjoyed my code. Then please support me <a onclick="alert('Thanks for your support πŸ˜ŠπŸ™πŸ»πŸ‘πŸ»')" href="https://www.sololearn.com/Discuss/578541/">here</a> </marquee>
    <script>
        function turnp(){$("#tt").html("Total Moves: "+moveCount),mode==2?$("#turn").show():$("#turn").hide();mode==1?$("#turnc").show():$("#turnc").hide();0==turn?($("#p2").show(),$("#p1").hide()):($("#p1").show(),$("#p2").hide());0==turn?($("#yt").show(),$("#ct").hide()):($("#ct").show(),$("#yt").hide())}function mode(){$("#mode").change(function(){$("#screen").hide(),mode=$("#mode").val(),mode==2?$("#turn").show():$("#turn").hide();mode==1?$("#turnc").show():$("#turnc").hide()})}function  btn1(){"     "==$("#b1").val()&&0==turn&&1==mode?($("#b1").attr("value"," X "),sqr1T=1,turn=1,turrn(),check()):"     "==$("#b1").val()&&1==turn&&2==mode?($("#b1").attr("value"," X "),sqr1T=1,turn=0,turrn(),p1c()):"     "==$("#b1").val()&&0==turn&&2==mode&&($("#b1").attr("value"," O "),sqr1T=1,turn=1,turrn(),p1c()),drawCheck()}function btn2(){"     "==$("#b2").val()&&0==turn&&1==mode?($("#b2").attr("value"," X "),sqr2T=1,turn=1,turrn(),check()):"     "==$("#b2").val()&&1==turn&&2==mode?($("#b2").attr("value"," X "),sqr2T=1,turn=0,turrn(),p1c()):"     "==$("#b2").val()&&0==turn&&2==mode&&($("#b2").attr("value"," O "),sqr2T=1,turn=1,turrn(),p1c()),drawCheck()}function btn3(){"     "==$("#b3").val()&&0==turn&&1==mode?($("#b3").attr("value"," X "),sqr3T=1,turn=1,turrn(),check()):"     "==$("#b3").val()&&1==turn&&2==mode?($("#b3").attr("value"," X "),sqr3T=1,turn=0,turrn(),p1c()):"     "==$("#b3").val()&&0==turn&&2==mode&&($("#b3").attr("value"," O "),sqr3T=1,turn=1,turrn(),p1c()),drawCheck()}function btn4(){"     "==$("#b4").val()&&0==turn&&1==mode?($("#b4").attr("value"," X "),sqr4T=1,turn=1,turrn(),check()):"     "==$("#b4").val()&&1==turn&&2==mode?($("#b4").attr("value"," X "),sqr4T=1,turn=0,turrn(),p1c()):"     "==$("#b4").val()&&0==turn&&2==mode&&($("#b4").attr("value"," O "),sqr4T=1,turn=1,turrn(),p1c()),drawCheck()}function btn5(){"     "==$("#b5").val()&&0==turn&&1==mode?($("#b5").attr("value"," X "),sqr5T=1,turn=1,turrn(),check()):"     "==$("#b5").val()&&1==turn&&2==mode?($("#b5").attr("value"," X "),sqr5T=1,turn=0,turrn(),p1c()):"     "==$("#b5").val()&&0==turn&&2==mode&&($("#b5").attr("value"," O "),sqr5T=1,turn=1,turrn(),p1c()),drawCheck()}function btn6(){"     "==$("#b6").val()&&0==turn&&1==mode?($("#b6").attr("value"," X "),sqr6T=1,turn=1,turrn(),check()):"     "==$("#b6").val()&&1==turn&&2==mode?($("#b6").attr("value"," X "),sqr6T=1,turn=0,turrn(),p1c()):"     "==$("#b6").val()&&0==turn&&2==mode&&($("#b6").attr("value"," O "),sqr6T=1,turn=1,turrn(),p1c()),drawCheck()}function btn7(){"     "==$("#b7").val()&&0==turn&&1==mode?($("#b7").attr("value"," X "),sqr7T=1,turn=1,turrn(),check()):"     "==$("#b7").val()&&1==turn&&2==mode?($("#b7").attr("value"," X "),sqr7T=1,turn=0,turrn(),p1c()):"     "==$("#b7").val()&&0==turn&&2==mode&&($("#b7").attr("value"," O "),sqr7T=1,turn=1,turrn(),p1c()),drawCheck()}function btn8(){"     "==$("#b8").val()&&0==turn&&1==mode?($("#b8").attr("value"," X "),sqr8T=1,turn=1,turrn(),check()):"     "==$("#b8").val()&&1==turn&&2==mode?($("#b8").attr("value"," X "),sqr8T=1,turn=0,turrn(),p1c()):"     "==$("#b8").val()&&0==turn&&2==mode&&($("#b8").attr("value"," O "),sqr8T=1,turn=1,turrn(),p1c()),drawCheck()}function btn9(){"     "==$("#b9").val()&&0==turn&&1==mode?($("#b9").attr("value"," X "),sqr9T=1,turn=1,turrn(),check()):"     "==$("#b9").val()&&1==turn&&2==mode?($("#b9").attr("value"," X "),sqr9T=1,turn=0,turrn(),p1c()):"     "==$("#b9").val()&&0==turn&&2==mode&&($("#b9").attr("value"," O "),sqr9T=1,turn=1,turrn(),p1c()),drawCheck()}function turrn(){sqr1=$("#b1").val(),sqr2=$("#b2").val(),sqr3=$("#b3").val(),sqr4=$("#b4").val(),sqr5=$("#b5").val(),sqr6=$("#b6").val(),sqr7=$("#b7").val(),sqr8=$("#b8").val(),sqr9=$("#b9").val()}function check(){" X "==sqr1&&" X "==sqr2&&" X "==sqr3?(wb(),reset()):" X "==sqr4&&" X "==sqr5&&" X "==sqr6?(wb(),reset()):" X "==sqr7&&" X "==sqr8&&" X "==sqr9?(wb(),reset()):" X "==sqr1&&" X "==sqr5&&" X "==sqr9?(wb(),reset()):" X "==sqr1&&" X "==sqr4&&" X "==sqr7?(wb(),reset()):" X "==sqr2&&" X "==sqr5&&" X "==sqr8?(wb(),reset()):" X "==sqr3&&" X "==sqr6&&" X "==sqr9?(wb(),reset()):" X "==sqr1&&" X "==sqr5&&" X "==sqr9?(wb(),reset()):" X "==sqr3&&" X "==sqr5&&" X "==sqr7?(wb(),reset()):(winCheck(),check2(),drawCheck())}function check2(){turrn(),drawCheck()," O "==sqr1&&" O "==sqr2&&" O "==sqr3?(lb() ,reset()):" O "==sqr4&&" O "==sqr5&&" O "==sqr6?(lb() ,reset()):" O "==sqr7&&" O "==sqr8&&" O "==sqr9?(lb() ,reset()):" O "==sqr1&&" O "==sqr5&&" O "==sqr9?(lb() ,reset()):" O "==sqr1&&" O "==sqr4&&" O "==sqr7?(lb() ,reset()):" O "==sqr2&&" O "==sqr5&&" O "==sqr8?(lb() ,reset()):" O "==sqr3&&" O "==sqr6&&" O "==sqr9?(lb() ,reset()):" O "==sqr1&&" O "==sqr5&&" O "==sqr9?(lb() ,reset()):" O "==sqr3&&" O "==sqr5&&" O "==sqr7&&(lb() ,reset())}function p1c(){" X "==sqr1&&" X "==sqr2&&" X "==sqr3?(p1w(),reset()):" X "==sqr4&&" X "==sqr5&&" X "==sqr6?(p1w(),reset()):" X "==sqr7&&" X "==sqr8&&" X "==sqr9?(p1w(),reset()):" X "==sqr1&&" X "==sqr5&&" X "==sqr9?(p1w(),reset()):" X "==sqr1&&" X "==sqr4&&" X "==sqr7?(p1w(),reset()):" X "==sqr2&&" X "==sqr5&&" X "==sqr8?(p1w(),reset()):" X "==sqr3&&" X "==sqr6&&" X "==sqr9?(p1w(),reset()):" X "==sqr1&&" X "==sqr5&&" X "==sqr9?(p1w(),reset()):" X "==sqr3&&" X "==sqr5&&" X "==sqr7?(p1w(),reset()):(p2c(),drawCheck())}function p2c(){turrn(),drawCheck()," O "==sqr1&&" O "==sqr2&&" O "==sqr3?(p2w(),reset()):" O "==sqr4&&" O "==sqr5&&" O "==sqr6?(p2w(),reset()):" O "==sqr7&&" O "==sqr8&&" O "==sqr9?(p2w(),reset()):" O "==sqr1&&" O "==sqr5&&" O "==sqr9?(p2w(),reset()):" O "==sqr1&&" O "==sqr4&&" O "==sqr7?(p2w(),reset()):" O "==sqr2&&" O "==sqr5&&" O "==sqr8?(p2w(),reset()):" O "==sqr3&&" O "==sqr6&&" O "==sqr9?(p2w(),reset()):" O "==sqr1&&" O "==sqr5&&" O "==sqr9?(p2w(),reset()):" O "==sqr3&&" O "==sqr5&&" O "==sqr7&&(p2w(),reset())}function drawCheck(){turnp(),turrn(),9==(moveCount=sqr1T+sqr2T+sqr3T+sqr4T+sqr5T+sqr6T+sqr7T+sqr8T+sqr9T)&&(reset(),db())}function winCheck(){check2()," O "==sqr1&&" O "==sqr2&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" O "==sqr2&&" O "==sqr3&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" O "==sqr4&&" O "==sqr5&&0==sqr6T&&1==turn?($("#b6").attr("value"," O "),sqr6T=1,turn=0):" O "==sqr5&&" O "==sqr6&&0==sqr4T&&1==turn?($("#b4").attr("value"," O "),sqr4T=1,turn=0):" O "==sqr7&&" O "==sqr8&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" O "==sqr8&&" O "==sqr9&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" O "==sqr1&&" O "==sqr5&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" O "==sqr5&&" O "==sqr9&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" O "==sqr3&&" O "==sqr5&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" O "==sqr7&&" O "==sqr5&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" O "==sqr1&&" O "==sqr3&&0==sqr2T&&1==turn?($("#b2").attr("value"," O "),sqr2T=1,turn=0):" O "==sqr4&&" O "==sqr6&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" O "==sqr7&&" O "==sqr9&&0==sqr8T&&1==turn?($("#b8").attr("value"," O "),sqr8T=1,turn=0):" O "==sqr1&&" O "==sqr7&&0==sqr4T&&1==turn?($("#b4").attr("value"," O "),sqr4T=1,turn=0):" O "==sqr2&&" O "==sqr8&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" O "==sqr3&&" O "==sqr9&&0==sqr6T&&1==turn?($("#b6").attr("value"," O "),sqr6T=1,turn=0):" O "==sqr1&&" O "==sqr5&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" O "==sqr4&&" O "==sqr7&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" O "==sqr5&&" O "==sqr8&&0==sqr2T&&1==turn?($("#b2").attr("value"," O "),sqr2T=1,turn=0):" O "==sqr6&&" O "==sqr9&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" O "==sqr1&&" O "==sqr4&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" O "==sqr2&&" O "==sqr5&&0==sqr8T&&1==turn?($("#b8").attr("value"," O "),sqr8T=1,turn=0):" O "==sqr3&&" O "==sqr6&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" O "==sqr1&&" O "==sqr9&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" O "==sqr3&&" O "==sqr7&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):computer(),check2()}function computer(){check2()," X "==sqr1&&" X "==sqr2&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" X "==sqr2&&" X "==sqr3&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" X "==sqr4&&" X "==sqr5&&0==sqr6T&&1==turn?($("#b6").attr("value"," O "),sqr6T=1,turn=0):" X "==sqr5&&" X "==sqr6&&0==sqr4T&&1==turn?($("#b4").attr("value"," O "),sqr4T=1,turn=0):" X "==sqr7&&" X "==sqr8&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" X "==sqr8&&" X "==sqr9&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" X "==sqr1&&" X "==sqr5&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" X "==sqr5&&" X "==sqr9&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" X "==sqr3&&" X "==sqr5&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" X "==sqr7&&" X "==sqr5&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" X "==sqr1&&" X "==sqr3&&0==sqr2T&&1==turn?($("#b2").attr("value"," O "),sqr2T=1,turn=0):" X "==sqr4&&" X "==sqr6&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" X "==sqr7&&" X "==sqr9&&0==sqr8T&&1==turn?($("#b8").attr("value"," O "),sqr8T=1,turn=0):" X "==sqr1&&" X "==sqr7&&0==sqr4T&&1==turn?($("#b4").attr("value"," O "),sqr4T=1,turn=0):" X "==sqr2&&" X "==sqr8&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" X "==sqr3&&" X "==sqr9&&0==sqr6T&&1==turn?($("#b6").attr("value"," O "),sqr6T=1,turn=0):" X "==sqr1&&" X "==sqr5&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" X "==sqr4&&" X "==sqr7&&0==sqr1T&&1==turn?($("#b1").attr("value"," O "),sqr1T=1,turn=0):" X "==sqr5&&" X "==sqr8&&0==sqr2T&&1==turn?($("#b2").attr("value"," O "),sqr2T=1,turn=0):" X "==sqr6&&" X "==sqr9&&0==sqr3T&&1==turn?($("#b3").attr("value"," O "),sqr3T=1,turn=0):" X "==sqr1&&" X "==sqr4&&0==sqr7T&&1==turn?($("#b7").attr("value"," O "),sqr7T=1,turn=0):" X "==sqr2&&" X "==sqr5&&0==sqr8T&&1==turn?($("#b8").attr("value"," O "),sqr8T=1,turn=0):" X "==sqr3&&" X "==sqr6&&0==sqr9T&&1==turn?($("#b9").attr("value"," O "),sqr9T=1,turn=0):" X "==sqr1&&" X "==sqr9&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):" X "==sqr3&&" X "==sqr7&&0==sqr5T&&1==turn?($("#b5").attr("value"," O "),sqr5T=1,turn=0):AI(),check2()}function AI(){turrn(),"     "==$("#b5").val()&&1==turn?($("#b5").attr("value"," O "),turn=0,sqr5T=1):"     "==$("#b1").val()&&1==turn?($("#b1").attr("value"," O "),turn=0,sqr1T=1):"     "==$("#b9").val()&&1==turn?($("#b9").attr("value"," O "),turn=0,sqr9T=1):"     "==$("#b6").val()&&1==turn?($("#b6").attr("value"," O "),turn=0,sqr6T=1):"     "==$("#b2").val()&&1==turn?($("#b2").attr("value"," O "),turn=0,sqr2T=1):"     "==$("#b8").val()&&1==turn?($("#b8").attr("value"," O "),turn=0,sqr8T=1):"     "==$("#b3").val()&&1==turn?($("#b3").attr("value"," O "),turn=0,sqr3T=1):"     "==$("#b7").val()&&1==turn?($("#b7").attr("value"," O "),turn=0,sqr7T=1):"     "==$("#b4").val()&&1==turn&&($("#b4").attr("value"," O "),turn=0,sqr4T=1),check2()}function resetclick(){$("#b1").attr("value","     "),$("#b2").attr("value","     "),$("#b3").attr("value","     "),$("#b4").attr("value","     "),$("#b5").attr("value","     "),$("#b6").attr("value","     "),$("#b7").attr("value","     "),$("#b8").attr("value","     "),$("#b9").attr("value","     "),$("#win").hide(),$("#loss").hide(),$("#p1win").hide(),$("#p2win").hide(),$("#draw").hide(),$("#reset").hide(),$("#resetbtn").hide(), sqr1T=0,sqr2T=0,sqr3T=0,sqr4T=0,sqr5T=0,sqr6T=0,sqr7T=0,sqr8T=0,sqr9T=0,turrn(),turn=0,moveCount=0}function reset(){turnp(),$("#reset").show(), $("#resetbtn").show(),$("#turn").hide(), 0==turn?($("#p2").show(),$("#p1").hide()):($("#p1").show(),$("#p2").hide())}function wb(){$("#win").show()}function p1w(){$("#p1win").show()}function p2w() {$("#p2win").show()}function lb(){$("#loss").show()}function db(){$("#draw").show()}function resetter(){reset()}var sqr1,sqr2,sqr3,sqr4,sqr5,sqr6,sqr7,sqr8,sqr9,sqr1T=0,sqr2T=0,sqr3T=0,sqr4T=0,sqr5T=0,sqr6T=0,sqr7T=0,sqr8T=0,sqr9T=0,moveCount=0,turn=0;
        </script>
    </body>
</html>

18. By Igor Makarsky

Made by Igor Makarsky. ( Source )

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
    .square {
    float:left;
    position: relative;
    width:30%;
    padding-bottom:30%; /* it equals width for a 1:1 aspect ratio */
    margin:1.66%;
    background-color:white;
}

.content {
    position:absolute;
    height:100%;
    width:100%;
    font-size:19.0vw;
}

body {
    color:#000;
    text-align:center;
    background:#ECECEC;
}

th, td {
    text-align:center;
}

dialog {
    top:30%;
    z-index: 1;
}
    </style>
</head>
<body>
    
<dialog id="dialog">  
  <h2>It's a draw!</h2>
  <p>Click OK to continue</p>
  <button id="dialogBtn" class="btn btn-info">OK</button>
</dialog>

<div class="container">
  <table class="table">
    <thead>
      <tr>
        <th>X</th>
        <th>Turn</th>
        <th>O</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><span id="xScore">0</span></td>
        <td id="header">X</td>
        <td><span id="oScore">0</span></td>
      </tr>
    </tbody>
  </table>
  <!-- 1st row -->

  <div class="square">
      <div class="content"></div>
  </div>
  <div class="square">
      <div class="content"></div>
  </div>
  <div class="square">
      <div class="content"></div>
  </div>
  <!-- 2nd row -->

  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content"></div>
  </div>
  <!-- 3rd row -->

  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content"></div>
  </div>
  
  <div>
    <button id="newGame" class="btn btn-info" onclick="startNewGame()">New game</button>
  </div>
  <div class="panel panel-default" style="margin-top:5px">
    <div class="panel-body">Made by <a href="https://www.sololearn.com/Profile/779917">Igor Makarsky</a></div>
  </div>
</div>

<script>
  var turn = "X";
  var next = "O";
  var isOver = false;
  var header = document.getElementById("header");
  var xScore = document.getElementById("xScore");
  var oScore = document.getElementById("oScore");
  var elements = document.getElementsByClassName("content");
  document.getElementById("newGame").style.visibility = "hidden";
</script>
<script>
    var UI = (function() {

  var DOMstrings = {
    dialog: 'dialog'
  };
 
  return {
    showDialog: function() {
      document.getElementById(DOMstrings.dialog).show();
    },
    closeDialog: function() {
      document.getElementById(DOMstrings.dialog).close();
    },
    restart: function() {
      // Remove winner colors.
      // Remove X O signs.
      // Reset the score
      // Reset the turn. The loser goes first.
    }
  };
 
})();

var Game = (function() {

  var isOver = false;
  
  return {
    restart: function() {
      isOver = false;
    }
  };
 
})();

var Controller = (function(UICtrl, GameCtrl) {

  var setupEventListeners = function() {
    document.getElementById('dialogBtn').addEventListener('click', () => {
      UICtrl.closeDialog();
    });
    
    let squares = document.getElementsByClassName("content");
  
    [].forEach.call(squares, (el) => {
      el.onclick = (e) => putSign(e.target);
    });
  };
  
  return {
    init: function() {
      setupEventListeners();
    }
  };

})(UI, Game);

document.addEventListener('DOMContentLoaded', Controller.init);

  function putSign(e) {
    if (e.innerHTML === "") {
      e.innerHTML = turn;
      turn = next;
      next = e.innerHTML;
      header.innerHTML = turn;
      var result = null;
      if (!isOver) {
          result = getWinner();
      }
      if (result === "draw" && isOver === false) {
          isOver = true;
          document.getElementById("newGame").style.visibility = "visible";
          UI.showDialog();
      }
      if (result === "X" && isOver === false) {
          xScore.innerHTML++;
          isOver = true;
          document.getElementById("newGame").style.visibility = "visible";
      }
      if (result === "O" && isOver === false) {
          oScore.innerHTML++;
          isOver = true;
          document.getElementById("newGame").style.visibility = "visible";
      }
    }
  }
  
  function getWinner() {
    if (elements[0].innerHTML == elements[1].innerHTML && 
        elements[0].innerHTML == elements[2].innerHTML &&
        elements[0].innerHTML !== "") {
        colorBackground(elements[0]);
        colorBackground(elements[1]);
        colorBackground(elements[2]);
        return elements[0].innerHTML;
    }
    if (elements[3].innerHTML == elements[4].innerHTML && 
        elements[3].innerHTML == elements[5].innerHTML &&
        elements[3].innerHTML !== "") {
        colorBackground(elements[3]);
        colorBackground(elements[4]);
        colorBackground(elements[5]);
        return elements[3].innerHTML;
    }
    if (elements[6].innerHTML == elements[7].innerHTML && 
        elements[6].innerHTML == elements[8].innerHTML &&
        elements[6].innerHTML !== "") {
        colorBackground(elements[6]);
        colorBackground(elements[7]);
        colorBackground(elements[8]);
        return elements[6].innerHTML;
    }
    if (elements[0].innerHTML == elements[3].innerHTML && 
        elements[0].innerHTML == elements[6].innerHTML &&
        elements[0].innerHTML !== "") {
        colorBackground(elements[0]);
        colorBackground(elements[3]);
        colorBackground(elements[6]);
        return elements[0].innerHTML;
    }
    if (elements[1].innerHTML == elements[4].innerHTML && 
        elements[1].innerHTML == elements[7].innerHTML &&
        elements[1].innerHTML !== "") {
        colorBackground(elements[1]);
        colorBackground(elements[4]);
        colorBackground(elements[7]);
        return elements[1].innerHTML;
    }
    if (elements[2].innerHTML == elements[5].innerHTML && 
        elements[2].innerHTML == elements[8].innerHTML &&
        elements[2].innerHTML !== "") {
        colorBackground(elements[2]);
        colorBackground(elements[5]);
        colorBackground(elements[8]);
        return elements[2].innerHTML;
    }
    if (elements[0].innerHTML == elements[4].innerHTML && 
        elements[0].innerHTML == elements[8].innerHTML &&
        elements[0].innerHTML !== "") {
        colorBackground(elements[0]);
        colorBackground(elements[4]);
        colorBackground(elements[8]);
        return elements[0].innerHTML;
    }
    if (elements[2].innerHTML == elements[4].innerHTML && 
        elements[2].innerHTML == elements[6].innerHTML &&
        elements[2].innerHTML !== "") {
        colorBackground(elements[2]);
        colorBackground(elements[4]);
        colorBackground(elements[6]);
        return elements[2].innerHTML;
    }
    var filled = 0;
    for (var i = 0; i < elements.length; i++) {
        if (elements[i].innerHTML == "X" || elements[i].innerHTML == "O") {
            filled++;
        }
        if (filled == 9) {
            return "draw";
        }
    }
    return false;
  }
  
  function colorBackground(el) {
      el.style.backgroundColor = "#b3ffb3";
  }
  
  function startNewGame() {
    for (var i = 0; i < elements.length; i++) {
      elements[i].innerHTML = "";
      elements[i].style.backgroundColor = "#FFF";
    }
    turn = "X";
    next = "O";
    header.innerHTML = turn;
    isOver = false;
    document.getElementById("newGame").style.visibility = "hidden";
  }
    </script>
</body>
</html>

19. By David (DonDejvo)

Made by David (DonDejvo). Simple JavaScript AI Tic tac toe game. ( Source )

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=0">
        <title>Page Title</title>
    <style>
        * {
    box-sizing: border-box;
}
html, body {
    user-select: none;
    -webkit-user-select: none;
    font-family: Arial;
}
#board {
    position: relative;
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    border: 1vw solid black;
}
#board > div::before {
    content: "";
    padding-bottom: 100%;
}
.board-cell {
    border: 1vw solid black;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20vw;
}
#msg_container {
    position: absolute;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 60%;
    height: 20vw;
    border: 1vw solid black;
    left: 20%;
    top: 80vw;
    background: silver;
    font-size: 10vw;
}
        </style>
    </head>
    <body>
        <div id="board">
            <div id="msg_container">
                <div id="msg"></div>
            </div>
        </div>
        <script>
            let cells, msg_con, msg;
const winning = [
    [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]
];
const x = "<span style='color:blue;'>x</span>";
const o = "<span style='color:red;'>o</span>";
const board = [];
let finished = false;
let turnCount = 0, starting = 0, playing = 0;
const players = [0, 1]; // human = 0, bot = 1
onload = init;
function place(idx) {
    if(board[idx] != -1 || finished) {
        return;
    }
    board[idx] = playing;
    cells[idx].innerHTML = playing == 0 ? x : o;
    ++turnCount;
    if(checkBoard(board, turnCount, true) == -1) {
        playing = (playing + 1) % 2;
        next();
    }
}
function switchPlayers() {
    [players[0], players[1]] = [players[1], players[0]];
}
function newGame() {
    msg_con.style.display = "none";
    for(let i = 0; i < 9; ++i) {
        board[i] = -1;
        cells[i].innerHTML = "";
    }
    turnCount = 0;
    finished = false;
    playing = starting;
    next();
}
function gameOver(except) {
    for(let i = 0; i < 9; ++i) {
        const symbol = board[i];
        if(!except.includes(i) && symbol != -1) {
            cells[i].innerHTML = "<span style='color:grey;'>" + (symbol == 0 ? "x" : "o") + "</span>";
        }
    }
    finished = true;
    msg_con.style.display = "flex";
    msg.innerHTML = except.length ? (playing == 0 ? x : o) + " won" : "It\'s draw";
    setTimeout(() => {
        switchPlayers();
        newGame();
    }, 3000);
}
function checkBoard(board, turnCount, real = false) {
    for(const c of winning) {
        const symbol = board[c[0]];
        if(symbol != -1 && symbol == board[c[1]] && symbol == board[c[2]]) {
            if(real) {
                gameOver(c);
            }
            return symbol;
        }
    }
    if(turnCount == 9) {
        if(real) {
            gameOver([]);
        }
        return -2;
    }
    return -1;
}
function onCellClick(idx) {
    if(finished || players[playing] == 1) {
        return;
    }
    place(idx);
}
function init() {
    const grid = document.getElementById("board");
    cells = document.getElementsByClassName("board-cell");
    msg_con = document.getElementById("msg_container");
    msg = document.getElementById("msg");
    for(let i = 0; i < 9; ++i) {
        const cell = document.createElement("div");
        cell.classList.add("board-cell");
        cell.onclick = () => onCellClick(i);
        grid.appendChild(cell);
    }    
    newGame();
}
function next() {
    if(players[playing] == 1) {
        playBot();
    }
}
function playBot() {
    if(turnCount == 0) {
        place(Math.floor(Math.random() * 9));
    } else {
        let idx;
        calc(turnCount, playing, true);
        place(idx);
        function calc(t, p, setValue = false) {
            const res = checkBoard(board, t);
            switch(res) {
                case 0: return 1;
                case 1: return -1;
                case -2: return 0;
                default: break;
            }
            let best, desired, other;
            if(p == 0) {
                best = -Infinity;
                desired = 1;
                other = 1;
            } else {
                best = Infinity;
                desired = -1;
                other = 0;
            }
            for (let i = 0; i < 9; ++i) {
                if (board[i] == -1) {
                    board[i] = p;
                    const temp = calc(t + 1, other, false);
                    const val = p == 0 ? Math.max(temp, best) : Math.min(temp, best);
                    board[i] = -1;
                    if (val != best) {
                        if (setValue) {
                            idx = i;
                        }
                        if (val == desired) {
                            return val;
                        }
                        best = val;
                    }
                }
            }
            return best;
        }
    }
}
            </script>
    </body>
</html>

20. By Salif Mehmed πŸ‡ΉπŸ‡·πŸ‡§πŸ‡¬

Made by Salif Mehmed πŸ‡ΉπŸ‡·πŸ‡§πŸ‡¬. ( Source )

<!DOCTYPE html>
<html>
<head>
<title>Tic Tac Toe</title>
<style>
    body {
background-color:blue;
color:white;
}
#tbl {
margin-top:50px;
}
#tbl td {
background-color:white;
border:3px solid blue;
color:black;
border-radius:10px;
height:50px;
width:50px;
text-align:center;
font-size:20pt;
font-weight:bolder;
}
@keyframes spinx {
from {
    transform:rotateX(0deg);
}
to {
    transform:rotateX(360deg);
}
}
@keyframes spiny {
from {
    transform:rotateY(0deg);
}
to {
    transform:rotateY(360deg);
}
}
@keyframes spinz {
from {
    transform:rotateZ(0deg);
}
to {
    transform:rotateZ(360deg);
}
}
@keyframes spinall {
from {
    transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg);
}
to {
    transform:rotateX(360deg) rotateY(360deg) rotateZ(360deg);
}
}
.f {
    margin-top:60px;
}
input {
    padding: 10px 20px;
    display: inline-block;
    background-color:#007bff;
    color:white;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}
input:focus {
    outline:none;
    background-color:#0069d9;
}
    </style>
</head>
<body>
<h1 id="or" align="center"></h1>
<table border="0" id="tbl" align="center" cellpadding="10" cellspacing="0">
<tr><td id="t1"></td><td id="t2"></td><td id="t3"></td></tr>
<tr><td id="t4"></td><td id="t5"></td><td id="t6"></td></tr>
<tr><td id="t7"></td><td id="t8"></td><td id="t9"></td></tr>
</table>
<div class="f" align="center">
    <input type="button" onclick="sm('x')" value="X">
    <input type="button" onclick="sm('y')" value="Y">
    <input type="button" onclick="sm('z')" value="Z">
    <input type="button" onclick="sm('0')" value="0">
    <input type="button" onclick="sm('all')" value="all">
</div>
<script>
    var xo=false, a=["", "", "", "", "", "", "", "", ""], p=false, ab=0, vor="0-0", vorx=0, voro=0;
Object.prototype.text=function(v) {
this.innerText=v;
};
Object.prototype.cl=function() {
if(p || this.textv()) {return;}
this.text(xof());
this.style.backgroundColor="red";
this.style.color="white";
a[this.id.charAt(1)-1]=xo?"x":"0";
switch(true){
case a[0]+a[1]+a[2]==="xxx" : s("x"); return; break;
case a[3]+a[4]+a[5]==="xxx" : s("x"); return; break;
case a[6]+a[7]+a[8]==="xxx" : s("x"); return; break;
case a[0]+a[3]+a[6]==="xxx" : s("x"); return; break;
case a[1]+a[4]+a[7]==="xxx" : s("x"); return; break;
case a[2]+a[5]+a[8]==="xxx" : s("x"); return; break;
case a[0]+a[4]+a[8]==="xxx" : s("x"); return; break;
case a[2]+a[4]+a[6]==="xxx" : s("x"); return; break;
case a[0]+a[1]+a[2]==="000" : s("0"); return; break;
case a[3]+a[4]+a[5]==="000" : s("0"); return; break;
case a[6]+a[7]+a[8]==="000" : s("0"); return; break;
case a[0]+a[3]+a[6]==="000" : s("0"); return; break;
case a[1]+a[4]+a[7]==="000" : s("0"); return; break;
case a[2]+a[5]+a[8]==="000" : s("0"); return; break;
case a[0]+a[4]+a[8]==="000" : s("0"); return; break;
case a[2]+a[4]+a[6]==="000" : s("0"); return; break;
}
ab++;
if(ab===9){s(""); return;}
};
Object.prototype.textv=function() {
if(this.innerText=="x" || this.innerText=="0") {
return true;
}
return false;
};
function $(v) {
return document.getElementById(v);
}
window.onload=function() {
$("t1").setAttribute("onclick", "c(this)");
$("t2").setAttribute("onclick", "c(this)");
$("t3").setAttribute("onclick", "c(this)");
$("t4").setAttribute("onclick", "c(this)");
$("t5").setAttribute("onclick", "c(this)");
$("t6").setAttribute("onclick", "c(this)");
$("t7").setAttribute("onclick", "c(this)");
$("t8").setAttribute("onclick", "c(this)");
$("t9").setAttribute("onclick", "c(this)");
$("or").text(vor);
}
function pr() {
$("t1").text("");
$("t2").text("");
$("t3").text("");
$("t4").text("");
$("t5").text("");
$("t6").text("");
$("t7").text("");
$("t8").text("");
$("t9").text("");
$("t1").oc();
$("t2").oc();
$("t3").oc();
$("t4").oc();
$("t5").oc();
$("t6").oc();
$("t7").oc();
$("t8").oc();
$("t9").oc();
xo=false;
a=["", "", "", "", "", "", "", "", ""];
ab=0;
vor=vorx+"-"+voro;
$("or").text(vor);
p=false;
}
Object.prototype.oc=function(){
this.style.backgroundColor="white";
this.style.color="black";
}
function c(v) {
if(p || v.textv()) {return;}
v.text(xof());
v.style.backgroundColor="orange";
v.style.color="white";
a[v.id.charAt(1)-1]=xo?"x":"0";
switch(true){
case a[0]+a[1]+a[2]==="xxx" : s("x"); return; break;
case a[3]+a[4]+a[5]==="xxx" : s("x"); return; break;
case a[6]+a[7]+a[8]==="xxx" : s("x"); return; break;
case a[0]+a[3]+a[6]==="xxx" : s("x"); return; break;
case a[1]+a[4]+a[7]==="xxx" : s("x"); return; break;
case a[2]+a[5]+a[8]==="xxx" : s("x"); return; break;
case a[0]+a[4]+a[8]==="xxx" : s("x"); return; break;
case a[2]+a[4]+a[6]==="xxx" : s("x"); return; break;
case a[0]+a[1]+a[2]==="000" : s("0"); return; break;
case a[3]+a[4]+a[5]==="000" : s("0"); return; break;
case a[6]+a[7]+a[8]==="000" : s("0"); return; break;
case a[0]+a[3]+a[6]==="000" : s("0"); return; break;
case a[1]+a[4]+a[7]==="000" : s("0"); return; break;
case a[2]+a[5]+a[8]==="000" : s("0"); return; break;
case a[0]+a[4]+a[8]==="000" : s("0"); return; break;
case a[2]+a[4]+a[6]==="000" : s("0"); return; break;
}
ab++;
if(ab===9){s("d"); return;}
if(a[0]+a[1]+a[2]==="00") {$("t"+np(0, 1, 2)).click(); return;}
else if(a[3]+a[4]+a[5]==="00") {$("t"+np(3, 4, 5)).cl(); return;}
else if(a[6]+a[7]+a[8]==="00") {$("t"+np(6, 7, 8)).cl(); return;}
else if(a[0]+a[3]+a[6]==="00") {$("t"+np(0, 3, 6)).cl(); return;}
else if(a[1]+a[4]+a[7]==="00") {$("t"+np(1, 4, 7)).cl(); return;}
else if(a[2]+a[5]+a[8]==="00") {$("t"+np(2, 5, 8)).cl(); return;}
else if(a[0]+a[4]+a[8]==="00") {$("t"+np(0, 4, 8)).cl(); return;}
else if(a[2]+a[4]+a[6]==="00") {$("t"+np(2, 4, 6)).cl(); return;}
else if(a[0]+a[1]+a[2]==="xx") {$("t"+np(0, 1, 2)).cl(); return;}
else if(a[3]+a[4]+a[5]==="xx") {$("t"+np(3, 4, 5)).cl(); return;}
else if(a[6]+a[7]+a[8]==="xx") {$("t"+np(6, 7, 8)).cl(); return;}
else if(a[0]+a[3]+a[6]==="xx") {$("t"+np(0, 3, 6)).cl(); return;}
else if(a[1]+a[4]+a[7]==="xx") {$("t"+np(1, 4, 7)).cl(); return;}
else if(a[2]+a[5]+a[8]==="xx") {$("t"+np(2, 5, 8)).cl(); return;}
else if(a[0]+a[4]+a[8]==="xx") {$("t"+np(0, 4, 8)).cl(); return;}
else if(a[2]+a[4]+a[6]==="xx") {$("t"+np(2, 4, 6)).cl(); return;}
else if(a[0]+a[1]+a[2]==="x0") {$("t"+np(0, 1, 2)).cl(); return;}
else if(a[3]+a[4]+a[5]==="x0") {$("t"+np(3, 4, 5)).cl(); return;}
else if(a[6]+a[7]+a[8]==="x0") {$("t"+np(6, 7, 8)).cl(); return;}
else if(a[0]+a[3]+a[6]==="x0") {$("t"+np(0, 3, 6)).cl(); return;}
else if(a[1]+a[4]+a[7]==="x0") {$("t"+np(1, 4, 7)).cl(); return;}
else if(a[2]+a[5]+a[8]==="x0") {$("t"+np(2, 5, 8)).cl(); return;}
else if(a[0]+a[4]+a[8]==="x0") {$("t"+np(0, 4, 8)).cl(); return;}
else if(a[2]+a[4]+a[6]==="x0") {$("t"+np(2, 4, 6)).cl(); return;}
else if(a[0]+a[1]+a[2]==="0x") {$("t"+np(0, 1, 2)).cl(); return;}
else if(a[3]+a[4]+a[5]==="0x") {$("t"+np(3, 4, 5)).cl(); return;}
else if(a[6]+a[7]+a[8]==="0x") {$("t"+np(6, 7, 8)).cl(); return;}
else if(a[0]+a[3]+a[6]==="0x") {$("t"+np(0, 3, 6)).cl(); return;}
else if(a[1]+a[4]+a[7]==="0x") {$("t"+np(1, 4, 7)).cl(); return;}
else if(a[2]+a[5]+a[8]==="0x") {$("t"+np(2, 5, 8)).cl(); return;}
else if(a[0]+a[4]+a[8]==="0x") {$("t"+np(0, 4, 8)).cl(); return;}
else if(a[2]+a[4]+a[6]==="0x") {$("t"+np(2, 4, 6)).cl(); return;}
else if(a[4]==="x" || a[4]==="0") {
if(a[1]==="x" || a[1]==="0") {
if(a[3]==="x" || a[3]==="0") {$("t1").cl(); return;}
else {$("t4").cl(); return;}
}
else {$("t2").cl(); return;}
}
else {$("t5").cl(); return;}
}
function np(v1, v2, v3) {
if(a[v1]=="") {return v1+1;}
if(a[v2]=="") {return v2+1;}
if(a[v3]=="") {return v3+1;}
}
function xof() {
xo=!xo;
return xo?"x":"0";
}
function s(v) {
if(v==="x") {
vorx++;
$("or").innerText="You win!";}
else if(v==="0") {
voro++;
$("or").innerText="You lose!";}
else {
vorx++;
voro++;
$("or").innerText="DRAW!";}
p=true;
window.setTimeout("pr()", 1500);
}
function sm(v) {
switch(v){
case "x" : 
$("tbl").style.animation="spinx 10s linear infinite"; break;
case "y" : 
$("tbl").style.animation="spiny 10s linear infinite"; break;
case "z" : 
$("tbl").style.animation="spinz 10s linear infinite"; break;
case "0" : 
$("tbl").style.animation="none"; break;
case "all" : 
$("tbl").style.animation="spinall 10s linear infinite"; break;
}
}
    </script>
</body>
</html>

21. By Supachai Rojanasiripong

Made by Supachai Rojanasiripong. AI Tic tac toe game with option to choose who draws the first move. ( Source )

<!--Coded by Supachai Rojanasiripong-->
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" charset="UTF-8">
        <title>Tic Tac Toe</title>
        <style>
            body {
    background-color:#F5F5F5;
    color:#556B2F;
    font-family:Arial, sans-serif;
}

#label {
    position:relative;
    top:0px;
    width:345px;
    height:180px;
    background-color:#F0E68C;
}

#nev{
    position:relative;
    top:50px;
    width:90px;
    height:20px;
    left:200px;
    background-color:#F0E68C;
    font-size:16px;
    font-weight:bold;
    text-align:center;
    border:2px solid #556B2F;
    border-radius:5px;
    transform:rotate(-5deg);
    animation:swing 15s infinite;
    z-index:3;
}
@keyframes swing {
    50% {
        transform-origin:left;
        transform:rotate(25deg);
    }
}

#tic {
    position:relative;
    top:30px;
    left:30px;
    width:80px;
    height:70px;
    transform:rotate(15deg);
    border:4px dashed #556B2F;
    font-weight:bold;
    font-size:60px;
}

#tac {
    position:relative;
    top:-10px;
    left:120px;
    width:70px;
    transform:rotate(-10deg);
    background-color:#556B2F;
    font-weight:bold;
    font-size:40px;
    color:#F0E68C; 
    padding:5px;
    text-align:center;
}

#toe {
    position:relative;
    top:-70px;
    left:210px;
    width:70px;
    height:70px;
    transform:rotate(5deg);
    border:4px dashed #556B2F;
    font-weight:bold;
    font-size:60px;
    z-index:2;
}

#ttt {
    width:200px;
    animation:swingT 15s infinite;
}

@keyframes swingT {
    50% {
        transform:rotate(-25deg);
    }
}

#menuBorder{
    position:relative;
    top:10px;
    left:0px;
    width:345px;
    height:100px;
    background-color:#556B2F;
    color:#F0E68C; 
    display:block;
}

#first {
    position:relative;
    top:10px;
    left:10px;
    font-size:20px;
    font-weight; bold; 
}

#hBtn {
    position:relative;
    top:20px;
    left:47px;
    width:100px;
    border:1px solid #F0E68C;
    text-align:center;
    font-size:30px;
}

#cBtn {
    position:relative;
    left:157px;
    top:-17px;
    width:140px;
    border:1px solid #556B2F;
    text-align:center;
    font-size:30px;
}

#sBtn {
    position:relative;
    top:20px;
    width:345px;
    height:24px;
    background-color:#F0E68C;
    font-size:22px;
    font-weight:bold;
    text-align:right;
}

p {
    position:relative;
    top:10px;
    font-size:16px
}

#console {
    display:none;
}

#again {
    position:relative;
    top:10px;
    left:10px;
    height:30px;
    border:none;
    font-size:20px;
    background-color:#556B2F;
    color:#F0E68C;   
}

#menuBtn {
    position:relative;
    top:10px;
    left:160px;
    height:30px;
    border:none;
    font-size:20px;
    background-color:#556B2F;
    color:#F0E68C;    
}

#topConsole {
    position:relative;
    width:345px; 
    height:410px;
    background-color:#F0E68C;
}

.board {
    position:relative;
    top:15px;
    left:8px;
    width:330px;
    height:335px;
    text-align:center;
}

.input {
    position:relative;
    top:8px;
    width:100px;
    height:100px;
    display:inline-block;
    border:3px solid #556B2F;
    color:#F0E68C;
    font-size:75px;
    text-align:center;
    overflow:hidden;    
}

#who {
    position:relative;
    top:20px;
    left:10px;
    height:30px;
    width:180px;
    font-size:16px;
    text-align:left;
}

#level {
    position:relative;
    top:-10px;
    left:185px;
    height:30px;
    width:150px;
    font-size:16px;
    text-align:right;
}

#info {
    position:relative;
    top:10px;
    left:17px;
    width:300px;
    height:70px;
    text-align:center;
    font-size:60px;
    transform:rotate(2deg);
    animation:quake 0.1s infinite;
    border:4px solid;
}

@keyframes quake {
    50% {
        transform:rotate(-2deg);
    }
}
            </style>
    </head>
    <body>
        <div id="menu">
            <div id="label">            
                <div id="ttt">
                    <div id="nev">Never win</div>
                    <div id="tic">Tic</div>
                    <div id="tac">Tac</div>
                    <div id="toe">Toe</div>
                </div>
            </div>
            <div id="menuBorder">
                <div id="first">Who turn first? :</div>
                <div id="hBtn" type="submit" onclick="whoFirstTurn('Human')">Human</div>
                <div id="cBtn" type="submit" onclick="whoFirstTurn('Computer')">Computer</div>
            </div>
            <div id="sBtn" onclick="start()">>>Start Game</div>
            <p>Coded by Supachai Rojanasiripong</p>
        </div>
        <div id="console">
            <div id="topConsole">   
                <button id="again" onclick="start()">Play Again</button>
                <button id="menuBtn" onclick="openMenu()">Menu</button>
                <div class="board">
                    <div>
                        <div class="input" id="0" onclick="turn('0')"></div>
                        <div class="input" id="1" onclick="turn('1')"></div>
                        <div class="input" id="2" onclick="turn('2')"></div>
                    </div>
                    <div>
                        <div class="input" id="3" onclick="turn('3')"></div>
                        <div class="input" id="4" onclick="turn('4')"></div>
                        <div class="input" id="5" onclick="turn('5')"></div>
                    </div>
                    <div>
                        <div class="input" id="6" onclick="turn('6')"></div>
                        <div class="input" id="7" onclick="turn('7')"></div>
                        <div class="input" id="8" onclick="turn('8')"></div>
                    </div>
                </div>
                <div id="who"></div>
                <div id="level"></div>
            </div>
            <div id="info"></div>   
        </div>
        <script>
            
    //Coded by Supachai Rojanasiripong
    alert("If you like it, upvote me please. this code work on mobile only.")
    var isStart = false;
    var humanFirst = true;
    var whoTurn;
    var count;
    var isClicked = [];
    var humanWin;
    var com;
    var human;
    var winList = [];
    var level = 'Hard';

    function whoFirstTurn(value){
        switch(value){
            case "Human":
                document.getElementById("hBtn").style. borderColor = "#F0E68C";
                document.getElementById("cBtn").style. borderColor = "#556B2F";
                humanFirst = true;
            break; 
            case "Computer":
                document.getElementById("hBtn").style.borderColor = "#556B2F";
                document.getElementById("cBtn").style.borderColor = "#F0E68C";
                humanFirst = false;
            break; 
        }
    }

    function openMenu(){
        document.getElementById("console").style.display = "none";
        document.getElementById("menu").style.display = "block";
    }

    function start(){
        document.getElementById("menu").style.display = "none";
        document.getElementById("console").style.display = "block";
        count = 0;    
        var info = document.getElementById("info");
        info.style.display = "none"; 
        isStart = true;
        humanWin = false;
        isClicked = [];
        winList = [];
        for(let i=0;i<9;i++){
            document.getElementById(i.toString()).style.backgroundColor = "#F0E68C";
            document.getElementById(i.toString()).style.color = "#556B2F";
            document.getElementById(i.toString()).innerHTML = '';
        }
        if(humanFirst==true){
            whoTurn = 'Human';
            human = 'o';
            com = 'x'
        } else{
            whoTurn = 'Computer';
            com = 'o';
            human = 'x'    
        }
        document.getElementById("who").innerHTML = "<b>The first turn : "+whoTurn;
        document.getElementById("level").innerHTML = "<b>Level : "+level;
        gameLoop();
    }
        
    function gameLoop(){        
        if(whoTurn=='Human'&&humanWin!=true){
            count++;
        } else{
            if(humanWin!=true){
                if(humanFirst==true&&count<9||humanFirst==false){                        
                    count++;
                    var input = '';
                    for(let i=0;i<9;i++){
                        let temp = document.getElementById(i.toString()).innerHTML;
                        if(temp==''){temp = 0;}
                        input += temp;
                    }
                    var turnId = getTurn(input);
                    if(turnId!=undefined){
                        comTurn(turnId);
                    } else{
                        comTurn(randMove());
                    }
                }                    
            }
        }    
    }

    function comTurn(id){
        document.getElementById(id).innerHTML = com;
        isClicked.push(id);
        if(humanFirst!=true){
            checkO();
        } else{
            checkX();
        }
        whoTurn = 'Human';
        gameLoop();
    }

    function turn(id){
        if(whoTurn=='Human'&&isClicked.indexOf(id)==-1){
            document.getElementById(id).innerHTML = human;
            info.innerHTML = '';
            isClicked.push(id);
            if(humanFirst==true){
                checkO();
            } else{
                checkX();
            }
            whoTurn = 'Computer';
            if(humanWin!=true){
                gameLoop();
            }
        }
    }

    var turnMap = 
    [
    //fisstMove
    '000000000',

    //center1 opp return on edges
    '000xo0000','0x00o0000','0000ox000','0000o00x0',

    //center2 opp return on conners
    '0000o0x00','x000o0000','00x0o0000','0000o000x',

    //center3 opp attrack edges
    '0xo0o0x00','x000ox00o','00x0o0ox0','o00xo000x',

    //center4 opp attrack edge revert
    '00o0oxx00','x000o00xo','00xxo0o00','ox00o000x',

    //conner1
    '000x00o00','000x00oxo','ox0000000','ox0x00o00','00o00x000','oxo00x000','0000000xo','00o00x0xo',

    //conner1 revert
    '000000ox0','o00x00ox0','o00x00000','oxox00000','0xo000000','0xo00x00o','00000x00o','00000xoxo',

    //conner2
    'x00000o00','x00000oxo','o0x000000','o0xx00o00','00o00000x','oxo00000x','000000x0o','00o00xx0o',

    //conner2 revert
    '000000o0x','o00x00o0x','o00000x00','oxo000x00','x0o000000','x0o00x00o','00x00000o','00x000oxo',

    //conner3
    '0x0000o00','0x0000oxo','o0000x000','o00x0xo00','00o0000x0','oxo0000x0',
    '000x0000o','00ox0x00o',

    //conner3 revert
    '00000xo00','o00x0xo00','o000000x0','oxo0000x0','00ox00000','00ox0x00o',
    '0x000000o','0x0000oxo',

    //conner4
    '00x000o00','o0xx00o00','o0000000x','oxo00000x','00o000x00','00o00xx0o','x0000000o','x00000oxo',

    //connor5
    '0000x0o00','o000x0000','00o0x0000','0000x000o',

    //humanFirstCenter1
    '0000o0000',

    //humanFirstCenter2
    '00o0o0x00','x000o000o','00x0o0o00','o000o000x',

    //humanFirstConner1
    '000000o00','o00000000','00o000000','00000000o',

    //humanFirstConner2
    '0o00x0o00','o000xo000','00o0x00o0','000ox000o',

    //humanFirstConner2 revert
    '0o00x000o','0000xoo00','o000x00o0','00oox0000',

    //humanFirstConner3
    '00o0x0o00','o000x000o',

    //humanFirstEdge1
    '000o00000','0o0000000','00000o000','0000000o0',

    //humanFirstEdge2
    '000oxo000','0o00x00o0',
    ];

    function getTurn(input){
        for(let i=0;i<turnMap.length;i++){
            if(turnMap[i]==input){
                switch(i){
                    //first move
                    case 0:
                        var x = Math.floor(Math.random()*5);
                        switch(x){
                            case 0:return '0';break;
                            case 1:return '2';break;
                            case 2:return '6';break;
                            case 3:return '8';break;
                            case 4:return '4';break;
                        }
                    break;
                    //center1 opp return on edges
                    case 1:return '8';break;
                    case 2:return '6';break;
                    case 3:return '0';break;
                    case 4:return '2';break;
                    //center2 opp return on conner
                    case 5:return '2';break;
                    case 6:return '8';break;
                    case 7:return '6';break;
                    case 8:return '0';break;
                    
                    //center3 opp attrack edges
                    case 9:return '8';break;
                    case 10:return '6';break;
                    case 11:return '0';break;
                    case 12:return '2';break;
                    
                    //cennter4 opp attrack edges revert
                    case 13:return '0';break;
                    case 14:return '2';break;
                    case 15:return '8';break;
                    case 16:return '6';break;
                    
                    //conner1
                    case 17:return '8';break;
                    case 18:return '2';break;
                    case 19:return '6';break;
                    case 20:return '8';break;
                    case 21:return '0';break;
                    case 22:return '6';break;
                    case 23:return '2';break;
                    case 24:return '0';break;
                    
                    //conner1 revert
                    case 25:return '0';break;
                    case 26:return '2';break;
                    case 27:return '2';break;
                    case 28:return '8';break;
                    case 29:return '8';break;
                    case 30:return '6';break;
                    case 31:return '6';break;
                    case 32:return '0';break;
                    
                    //conner2
                    case 33:return '8';break;
                    case 34:return '2';break;
                    case 35:return '6';break;
                    case 36:return '8';break;
                    case 37:return '0';break;
                    case 38:return '6';break;
                    case 39:return '2';break;
                    case 40:return '0';break;
                    
                    //conner2 revert
                    case 41:return '0';break;
                    case 42:return '2';break;
                    case 43:return '2';break;
                    case 44:return '8';break;
                    case 45:return '8';break;
                    case 46:return '6';break;
                    case 47:return '6';break;
                    case 48:return '0';break;
                    
                    //conner3
                    case 49:return '8';break;
                    case 50:return '4';break;
                    case 51:return '6';break;
                    case 52:return '4';break;
                    case 53:return '0';break;
                    case 54:return '4';break;
                    case 55:return '2';break;
                    case 56:return '4';break;
                    
                    //conner3 revert
                    case 57:return '0';break;
                    case 58:return '4';break;
                    case 59:return '2';break;
                    case 60:return '4';break;
                    case 61:return '8';break;
                    case 62:return '4';break;
                    case 63:return '6';break;
                    case 64:return '4';break;
                    
                    //conner4
                    case 65:return '0';break;
                    case 66:return '8';break;
                    case 67:return '2';break;
                    case 68:return '6';break;
                    case 69:return '8';break;
                    case 70:return '0';break;
                    case 71:return '6';break;
                    case 72:return '2';break;
                    
                    //conner5
                    case 73:return '2';break;
                    case 74:return '8';break;
                    case 75:return '6';break;
                    case 76:return '0';break;
                    
                    //humunFirstCenter1
                    case 77:
                        var x = Math.floor(Math.random()*4);
                        switch(x){
                            case 0:return '6';break;
                            case 1:return '0';break;
                            case 2:return '2';break;
                            case 3:return '8';break;
                        }
                    break;
                    
                    //humanFirstCenter2
                    case 78:return '0';break;
                    case 79:return '2';break;
                    case 80:return '8';break;
                    case 81:return '6';break;
                    
                    //humanFirstConner1
                    case 82:return '4';break;
                    case 83:return '4';break;
                    case 84:return '4';break;
                    case 85:return '4';break;
                    
                    //humunFirstConner2
                    case 86:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '0';break;
                            case 1:return '2';break;
                            case 2:return '5';break;
                        }
                    break;
                    case 87:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '2';break;
                            case 1:return '8';break;
                            case 2:return '7';break;
                        }
                    break;
                    case 88:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '8';break;
                            case 1:return '6';break;
                            case 2:return '3';break;
                        }
                    break;
                    case 89:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '6';break;
                            case 1:return '0';break;
                            case 2:return '1';break;
                        }
                    break;
                    
                    //humunFirstConner2 revert
                    case 90:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '0';break;
                            case 1:return '2';break;
                            case 2:return '3';break;
                        }
                    break;
                    case 91:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '2';break;
                            case 1:return '8';bteak;
                            case 2:return '1';break;
                        }
                    break;
                    case 92:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '8';break;
                            case 1:return '6';break;
                            case 2:return '5';break;
                        }
                    break;
                    case 93:
                        var x = Math.floor(Math.random()*3);
                        switch(x){
                            case 0:return '6';break;
                            case 1:return '0';break;
                            case 2:return '7';break;
                        }
                    break;
                    
                    //humanFirstConner3
                    case 94:
                        var x = Math.floor(Math.random()*4);
                        switch(x){
                            case 0:return '1';break;
                            case 1:return '5';break;
                            case 2:return '7';break;
                            case 3:return '3';break;
                        }
                    break;
                    case 95:
                        var x = Math.floor(Math.random()*4);
                        switch(x){
                            case 0:return '1';break;
                            case 1:return '5';break;
                            case 2:return '7';break;
                            case 3:return '3';break;
                        }
                    break;
                    
                    //humanFirstEdge1
                    case 96:return '4';
                    case 97:return '4';
                    case 98:return '4';
                    case 99:return '4';
                    
                    //humanFirstEdge2
                    case 100:
                        var x = Math.floor(Math.random()*4);
                        switch(x){
                            case 0:return '0';break;
                            case 1:return '2';break;
                            case 2:return '8';break;
                            case 3:return '6';break;
                        }
                    break;
                    case 101:
                        var x = Math.floor(Math.random()*4);
                        switch(x){
                            case 0:return '0';break;
                            case 1:return '2';break;
                            case 2:return '8';break;
                            case 3:return '6';break;
                        }
                    break;
                }
            }
        }    
    }

    function randMove(){
        var arr = [];
        for(let i=0;i<9;i++){
            arr[i] = document.getElementById(i.toString()).innerHTML;
        }
        if(humanFirst==true){
        //attrack
        if(arr[0]=='x'&&arr[1]=='x'&&arr[2]==''){
            return '2';
        } else 
        if(arr[0]=='x'&&arr[1]==''&&arr[2]=='x'){
            return '1';
        } else
        if(arr[0]==''&&arr[1]=='x'&&arr[2]=='x'){
            return '0';
        } else
        
        if(arr[3]=='x'&&arr[4]=='x'&&arr[5]==''){
            return '5';
        } else
        if(arr[3]=='x'&&arr[4]==''&&arr[5]=='x'){
            return '4';
        } else
        if(arr[3]==''&&arr[4]=='x'&&arr[5]=='x'){
            return '3';
        } else
        if(arr[6]=='x'&&arr[7]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[6]=='x'&&arr[7]==''&&arr[8]=='x'){
            return '7';
        } else
        if(arr[6]==''&&arr[7]=='x'&&arr[8]=='x'){
            return '6';
        } else
        
        if(arr[0]=='x'&&arr[3]=='x'&&arr[6]==''){
            return '6';
        } else
        if(arr[0]=='x'&&arr[3]==''&&arr[6]=='x'){
            return '3';
        } else
        if(arr[0]==''&&arr[3]=='x'&&arr[6]=='x'){
            return '0';
        } else
        if(arr[1]=='x'&&arr[4]=='x'&&arr[7]==''){
            return '7';
        } else
        if(arr[1]=='x'&&arr[4]==''&&arr[7]=='x'){
            return '7';
        } else
        if(arr[1]==''&&arr[4]=='x'&&arr[7]=='x'){
            return '1';
        } else
        if(arr[2]=='x'&&arr[5]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[2]=='x'&&arr[5]==''&&arr[8]=='x'){
            return '5';
        } else
        if(arr[2]==''&&arr[5]=='x'&&arr[8]=='x'){
            return '2';
        } else
        
        if(arr[0]=='x'&&arr[4]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[0]=='x'&&arr[4]==''&&arr[8]=='x'){
            return '4';
        } else
        if(arr[0]==''&&arr[4]=='x'&&arr[8]=='x'){
            return '0';
        } else
        if(arr[6]=='x'&&arr[4]=='x'&&arr[2]==''){
            return '2';
        } else
        if(arr[6]=='x'&&arr[4]==''&&arr[2]=='x'){
            return '4';
        } else
        if(arr[6]==''&&arr[4]=='x'&&arr[2]=='x'){
            return '6';
        } else
        
        //defend
        if(arr[0]=='o'&&arr[1]=='o'&&arr[2]==''){
            return '2';
        } else 
        if(arr[0]=='o'&&arr[1]==''&&arr[2]=='o'){
            return '1';
        } else
        if(arr[0]==''&&arr[1]=='o'&&arr[2]=='o'){
            return '0';
        } else
        
        if(arr[3]=='o'&&arr[4]=='o'&&arr[5]==''){
            return '5';
        } else
        if(arr[3]=='o'&&arr[4]==''&&arr[5]=='o'){
            return '4';
        } else
        if(arr[3]==''&&arr[4]=='o'&&arr[5]=='o'){
            return '3';
        } else
        if(arr[6]=='o'&&arr[7]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[6]=='o'&&arr[7]==''&&arr[8]=='o'){
            return '7';
        } else
        if(arr[6]==''&&arr[7]=='o'&&arr[8]=='o'){
            return '6';
        } else
        
        if(arr[0]=='o'&&arr[3]=='o'&&arr[6]==''){
            return '6';
        } else
        if(arr[0]=='o'&&arr[3]==''&&arr[6]=='o'){
            return '3';
        } else
        if(arr[0]==''&&arr[3]=='o'&&arr[6]=='o'){
            return '0';
        } else
        if(arr[1]=='o'&&arr[4]=='o'&&arr[7]==''){
            return '7';
        } else
        if(arr[1]=='o'&&arr[4]==''&&arr[7]=='o'){
            return '7';
        } else
        if(arr[1]==''&&arr[4]=='o'&&arr[7]=='o'){
            return '1';
        } else
        if(arr[2]=='o'&&arr[5]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[2]=='o'&&arr[5]==''&&arr[8]=='o'){
            return '5';
        } else
        if(arr[2]==''&&arr[5]=='o'&&arr[8]=='o'){
            return '2';
        } else
        
        if(arr[0]=='o'&&arr[4]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[0]=='o'&&arr[4]==''&&arr[8]=='o'){
            return '4';
        } else
        if(arr[0]==''&&arr[4]=='o'&&arr[8]=='o'){
            return '0';
        } else
        if(arr[6]=='o'&&arr[4]=='o'&&arr[2]==''){
            return '2';
        } else
        if(arr[6]=='o'&&arr[4]==''&&arr[2]=='o'){
            return '4';
        } else
        if(arr[6]==''&&arr[4]=='o'&&arr[2]=='o'){
            return '6';
        } else
            do{
                var i = Math.floor(Math.random()*9);        
            }while(arr[i]=='o'||arr[i]=='x');
            return i.toString();       
        } else{
        //attack
        if(arr[0]=='o'&&arr[1]=='o'&&arr[2]==''){
            return '2';
        } else 
        if(arr[0]=='o'&&arr[1]==''&&arr[2]=='o'){
            return '1';
        } else
        if(arr[0]==''&&arr[1]=='o'&&arr[2]=='o'){
            return '0';
        } else
        
        if(arr[3]=='o'&&arr[4]=='o'&&arr[5]==''){
            return '5';
        } else
        if(arr[3]=='o'&&arr[4]==''&&arr[5]=='o'){
            return '4';
        } else
        if(arr[3]==''&&arr[4]=='o'&&arr[5]=='o'){
            return '3';
        } else
        if(arr[6]=='o'&&arr[7]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[6]=='o'&&arr[7]==''&&arr[8]=='o'){
            return '7';
        } else
        if(arr[6]==''&&arr[7]=='o'&&arr[8]=='o'){
            return '6';
        } else
        
        if(arr[0]=='o'&&arr[3]=='o'&&arr[6]==''){
            return '6';
        } else
        if(arr[0]=='o'&&arr[3]==''&&arr[6]=='o'){
            return '3';
        } else
        if(arr[0]==''&&arr[3]=='o'&&arr[6]=='o'){
            return '0';
        } else
        if(arr[1]=='o'&&arr[4]=='o'&&arr[7]==''){
            return '7';
        } else
        if(arr[1]=='o'&&arr[4]==''&&arr[7]=='o'){
            return '7';
        } else
        if(arr[1]==''&&arr[4]=='o'&&arr[7]=='o'){
            return '1';
        } else
        if(arr[2]=='o'&&arr[5]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[2]=='o'&&arr[5]==''&&arr[8]=='o'){
            return '5';
        } else
        if(arr[2]==''&&arr[5]=='o'&&arr[8]=='o'){
            return '2';
        } else
        
        if(arr[0]=='o'&&arr[4]=='o'&&arr[8]==''){
            return '8';
        } else
        if(arr[0]=='o'&&arr[4]==''&&arr[8]=='o'){
            return '4';
        } else
        if(arr[0]==''&&arr[4]=='o'&&arr[8]=='o'){
            return '0';
        } else
        if(arr[6]=='o'&&arr[4]=='o'&&arr[2]==''){
            return '2';
        } else
        if(arr[6]=='o'&&arr[4]==''&&arr[2]=='o'){
            return '4';
        } else
        if(arr[6]==''&&arr[4]=='o'&&arr[2]=='o'){
            return '6';
        } else
        
        //defend
        if(arr[0]=='x'&&arr[1]=='x'&&arr[2]==''){
            return '2';
        } else 
        if(arr[0]=='x'&&arr[1]==''&&arr[2]=='x'){
            return '1';
        } else
        if(arr[0]==''&&arr[1]=='x'&&arr[2]=='x'){
            return '0';
        } else
        
        if(arr[3]=='x'&&arr[4]=='x'&&arr[5]==''){
            return '5';
        } else
        if(arr[3]=='x'&&arr[4]==''&&arr[5]=='x'){
            return '4';
        } else
        if(arr[3]==''&&arr[4]=='x'&&arr[5]=='x'){
            return '3';
        } else
        if(arr[6]=='x'&&arr[7]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[6]=='x'&&arr[7]==''&&arr[8]=='x'){
            return '7';
        } else
        if(arr[6]==''&&arr[7]=='x'&&arr[8]=='x'){
            return '6';
        } else
        
        if(arr[0]=='x'&&arr[3]=='x'&&arr[6]==''){
            return '6';
        } else
        if(arr[0]=='x'&&arr[3]==''&&arr[6]=='x'){
            return '3';
        } else
        if(arr[0]==''&&arr[3]=='x'&&arr[6]=='x'){
            return '0';
        } else
        if(arr[1]=='x'&&arr[4]=='x'&&arr[7]==''){
            return '7';
        } else
        if(arr[1]=='x'&&arr[4]==''&&arr[7]=='x'){
            return '7';
        } else
        if(arr[1]==''&&arr[4]=='x'&&arr[7]=='x'){
            return '1';
        } else
        if(arr[2]=='x'&&arr[5]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[2]=='x'&&arr[5]==''&&arr[8]=='x'){
            return '5';
        } else
        if(arr[2]==''&&arr[5]=='x'&&arr[8]=='x'){
            return '2';
        } else
        
        if(arr[0]=='x'&&arr[4]=='x'&&arr[8]==''){
            return '8';
        } else
        if(arr[0]=='x'&&arr[4]==''&&arr[8]=='x'){
            return '4';
        } else
        if(arr[0]==''&&arr[4]=='x'&&arr[8]=='x'){
            return '0';
        } else
        if(arr[6]=='x'&&arr[4]=='x'&&arr[2]==''){
            return '2';
        } else
        if(arr[6]=='x'&&arr[4]==''&&arr[2]=='x'){
            return '4';
        } else
        if(arr[6]==''&&arr[4]=='x'&&arr[2]=='x'){
            return '6';
        } else
            do{
                var i = Math.floor(Math.random()*9);        
            }while(arr[i]=='o'||arr[i]=='x');
            return i.toString();
        }
    }

    function checkO(){
        var arr = [];
        for(let i=0;i<9;i++){
            arr[i] = document.getElementById(i.toString()).innerHTML;
        }
    if(arr[0]=='o'&&arr[1]=='o'&&arr[2]=='o'){
        winList = ['0','1','2'];
    } else
    if(arr[3]=='o'&&arr[4]=='o'&&arr[5]=='o'){
        winList = ['3','4','5'];
    } else 
    if(arr[6]=='o'&&arr[7]=='o'&&arr[8]=='o'){
        winList = ['6','7','8'];
    } else

    if(arr[0]=='o'&&arr[3]=='o'&&arr[6]=='o'){
        winList = ['0','3','6'];
    } else 
    if(arr[1]=='o'&&arr[4]=='o'&&arr[7]=='o'){
        winList = ['1','4','7'];
    } else
    if(arr[2]=='o'&&arr[5]=='o'&&arr[8]=='o'){
        winList = ['2','5','8'];
    } else

    if(arr[0]=='o'&&arr[4]=='o'&&arr[8]=='o'){
        winList = ['0','4','8'];
    } else
    if(arr[2]=='o'&&arr[4]=='o'&&arr[6]=='o'){
        winList = ['2','4','6'];
    }
        if(winList.length!=0){
            if(humanFirst==true){
                humanWin = true;
            } else{
                humanWin = false;
            }
            drawWinList();
            isClicked = ['0','1','2','3','4','5','6','7','8'];
        } else {
            if(count==9){
                info.style.display = "block"; 
                info.style.color = "#556B2F"
                info. innerHTML  = "Draw";
            }
        }
    }

    function checkX(){
        var arr = [];
        for(let i=0;i<9;i++){
            arr[i] = document.getElementById(i.toString()).innerHTML;
        }    if(arr[0]=='x'&&arr[1]=='x'&&arr[2]=='x'){
        winList = ['0','1','2'];    
    } else
    if(arr[3]=='x'&&arr[4]=='x'&&arr[5]=='x'){
        winList = ['3','4','5'];    
    } else
    if(arr[6]=='x'&&arr[7]=='x'&&arr[8]=='x'){
        winList = ['6','7','8'];
    } else

    if(arr[0]=='x'&&arr[3]=='x'&&arr[6]=='x'){
        winList = ['0','3','6'];
    } else
    if(arr[1]=='x'&&arr[4]=='x'&&arr[7]=='x'){
        winList = ['1','4','7'];
    } else
    if(arr[2]=='x'&&arr[5]=='x'&&arr[8]=='x'){
        winList = ['2','5','8'];
    } else

    if(arr[0]=='x'&&arr[4]=='x'&&arr[8]=='x'){
        winList = ['0','4','8'];
    } else
    if(arr[2]=='x'&&arr[4]=='x'&&arr[6]=='x'){
        winList = ['2','4','6'];
    }
        if(winList.length!=0){
            if(humanFirst!=true){
                humanWin = true;
            } else{
                humanWin = false;
            }
            drawWinList();   
            isClicked = ['0','1','2','3','4','5','6','7','8'];
        } else {
            if(count==9){
                info.style.display = "block";
                info.style.color = "#556B2F"
                info. innerHTML  = "Draw";
            }
        }
    }

    function drawWinList(){
        let color;
        if(humanWin==true){
            color = "#556B2F";
            info.style.display = "block";
            info.style.color = color;
            info.innerHTML = "You Win!!"
        } else{
            color = "#CD5C5C"
            info.style.display = "block"; 
            info.style.color = color; 
            info.innerHTML = "You Lose!! ";
        }
        for(let i=0;i<winList.length;i++){
            document.getElementById(winList[i]).style.backgroundColor = color;
            document.getElementById(winList[i]).style.color = "#FFFFFF";
        }    
    }

        </script>          
    </body>
</html>

22. By Jason Stone

Made by Jason Stone. ( Source )

<!DOCTYPE html>
<html>
	<head>
		<title>Page Title</title>
        <style>
            body {
	text-align: center;
}

canvas {
	border: solid;
}
            </style>
	</head>
	<body>
		<canvas id="canvas" width="500" height="500"></canvas>
        <script>
            // declare a few variables
var canvas, width, height, ctx;

// create the board class so I can create new boards as needed for the minimax algorithm
class Board {
	// if there's no input it creates a blank board, otherwise it assumes the input is an object of the class board and copies that board's board to the new object's board
	constructor(input) {
		if (!input) this.board = [["", "", ""], ["", "", ""], ["", "", ""]];
		else {
			this.board = [[], [], []];
			for (let x = 0; x < 3; x++) {
				for (let y = 0; y < 3; y++) {
					this.board[x][y] = input.board[x][y];
				}
			}
		}
	}
	// puts down an X
	makePlayerMove(x, y) {
		if (this.board[x][y] != "") throw new Error("cannot place an X at position " + x + " " + y)
		else this.board[x][y] = "X";
	}
	// puts down an O
	makeOpponentMove(x, y) {
		if (this.board[x][y] != "") throw new Error("cannot place an O at position " + x + " " + y)
		else this.board[x][y] = "O";
	}
	// gets the winner, returning either "player" (you), "opponent" (AI), or "" (no winner)
	winner() {
		if (
			(this.board[0][0] == "X" && this.board[1][0] == "X" && this.board[2][0] == "X") ||
			(this.board[0][1] == "X" && this.board[1][1] == "X" && this.board[2][1] == "X") ||
			(this.board[0][2] == "X" && this.board[1][2] == "X" && this.board[2][2] == "X") ||
			(this.board[0][0] == "X" && this.board[0][1] == "X" && this.board[0][2] == "X") ||
			(this.board[1][0] == "X" && this.board[1][1] == "X" && this.board[1][2] == "X") ||
			(this.board[2][0] == "X" && this.board[2][1] == "X" && this.board[2][2] == "X") ||
			(this.board[0][0] == "X" && this.board[1][1] == "X" && this.board[2][2] == "X") ||
			(this.board[0][2] == "X" && this.board[1][1] == "X" && this.board[2][0] == "X")
		) {
			return "player";
		} else if (
			(this.board[0][0] == "O" && this.board[1][0] == "O" && this.board[2][0] == "O") ||
			(this.board[0][1] == "O" && this.board[1][1] == "O" && this.board[2][1] == "O") ||
			(this.board[0][2] == "O" && this.board[1][2] == "O" && this.board[2][2] == "O") ||
			(this.board[0][0] == "O" && this.board[0][1] == "O" && this.board[0][2] == "O") ||
			(this.board[1][0] == "O" && this.board[1][1] == "O" && this.board[1][2] == "O") ||
			(this.board[2][0] == "O" && this.board[2][1] == "O" && this.board[2][2] == "O") ||
			(this.board[0][0] == "O" && this.board[1][1] == "O" && this.board[2][2] == "O") ||
			(this.board[0][2] == "O" && this.board[1][1] == "O" && this.board[2][0] == "O")
		) {
			return "opponent";
		} else if (this.isFull()) {
			return "tie";
		} else return "";
	}
	isFull() {
		var isFull = true;
		
		for (var x = 0; x < 3; x++) {
			for (var y = 0; y < 3; y++) {
				if (this.board[x][y] == "") isFull = false;
			}
		}
		
		return isFull;
	}
}

// create the main board
var mainBoard = new Board();

// for when the window loads
window.onload = function() {
	// get the canvas, its width and height, and the drawing context
	canvas = document.querySelector("#canvas");
	width = canvas.width;
	height = canvas.height;
	ctx = canvas.getContext("2d");
	
	// create the tic tac toe lines
	ctx.strokeStyle = "#000";
	ctx.beginPath();
	
	ctx.moveTo(width / 3, 0);
	ctx.lineTo(width / 3, height);
	
	ctx.moveTo(2 * width / 3, 0);
	ctx.lineTo(2 * width / 3, height);
	
	ctx.moveTo(0, height / 3);
	ctx.lineTo(width, height / 3);
	
	ctx.moveTo(0, 2 * height / 3);
	ctx.lineTo(width, 2 * height / 3);
	
	ctx.stroke();
	ctx.closePath();
	
	// create the script to be run when you click/tap on the canvas
	canvas.onclick = function(event) {
		// get the x & y of where you clicked/tapped
		var x = event.pageX - this.offsetLeft;
		var y = event.pageY - this.offsetTop;
		x = Math.floor(x / width * 3);
		y = Math.floor(y / width * 3);
		
		// if there's a valid x & y
		if (x >= 0 && x <= 2 && y >= 0 && y <= 2) {
			// if the spot is empty
			if (mainBoard.board[x][y] == "") {
				// put down an X
				putX(x, y);
				
				// initialize boardFull to true
				var boardFull = true;
				
				// for position on board
				for (let x = 0; x < 3; x++) {
					for (let y = 0; y < 3; y++) {
						// if that position is unfilled set boardFull to false
						if (mainBoard.board[x][y] == "") boardFull = false;
					}
				}
				
				// if the board is not full make the AI move
				if (!boardFull) AImove()
				// if the board is full and you won make an alert that you won and delete canvas.onclick
				else if (mainBoard.winner == "player") {
					alert("You won!")
					canvas.onclick = () => {};
				}
				// otherwise alert that it's a tie and delete canvas.onclick
				else {
					alert("It's a tie!");
					canvas.onclick = () => {};
				}
			}
		}
	}
	
	if (!confirm("Do you want to go first?")) AImove();
}

function putX(x, y) {
	// draw the X
	ctx.beginPath();
	
	ctx.moveTo(x * width / 3 + width / 12, y * height / 3 + height / 12);
	ctx.lineTo(x * width / 3 + 3 * width / 12, y * height / 3 + 3 * height / 12);
	
	ctx.moveTo(x * width / 3 + 3 * width / 12, y * height / 3 + height / 12);
	ctx.lineTo(x * width / 3 + width / 12, y * height / 3 + 3 * height / 12);
	
	ctx.stroke();
	ctx.closePath();
	
	// put down the X on the board in the program
	mainBoard.makePlayerMove(x, y);
}

function putO(x, y) {
	// draw the O
	ctx.beginPath();
	
	ctx.arc(x * width / 3 + width / 6, y * height / 3 + height / 6, width / 12, 0, 2 * Math.PI);
	
	ctx.stroke();
	ctx.closePath();
	
	// put down the O on the board in the program
	mainBoard.makeOpponentMove(x, y);
}

function AImove() {
	// if you won alert that you won and remove canvas.onclick
	if (mainBoard.winner() == "player") {
		alert("You won!");
		canvas.onclick = () => {};
	}
	// if you aren't in a winning state
	else {
		// get the best move. If this function returns null give an invalid move that doesn't return an error
		var move = getBestMove() || {x: 0, y: -1};
		
		// put down the AI move
		putO(move.x, move.y);
		
		// if the AI won alert you that it won and delete canvas.onclick
		if (mainBoard.winner() == "opponent") {
			alert("You lost!");
			canvas.onclick = () => {};
		}
		else if (mainBoard.winner() == "tie") {
			alert("It's a tie!");
			canvas.onclick = () => {};
		}
	}
}

// the minimax function
function minimax(board, player) {
	// if you won return a bad score since this is trying to get the computer to win
	if (board.winner() == "player") return -1;
	// if the AI won return a good score
	else if (board.winner() == "opponent") return 1;
	// if tie return neutral score
	else if (board.winner() == "tie") return 0;
	
	// initiate moveScores to an empty array
	let moveScores = [];
	
	// for each position on the board that is empty
	for (let x = 0; x < 3; x++) {
		for (let y = 0; y < 3; y++) {
			if (board.board[x][y] == "") {
				// create a new board with the same state as the board passed to the function
				let newBoard = new Board(board);
				
				// if the player value passed to the function is "player" then put an X down and call minimax and add the return value to the array moveScores
				if (player == "player") {
					newBoard.makePlayerMove(x, y);
					moveScores.push(minimax(newBoard, "opponent"));
				}
				// if the player value passed to the function isn't "player" (which means opponent/AI) put an O down and call minimax and add the return value to the array moveScores
				else {
					newBoard.makeOpponentMove(x, y);
					moveScores.push(minimax(newBoard, "player"));
				}
			}
		}
	}
	
	// if this is player's turn return the minimum of the moveScores
	if (player == "player") {
		return Math.min(...moveScores);
	}
	// else return the maximum of the moveScores
	else {
		return Math.max(...moveScores);
	}
}

function getBestMove() {
	// initiate the score array
	var score = [];
	// for every empty position in the board get what happens when you put an O at that spot and return the resulting score
	for (let x = 0; x < 3; x++) {
		for (let y = 0; y < 3; y++) {
			if (mainBoard.board[x][y] == "") {
				let newBoard = new Board(mainBoard);
				newBoard.makeOpponentMove(x, y);
				score.push([x, y, minimax(newBoard, "player")]);
			}
		}
	}
	
	// initiate the moves array and initiate bestScore to -1
	var moves = [];
	var bestScore = -1;
	
	// get the max score in score and put it in bestScore
	for (let i = 0; i < score.length; i++) {
		bestScore = Math.max(bestScore, score[i][2]);
	}
	
	// for each move in score that has a score equal to bestScore add it to the array moves
	for (let i = 0; i < score.length; i++) {
		if (score[i][2] == bestScore) {
			moves.push({x: score[i][0], y: score[i][1]});
		}
	}
	
	// return a random element of the array moves
	return moves[Math.floor(Math.random() * moves.length)];
}
            </script>
	</body>
</html>

23. By MΗŸΙ–β†»Γ΄Ι–Ι†β±€πŸ’‰

Made by MΗŸΙ–β†»Γ΄Ι–Ι†β±€πŸ’‰. ( Source )

<!DOCTYPE html>
<html>
    <head>
    
        <title>ticTacToe</title>
        
        <style>
         
         .tictac {
             background-color: white;
             color: blue;
             border: 2px solid #000000; 
             transition-duration: 0.3s;
         }
         
        
        </style>
        <script src = "https://code.jquery.com/jquery-3.1.1.js">
        </script>
        
       <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
        
    </head>
       <body>
      
       <SCRIPT>
       
//if IE4/NS6, apply style
if (document.all||document.getElementById){
document.write('<style>.tictac{')
document.write('width:90px;height:90px;')
document.write('}</style>')
}

//defining grids
var sqr1
var sqr2
var sqr3
var sqr4
var sqr5
var sqr6
var sqr7
var sqr8
var sqr9
var sqr1T = 0
var sqr2T = 0
var sqr3T = 0
var sqr4T = 0
var sqr5T = 0
var sqr6T = 0
var sqr7T = 0
var sqr8T = 0
var sqr9T = 0
var moveCount = 0
var turn = 0
var mode = 1

//use function to manipulate values
function vari()
{
sqr1 = document.tic.sqr1.value
sqr2 = document.tic.sqr2.value
sqr3 = document.tic.sqr3.value
sqr4 = document.tic.sqr4.value
sqr5 = document.tic.sqr5.value
sqr6 = document.tic.sqr6.value
sqr7 = document.tic.sqr7.value
sqr8 = document.tic.sqr8.value
sqr9 = document.tic.sqr9.value
}

// winning status checker function
function check()
{
  if(sqr1 == " X " && sqr2 == " X " && sqr3 == " X ")
  {
    alert("You Win!")
    reset()
  } 
  else if(sqr4 == " X " && sqr5 == " X " && sqr6 == " X ")
  {
    alert("You Win!")
    reset()
  } 
  else if(sqr7 == " X " && sqr8 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7 == " X ")
  {
    alert("You Win!")
    reset()
  }
  else
  {
    winCheck()
    check2()
    drawCheck()  
  } 
}

//losing status checker function
function check2()
{
  vari()
  drawCheck()
  if(sqr1 == " O " && sqr2 == " O " && sqr3 == " O ")
  {
    alert("You Lose!")
    reset()
  } 
  else if(sqr4 == " O " && sqr5 == " O " && sqr6 == " O ")
  {
    alert("You Lose!")
    reset()
  } 
  else if(sqr7 == " O " && sqr8 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("You Lose!")
    reset()
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7 == " O ")
  {
    alert("You Lose!")
    reset()
  }
}

//for upcoming versions
function player1Check()
{
  if(sqr1 == " X " && sqr2 == " X " && sqr3 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  } 
  else if(sqr4 == " X " && sqr5 == " X " && sqr6 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  } 
  else if(sqr7 == " X " && sqr8 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7 == " X ")
  {
    alert("Player 1 wins!")
    reset()
  }
  else
  {
    player2Check()
    drawCheck()  
  } 
}

//for upcoming version
function player2Check()
{
  vari()
  drawCheck()
  if(sqr1 == " O " && sqr2 == " O " && sqr3 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  } 
  else if(sqr4 == " O " && sqr5 == " O " && sqr6 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  } 
  else if(sqr7 == " O " && sqr8 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7 == " O ")
  {
    alert("Player 2 wins!")
    reset()
  }
}

//drawing section
function drawCheck()
{
  vari()
  moveCount = sqr1T + sqr2T + sqr3T + sqr4T + sqr5T + sqr6T + sqr7T + sqr8T + sqr9T 
  if(moveCount == 9)
  {
    reset()
    alert("Draw") 
  }
}

//win status
function winCheck()
{
  check2()
  if(sqr1 == " O " && sqr2 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr3 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr5 == " O " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr6 == " O " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr8 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr8 == " O " && sqr9 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr9 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr5 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr5 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr3 == " O " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr6 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr7 == " O " && sqr9 == " O " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr7 == " O " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr8 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr9 == " O " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr5 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr4 == " O " && sqr7 == " O " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr5 == " O " && sqr8 == " O " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr6 == " O " && sqr9 == " O " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr4 == " O " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr2 == " O " && sqr5 == " O " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr6 == " O " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr1 == " O " && sqr9 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " O " && sqr7 == " O " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else
  {
    computer()
  }
  check2()
}

//feedback implementation
function computer()
{
  check2()
  if(sqr1 == " X " && sqr2 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr3 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr5 == " X " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr6 == " X " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr8 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr8 == " X " && sqr9 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr9 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr5 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr5 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr3 == " X " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr6 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr7 == " X " && sqr9 == " X " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr7 == " X " && sqr4T == 0 && turn == 1)
  {
    document.tic.sqr4.value = " O "
    sqr4T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr8 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr9 == " X " && sqr6T == 0 && turn == 1)
  {
    document.tic.sqr6.value = " O "
    sqr6T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr5 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr4 == " X " && sqr7 == " X " && sqr1T == 0 && turn == 1)
  {
    document.tic.sqr1.value = " O "
    sqr1T = 1;
    turn = 0;
  }
  else if(sqr5 == " X " && sqr8 == " X " && sqr2T == 0 && turn == 1)
  {
    document.tic.sqr2.value = " O "
    sqr2T = 1;
    turn = 0;
  }
  else if(sqr6 == " X " && sqr9 == " X " && sqr3T == 0 && turn == 1)
  {
    document.tic.sqr3.value = " O "
    sqr3T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr4 == " X " && sqr7T == 0 && turn == 1)
  {
    document.tic.sqr7.value = " O "
    sqr7T = 1;
    turn = 0;
  }
  else if(sqr2 == " X " && sqr5 == " X " && sqr8T == 0 && turn == 1)
  {
    document.tic.sqr8.value = " O "
    sqr8T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr6 == " X " && sqr9T == 0 && turn == 1)
  {
    document.tic.sqr9.value = " O "
    sqr9T = 1;
    turn = 0;
  }
  else if(sqr1 == " X " && sqr9 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else if(sqr3 == " X " && sqr7 == " X " && sqr5T == 0 && turn == 1)
  {
    document.tic.sqr5.value = " O "
    sqr5T = 1;
    turn = 0;
  }
  else
  {
    AI()
  }
  check2()
}

//AI implementation
function AI()
{
  vari()
  if(document.tic.sqr5.value == "     " && turn == 1)
  {
    document.tic.sqr5.value = " O "
    turn = 0
    sqr5T = 1
  }
  else if(document.tic.sqr1.value == "     " && turn == 1)
  {
    document.tic.sqr1.value = " O "
    turn = 0
    sqr1T = 1
  }
  else if(document.tic.sqr9.value == "     " && turn == 1)
  {
    document.tic.sqr9.value = " O "
    turn = 0
    sqr9T = 1
  }
  else if(document.tic.sqr6.value == "     " && turn == 1)
  {
    document.tic.sqr6.value = " O "
    turn = 0
    sqr6T = 1
  }
  else if(document.tic.sqr2.value == "     " && turn == 1)
  {
    document.tic.sqr2.value = " O "
    turn = 0
    sqr2T = 1
  }
  else if(document.tic.sqr8.value == "     " && turn == 1)
  {
    document.tic.sqr8.value = " O "
    turn = 0
    sqr8T = 1
  }
  else if(document.tic.sqr3.value == "     " && turn == 1)
  {
    document.tic.sqr3.value = " O "
    turn = 0
    sqr3T = 1
  }
  else if(document.tic.sqr7.value == "     " && turn == 1)
  {
    document.tic.sqr7.value = " O "
    turn = 0
    sqr7T = 1
  }
  else if(document.tic.sqr4.value == "     " && turn == 1)
  {
    document.tic.sqr4.value = " O "
    turn = 0
    sqr4T = 1
  }
  check2()
}

/*reset board*/
function reset()
{
  document.tic.sqr1.value = "     "
  document.tic.sqr2.value = "     "
  document.tic.sqr3.value = "     "
  document.tic.sqr4.value = "     "
  document.tic.sqr5.value = "     "
  document.tic.sqr6.value = "     "
  document.tic.sqr7.value = "     "
  document.tic.sqr8.value = "     "
  document.tic.sqr9.value = "     "
  sqr1T = 0
  sqr2T = 0
  sqr3T = 0
  sqr4T = 0
  sqr5T = 0
  sqr6T = 0
  sqr7T = 0
  sqr8T = 0
  sqr9T = 0
  vari()
  turn = 0
  moveCount = 0
}

function resetter()
{
  reset()
}
</SCRIPT>
    <h1 align="center">Tic Tac Toe</h1>
    <hr>
        
    <marquee behavior="scroll" direction="left" scrollamount="-30">⬇️⬇️ Hope you guys Enjoy the game 😊 ⬇️⬇️</marquee>
        
    <hr>

<FORM NAME="tic" method="post" align="center">

<INPUT TYPE="button" 
NAME="sqr1" 
class="tictac" value="     " onClick="if(document.tic.sqr1.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr1.value = ' X '; sqr1T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr1.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr1.value = ' X '; sqr1T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr1.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr1.value = ' O '; sqr1T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">

<INPUT TYPE="button" 
NAME="sqr2" 
class="tictac" value="     " onClick="if(document.tic.sqr2.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr2.value = ' X '; sqr2T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr2.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr2.value = ' X '; sqr2T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr2.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr2.value = ' O '; sqr2T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">
 
<INPUT TYPE="button" 
NAME="sqr3" 
class="tictac" value="     " onClick="if(document.tic.sqr3.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr3.value = ' X '; sqr3T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr3.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr3.value = ' X '; sqr3T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr3.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr3.value = ' O '; sqr3T = 1; turn = 1; vari(); player1Check()
 } drawCheck()"><br />
 
<INPUT TYPE="button" 
NAME="sqr4" 
class="tictac" value="     " onClick="if(document.tic.sqr4.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr4.value = ' X '; sqr4T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr4.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr4.value = ' X '; sqr4T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr4.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr4.value = ' O '; sqr4T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">
 
<INPUT TYPE="button" 
NAME="sqr5" 
class="tictac" value="     " onClick="if(document.tic.sqr5.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr5.value = ' X '; sqr5T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr5.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr5.value = ' X '; sqr5T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr5.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr5.value = ' O '; sqr5T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">
 
<INPUT TYPE="button" 
NAME="sqr6" 
class="tictac" value="     " onClick="if(document.tic.sqr6.value == '     ' && turn == 0 && mode == 1) {
document.tic.sqr6.value = ' X '; sqr6T = 1; turn = 1; vari(); check();
} 
else if(document.tic.sqr6.value == '     ' && turn == 1 && mode == 2) {
document.tic.sqr6.value = ' X '; sqr6T = 1; turn = 0; vari(); player1Check()
} 
else if(document.tic.sqr6.value == '     ' && turn == 0 && mode == 2) {
document.tic.sqr6.value = ' O '; sqr6T = 1; turn = 1; vari(); player1Check()
} drawCheck()"><br />

<INPUT TYPE="button" 
NAME="sqr7" 
class="tictac" value="     " onClick="if(document.tic.sqr7.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr7.value = ' X '; sqr7T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr7.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr7.value = ' X '; sqr7T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr7.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr7.value = ' O '; sqr7T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">
 
<INPUT TYPE="button" 
NAME="sqr8" 
class="tictac" value="     " onClick="if(document.tic.sqr8.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr8.value = ' X '; sqr8T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr8.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr8.value = ' X '; sqr8T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr8.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr8.value = ' O '; sqr8T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">

<INPUT TYPE="button" 
NAME="sqr9" class="tictac" value="     " onClick="if(document.tic.sqr9.value == '     ' && turn == 0 && mode == 1) {
 document.tic.sqr9.value = ' X '; sqr9T = 1; turn = 1; vari(); check();
 } 
 else if(document.tic.sqr9.value == '     ' && turn == 1 && mode == 2) {
 document.tic.sqr9.value = ' X '; sqr9T = 1; turn = 0; vari(); player1Check()
 } 
 else if(document.tic.sqr9.value == '     ' && turn == 0 && mode == 2) {
 document.tic.sqr9.value = ' O '; sqr9T = 1; turn = 1; vari(); player1Check()
 } drawCheck()">
 
</form>
    </body>
    <br /><br />
    <footer>
        &copy; All rights reserved by <a href="https://code.sololearn.com/WhEZu2Y95CIx/?ref=app">maDCoder πŸ’‰</a><br />
        Version 1.0 <em>License by <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">
        GNU General Public License</a></em>
    </footer>
    <script>
        alert("⬇️        ⬇️        ⬇️        ⬇️        ⬇️        ⬇️        ⬇️\n\n\n    If anyone wins assure me in comments 😁\n\n\n⬇️        ⬇️        ⬇️        ⬇️        ⬇️        ⬇️        ⬇️")
alert(" Instruction⬇️\n\n\nYou need to click on any square from the grid 3 X 3. While you click it represent 'x' then my AI function generate a '0' in any square of the grid depending on your input. This is how user input and my AI feedback go through.\n\nThe grid seems like that⬇️\n\n1       2       3\n\n4       5       6\n\n7       8       9\n\n➑️The Rule is simple. You must target to fill 3 consecutive 'x' in horizontally or vertically or might it be in a cross-section. My AI will never make you win 😁")
alert("DISCLAIMER⬇️\n\nTicTacToe v1.0\n\nBasically I am not a professional programmer nor a gammer at all. But I want to make a professional tic tac toe game which will be open source. This code will also help my further lessons in SoloLearn for being a professional programmer.\n\nThis is my first version and I just implement a classical UI and simple AI. I know it is very easy to beat down my AI but I assure you my upcomming versions will be harder and harder😁\n\nEnjoy guys and give your feedBack in comments section below⬇️")

$(function() {
    
});

        </script>
    </body>
       </html>
       
<!-- Special thanks to $__junayeDβ€Š ●_Β° -->

24. By …

Made by …. The program has two modes, 1 player and 2 Player mode, one player is with AI and two player is with another player. ( Source )

<!DOCTYPE html>
<html>
    <head>
        <title>Page Title</title>
        
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
      <style>
          body,
html {
  width: 100%;
  height: 100%;
}

li {
  list-style: none;
}

.outer-container {
  background: rgba(240,180,135,1);
  box-shadow: inset -1px 1px 7px rgba(0,0,0,.2), inset 1px -1px 7px rgba(0,0,0,.2), 1px 12px 5px rgba(0,0,0,.4), 4px 3px 8px rgba(0,0,0,.4), 5px 10px 10px rgba(0,0,0,.2), -5px 10px 10px rgba(0,0,0,.4);
  position: relative;
  border-radius: 10px;
  width: 400px;
  height: 390px;
  margin: 10% auto;
  padding: 40px 0 0;
}


.board-container {
  width: 350px;
  height: 350px;
  background: rgba(40,40,40,1)
    -webkit-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    -moz-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    -ms-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background-size: cover;
  position: relative;
  margin: 0 auto;
  overflow: hidden;
}

.game-board {
  width: 100%;
  height: 100%;
  margin: 0 auto;
  position: relative;
}

.boxes {
  padding: 0;
  width: 100%;
  height: 100%;
  position: relative;
  left: 12px;
  top: 0;
}

.boxes li {
  width: 30%;
  height: 30%;
  display: inline-block;
  position: relative;
  z-index: 1000;
  margin-left: 2px;
  margin-right: 2px;
  overflow: hidden;
}

li i {
  font-size: 6.5rem;
  text-align: center;
  display: block;
  width: 100%;
  height: 100%;
  font-style: normal;
  font-family: "Architects Daughter", "Helvetica", "sans-serif";
  color: rgba(220,220,220,.7);
  z-index: 500;
}

li span {
  position: relative;
  bottom: 15px;
}

/* Canvas Drawing */

#myCanvas {
  width: 330px;
  height: 330px;
  position: absolute;
  z-index: 0;
  left: 10px;
  top: 0;
  opacity: 0;
}

/* Player/Computer prompt */
.player-one-turn {
  background: rgba(0,200,200,1);
  left: 15px;
}

.player-two-turn {
  background: rgba(200,100,100,1);
  right: 15px;
}

.player-one-turn,
.player-two-turn {
  position: absolute;
  top: 0;
  width: 170px;
  height: 50px;
  z-index: -10;
  color: white;
  text-align: center;
}

.player-one-turn p,
.player-two-turn p {
  font-size: 1.3rem;
  margin-top: 10px;
}

/* Score keeping */
.points-divider,
.score-1,
.score-2 {
  position: absolute;
  font-size: .9rem;
  margin: 0;
  display: none;
}

.score-1,
.score-2 {
  font-family: 'Architects Daughter', sans-serif;
  top: 17px;
  color: rgba(100,60,50,.8);
}

.score-1 .points, 
.score-2 .points {
  position: absolute;
  text-align: center;
  bottom: 14px;
  color: rgba(100,60,50, .9);
  font-family: 'Architects Daughter', sans-serif;
}

.points-divider {
  top: 5px;
  left: 141px;
  font-size: 2rem;
  font-family: helvetica, sans-serif;
  font-style: normal;
  opacity: .2;
}

.score-1 {
  left: 75px;
}

.score-2 {
  left: 161px;
}

/* reset button */
.hard-reset {
  position: absolute;
  top: 5px;
  right: 20px;
  background: none;
  border: none;
  font-family: 'Architects Daughter', sans-serif;
  color: rgba(100,60,50,.8);
  font-size: 1.1rem;
  border-radius: 20px;
  border: 2px dashed transparent;
  display: none;
}

.hard-reset:hover {
  border: 2px dashed rgba(100,60,50,1);
  color: rgba(100,60,50,1);
}

.hard-reset:focus {
  outline: none;
}

/*  Result Feedback */
span.rotate {
  color: rgba(0,200,200,1);
}

i.win {
  background: black;
}

.draw-message,
.lose-message,
.win-message {
  background: rgba(0,0,0,.8);
  width: 400px;
  height: 400px;
  z-index: 2000;
  position: absolute;
  display: none;
  top: -15px;
  left: 0;
  box-sizing: border-box;
}

.draw-message p,
.lose-message p,
.win-message p {
  color: white;
  text-align: center;
  position: absolute;
  font-size: 2.3rem;
  margin: 0;
  top: 150px;
  left: 50px;
  font-family: 'Architects Daughter', sans-serif;
}

/*============================================
          Game Starter
============================================*/

.game-choice,
.game-starter {
  background: rgba(40,40,40,1)
    -webkit-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    -moz-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    -ms-radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  background: rgba(40,40,40,1)
    radial-gradient(center, rgba(40,80,60,1), rgba(0,20,20,.6));
  
  display: block;
  width: 100%;
  height: 500px;
  position: absolute;
  top: 0px;
  text-align: center;
  font-family: 'Architects Daughter', Helvetica, sans-serif;
  z-index: 1500;
/*  display: none;*/
}

.game-starter {
  display: none;
}

.game-choice p,
.game-starter p {
  font-size: 2.2rem;
}

.game-choice button,
.game-choice p,
.game-starter button,
.game-starter p {
  color: rgba(220,220,220,1);
  position: relative;
  top: 50px;
  margin: 10px auto;
}

.game-choice p,
.game-starter p {
  max-width: 80%;
}

.game-choice button,
.game-starter button {
  background: none;
  border: none;
  opacity: .6;
  border-radius: 20px;
  border: 2px solid transparent;
  font-size: 1.7rem;
}

.game-starter button {
   font-size: 2.8rem;
}

.game-choice button:focus,
.game-starter button:focus {
  outline: none;
}
.game-choice button:hover,
.game-starter button:hover {
  opacity: 1;
  border: 2px dashed rgba(230,230,230,.5);
}

.game-starter button.back-button  {
  position: absolute;
  top: 270px;
  right: 130px;
  font-size: 1.5rem;
  border: none;
}

.game-starter .back-button:hover {
  border: none;
}

button {
  cursor: pointer;
}

/*============================
    Win/Lose animation 
==============================*/
.rotate {
  -webkit-animation: rotating 2s linear infinite;
  -moz-animation: rotating 2s linear infinite;
  -ms-animation: rotating 2s linear infinite;
  -o-animation: rotating 2s linear infinite;
  animation: rotating 2s linear infinite;
}

@-webkit-keyframes rotating /* Safari and Chrome */ {
  from {
    -ms-transform: rotateY(0deg);
    -moz-transform: rotateY(0deg);
    -webkit-transform: rotateY(0deg);
    -o-transform: rotateY(0deg);
    transform: rotateY(0deg);
  }
  to {
    -ms-transform: rotateY(360deg);
    -moz-transform: rotateY(360deg);
    -webkit-transform: rotateY(360deg);
    -o-transform: rotateY(360deg);
    transform: rotateY(360deg);
  }
}
@keyframes rotating {
  from {
    -ms-transform: rotateY(0deg);
    -moz-transform: rotateY(0deg);
    -webkit-transform: rotateY(0deg);
    -o-transform: rotateY(0deg);
    transform: rotateY(0deg);
  }
  to {
    -ms-transform: rotateY(360deg);
    -moz-transform: rotateY(360deg);
    -webkit-transform: rotateY(360deg);
    -o-transform: rotateY(360deg);
    transform: rotateY(360deg);
  }
}
          </style>
      </head>
    <body>
      <div class="outer-container">
  <button class="hard-reset">Reset All</button>
  <p class="score-1"><span class="points"></span><span class="name"></span></p>
  <i class="points-divider">&#124;</i>
  <p class="score-2"><span class="points"></span><span class="name"></span></p>
  <div class="player-one-turn">
    <p></p>
  </div>
  <div class="player-two-turn">
    <p></p>
  </div>
  <div class="board-container">
    <div class="game-starter">
        <p>Would you like to be X or O?</p>
        <button class="choose-x">X</button>
        <button class="choose-o">O</button>
        <button class="back-button"><i class="fa fa-arrow-left"></i> Back</button>
      </div>
      <div class="game-choice">
        <p>How do you want to play?</p>
        <button class="one-player">One Player</button>
        <button class="two-player">Two Player</button>
      </div>
    <div class="game-board">
      <div class="draw-message">
        <p>It was a draw..</p>
      </div>
      <div class="lose-message">
        <p>Uh oh, you lost..</p>
      </div>
      <div class="win-message">
        <p>You Won!!! :)</p>
      </div>
      <canvas id="myCanvas"></canvas>
      <ul class="boxes">
      </ul>
    </div>
  </div>
</div>
<script>
    var MYAPP = MYAPP || {
  gameInPlay: false,
  winCombos: [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [1, 4, 7],
    [2, 5, 8],
    [3, 6, 9],
    [1, 5, 9],
    [7, 5, 3]
  ],
  playerOneScore: 0,
  playerTwoScore: 0,
  timeOuts: [],
  initializeVars: function() {
    this.numFilledIn = 0;
    this.currentBoard = {
      1: '',
      2: '',
      3: '',
      4: '',
      5: '',
      6: '',
      7: '',
      8: '',
      9: ''
    };
  },
  initializeGame: function() {
    MYAPP.initializeVars();
    MYAPP.display.drawBoard();
    $('.game-choice button').click(function() {
      MYAPP.secondPlayer = MYAPP.game.gameSelection(this);
      MYAPP.display.hideGameChoice();
      MYAPP.display.showGameStarter(MYAPP.secondPlayer);
      $('.game-starter .choose-x, .game-starter .choose-o').off().click(MYAPP.game.firstGame);

      $('.back-button').on('click', function() {
        MYAPP.display.hideGameStarter();
        MYAPP.display.showGameChoice();
      });
    });
    $('.hard-reset').on('click', MYAPP.game.resetGame);
  }
};

  /*=========================
      Display functions
==========================*/
MYAPP.display = {  
  hideGameStarter: function() {
  $('.game-starter').fadeOut();
},

  showGameStarter: function(isTwoPlayer) {
  var message;
  if (isTwoPlayer) {
    message = "Player 1 : Would you like X or O?"
  }
  else {
    message = "Would you like to be X or O?";
  }
  MYAPP.timeOuts.push(
    setTimeout(function() {
      $('.game-starter').fadeIn(500).children('p').text(message);
  }, 700));
},

  showGameChoice: function() {
  $('.game-choice').fadeIn(600);
},

  hideGameChoice: function() {
  $('.game-choice').fadeOut(600);
},

  showPlayerOnePrompt: function() {
  if (MYAPP.secondPlayer) {
    $('.player-one-turn p').text('Go Player 1!');
  }
  else {
    $('.player-one-turn p').text('Your turn!');
  }
  $('.player-one-turn').animate({'top': '-45px'}, 500);
},

  hidePlayerOnePrompt: function() {
  $('.player-one-turn').animate({'top': '0'}, 500);
},

  showPlayerTwoPrompt: function() {
  if (MYAPP.secondPlayer) {
    $('.player-two-turn p').text('Go Player 2!');
  }
  else {
    $('.player-two-turn p').text('Computer\'s turn');
  }
  $('.player-two-turn').animate({'top': '-45px'}, 500);
},

  hidePlayerTwoPrompt: function() {
  $('.player-two-turn').animate({'top': '0'}, 500);
},

  showDrawMessage: function() {
  MYAPP.timeOuts.push(
    setTimeout(function() {
    $('.draw-message').fadeIn(500);
  }, 1500));
},

  hideDrawMessage: function() {
  $('.draw-message').fadeOut(1000);
},

  showLoseMessage: function() {
    MYAPP.timeOuts.push(
      setTimeout(function() {
    $('.lose-message').fadeIn(500);
}, 1500)
    );
},

  hideLoseMessage: function() {
  $('.lose-message').fadeOut(1000);
},

  showWinMessage: function() {
    MYAPP.timeOuts.push(
      setTimeout(function() {
    $('.win-message').fadeIn(500).children('p').text("Player " + MYAPP.turn + " wins!! :D ")
}, 1500));
},

  hideWinMessage: function() {
  $('.win-message').fadeOut(1000);
},

  drawBoard: function() {
    MYAPP.timeOuts.push(setTimeout(function() {
    var c = document.getElementById("myCanvas");
    var canvas = c.getContext("2d");
    canvas.lineWidth = 1;
    canvas.strokeStyle = "#fff";
    //vertical lines
    canvas.beginPath();
    canvas.moveTo(100, 0);
    canvas.lineTo(100, 146.5);
    canvas.closePath();
    canvas.stroke();
    canvas.beginPath();
    canvas.moveTo(200, 0);
    canvas.lineTo(200, 146.5);
    canvas.closePath();
    canvas.stroke();

    // horizontal lines
    canvas.lineWidth = .5;

    canvas.beginPath();
    canvas.moveTo(4, 48.5);
    canvas.lineTo(296, 48.5);
    canvas.closePath();
    canvas.stroke();
      
    canvas.beginPath();
    canvas.moveTo(4, 98.5);
    canvas.lineTo(296, 98.5);
    canvas.closePath();
    canvas.stroke();  
  }, 1500));
},

  resetSquares: function() {
  $('.boxes').html('');
  for (var i = 1; i <= 9; i++) {
    var box = '<li class="' + i + '"><i class="letter"><span></span></i></li>';
    $(box).appendTo($('.boxes'));
  }
},
  
  showScore: function() {
    if (MYAPP.secondPlayer) {
      $('.score-1').children('.name').text('player 1'); 
      $('.score-2').children('.name').text('player 2'); 
    }
    else {
      $('.score-1').children('.name').text('player 1'); 
      $('.score-2').children('.name').text('computer'); 
    }
    $('.score-1, .score-2').children('.points').text('0');
    $('.score-1,.score-2, .points-divider').fadeIn();
  },
  updateScore: function(turn) {
    var currentScore = turn === 1 ? MYAPP.playerOneScore : MYAPP.playerTwoScore;

    $('.score-' + turn).children('.points').text(currentScore);
  }
};

/*=========================
      Game Logic
==========================*/
MYAPP.game = {
  whoStarts: function() {
    var random = Math.floor(Math.random() * 2 + 1);
    return random;
  },
  gameSelection: function(item) {
    if ($(item).text() === 'One Player') {
      // returns what secondPlayer value to set
      return false;
    }
    else {
      return true;
    } 
  },
  firstGame: function() {
    MYAPP.playerOneSymbol = $(this).text();
    MYAPP.playerTwoSymbol = MYAPP.playerOneSymbol == 'X' ? 'O' : 'X'; 
    MYAPP.turn = MYAPP.game.whoStarts();
    MYAPP.display.hideGameStarter();
    $('#myCanvas').animate({'opacity': '1'}, 1200);
    $('.hard-reset').fadeIn(600);
    MYAPP.display.showScore();
    MYAPP.display.resetSquares();
    MYAPP.game.play();
  },
  play: function() {
    
    MYAPP.gameInPlay = true;
    $('.boxes li').on('click', function() {
     MYAPP.game.playerTurn(this);
    });  
    
    MYAPP.timeOuts.push(
      setTimeout(function(){
      if (MYAPP.turn === 1) {
        MYAPP.display.showPlayerOnePrompt();
      }
      else if (MYAPP.turn === 2) {
        MYAPP.display.showPlayerTwoPrompt();
      }
    }, 1500),
    setTimeout(function() {
      if (MYAPP.turn === 2 && !MYAPP.secondPlayer) {
        MYAPP.game.computerPlay();
      }
    }, 1200));
  },
  playerTurn: function(square) {
    var symbol = MYAPP.turn === 1 ? MYAPP.playerOneSymbol : MYAPP.playerTwoSymbol;
    var box = $(square).children('i').children('span');
    if (box.text() === '' && MYAPP.gameInPlay && (MYAPP.turn === 1 || (MYAPP.turn === 2 && MYAPP.secondPlayer))) {
      box.text(symbol);
      var number = $(square).attr('class');
      MYAPP.game.updateSquare(number, symbol);
      MYAPP.game.endTurn(symbol);
    }
  },
  computerPlay: function() {
    var computer = MYAPP.computer;
    //test computer move suggestion
    var boxNumber;
    if (computer.computerWhichMove(MYAPP.game) && MYAPP.turn === 2) {
      boxNumber = computer.computerWhichMove(MYAPP.game);
      var currentBox = $('.' + boxNumber).children('i');
      
      var symbol = MYAPP.playerTwoSymbol;

      MYAPP.timeOuts.push(
        setTimeout(function() {
        currentBox.children('span').text(symbol);
        MYAPP.game.updateSquare(boxNumber, MYAPP.playerTwoSymbol);
        MYAPP.game.endTurn(symbol);
      }, 1000));
    } 
  },
  endTurn: function(symbol) {
    MYAPP.numFilledIn = MYAPP.numFilledIn + 1;
    if (MYAPP.gameInPlay) {
      if (MYAPP.game.checkWin(symbol)[0]) {
        MYAPP.game.updateScore(MYAPP.turn);
        if (MYAPP.secondPlayer) {
          MYAPP.display.showWinMessage();
        }
        else {
          MYAPP.turn === 1 ? MYAPP.display.showWinMessage() : MYAPP.display.showLoseMessage();
        }
        MYAPP.gameInPlay = false;
        MYAPP.game.showWinningCombination();
        MYAPP.display.hidePlayerOnePrompt();
        MYAPP.display.hidePlayerTwoPrompt();
        MYAPP.game.reset();
      }
      // stop if it is a draw
      else if (MYAPP.numFilledIn >= 9) {
        MYAPP.gameInPlay = false;
        MYAPP.display.hidePlayerOnePrompt();
        MYAPP.display.hidePlayerTwoPrompt();
        MYAPP.display.showDrawMessage();
        MYAPP.turn = MYAPP.game.whoStarts();
        MYAPP.game.reset();
      } else {
        if (MYAPP.turn === 1) {
          MYAPP.display.hidePlayerOnePrompt();
          MYAPP.display.showPlayerTwoPrompt();
          MYAPP.turn = 2;
          // call computer turn if no second player
          if (!MYAPP.secondPlayer) {
            MYAPP.game.computerPlay();
          }
        } else if (MYAPP.turn === 2) {
          MYAPP.display.showPlayerOnePrompt();
          MYAPP.display.hidePlayerTwoPrompt();
          MYAPP.turn = 1;
        }
      }
    }
  },
  updateSquare: function(number, symbol) {
    MYAPP.currentBoard[number] = symbol;
  },
  checkWin: function(symbol) {
    var currentBoard = MYAPP.currentBoard;
    var wins = MYAPP.winCombos;
    var winningCombo = [];
    var winner = wins.some(function(combination) {
      var winning = true;
      for (var i = 0; i < combination.length; i++) {
        if (currentBoard[combination[i]] !== symbol) {
          winning = false;
        }
      }
      if (winning) {
        winningCombo = combination;
      }
      return winning;
    });
    return [winner, winningCombo];
  },
  showWinningCombination: function() {
    var symbol = MYAPP.turn === 1 ? MYAPP.playerOneSymbol : MYAPP.playerTwoSymbol;
    var combo = MYAPP.game.checkWin(symbol)[1];
    for (var i = 0; i < combo.length; i++) {
      var currentBox = '.' + combo[i]; 
   // Black box and rotating test for winning combo  
        $(currentBox).children('i').addClass('win').children('span').addClass('rotate');
     }
  },
  updateScore: function(turn) {
    turn === 1 ? MYAPP.playerOneScore += 1 : MYAPP.playerTwoScore += 1; 
    
    MYAPP.display.updateScore(turn);
    
  },
  reset: function() {
    MYAPP.initializeVars();
    
    MYAPP.timeOuts.push(
      setTimeout(function() {
        MYAPP.display.hideDrawMessage();
        MYAPP.display.hideLoseMessage();
        MYAPP.display.hideWinMessage();
        $('.boxes li').fadeOut();
      }, 5000),
      setTimeout(function(){
        MYAPP.display.resetSquares();
        $('.boxes li').fadeIn();
        MYAPP.numFilledIn = 0;
      }, 6000),
    //Make sure time for next timeout is long enough
    //to not cause problems after first game
      setTimeout(function() {
        MYAPP.gameInPlay = true;
        MYAPP.game.play();
      }, 6000)
      );
  },
  resetGame: function() {
    $('#myCanvas').css('opacity', '0');
    $('.hard-reset').fadeOut();
    $('.points-divider, .score-1, .score-2').fadeOut();
    MYAPP.playerOneScore = 0;
    MYAPP.playerTwoScore = 0;
    MYAPP.display.resetSquares();
    MYAPP.initializeVars();
    MYAPP.gameInPlay = false;
    MYAPP.playerOneSymbol = null;
    MYAPP.playerTwoSymbol = null;
    MYAPP.timeOuts.forEach(function(timer) {
      clearTimeout(timer);
    });
    $('.draw-message, .win-message, .lose-message').hide();
    MYAPP.display.hidePlayerOnePrompt();
    MYAPP.display.hidePlayerTwoPrompt();
    MYAPP.display.showGameChoice();
  }
};

/* End Game Logic */
  
/*================================
    Computer Move Decisions
=================================*/    

MYAPP.computer = {
  computerWhichMove: function () {
    var move = this.winOrBlockChoice('win')[0];
    if (!move) {
      move = this.winOrBlockChoice('block')[0]; }
    if (!move) {
      move = this.doubleThreatChoice('win');
    }
    if (!move) {
      move = this.doubleThreatChoice('block');
    }
    if (!move) {
      move = this.firstPlay();
    }
    if (!move) {
      move = this.playCenter();
    }
    if (!move) {
      move = this.emptyCorner();
    }
    if (!move) {
      move = this.emptySide();
    }
    move = (move && MYAPP.currentBoard[move]) === '' ? move : false;
    return move;
  },

  winOrBlockChoice: function(choiceType, board) {
    var board = board || MYAPP.currentBoard;
    if (choiceType === 'win') {
      var currentSymbol = MYAPP.playerTwoSymbol;
      var opponentSymbol = MYAPP.playerOneSymbol;
    } else if (choiceType === 'block') {
      var currentSymbol = MYAPP.playerOneSymbol;
      var opponentSymbol = MYAPP.playerTwoSymbol;
    } else {
      return;
    }
    var moves = [];
    MYAPP.winCombos.forEach(function(combo) {
      var notFound = [];
      var notPlayer = true;
      for (var i = 0; i < combo.length; i++) {
        if (board[combo[i]] !== currentSymbol) {
          if (board[combo[i]] === opponentSymbol) {
            notPlayer = false;
          } else {
            notFound.push(combo[i]);
          }
        }
      }
      if (notFound.length === 1 && notPlayer) {
        var move = notFound[0];
        moves.push(move);
      }
    });
    return moves;
},

  doubleThreatChoice: function(choiceType) {
  // use winChoice function to test a spot for double threat
  var board = MYAPP.currentBoard;
  var move;

  if (choiceType === 'win') {
    var currentSymbol = MYAPP.playerTwoSymbol;
    var opponentSymbol = MYAPP.playerOneSymbol;
  } else if (choiceType === 'block') {
    var currentSymbol = MYAPP.playerOneSymbol;
    var opponentSymbol = MYAPP.playerTwoSymbol;
  }

  // forced diagonal win on 4th move prevention
    if (board[5] === currentSymbol && MYAPP.numFilledIn === 3) {
      if ((board[1] === opponentSymbol && board[9] === opponentSymbol) || (board[3] === opponentSymbol && board[7] === opponentSymbol)) {
        // Play an edge to block double threat
        move = this.emptySide();
      }
    }
  
    if (!move && board[5] === opponentSymbol && MYAPP.numFilledIn === 2) {
      move = this.diagonalSecondAttack();
    }

  if (!move) {
    // clone current board;
    var testBoard = $.extend({}, board);
    for (var i = 1; i <= 9; i++) {

      testBoard = $.extend({}, board);
      if (testBoard[i] === '') {
        testBoard[i] = currentSymbol;
        if (this.winOrBlockChoice(choiceType, testBoard).length >= 2) {
          move = i;
        }
      }
    }
  }
  return move || false;
},

  diagonalSecondAttack: function() {
  var board = MYAPP.currentBoard;
  var comp = MYAPP.playerTwoSymbol;
  var corners = [1,3,7,9];
  for (var i = 0; i < corners.length; i++) {
    if (board[corners[i]] === comp) {
      return 10 - corners[i];
    }
  }
},

  firstPlay: function() {
  var board = MYAPP.currentBoard;
  var corners = [1, 3, 7, 9];
  var move;
  if (MYAPP.numFilledIn === 1) {
    // player plays center
    if (board[5] === MYAPP.playerOneSymbol) {
      var cornerNum = Math.floor(Math.random() * 4 + 1);
      move = [1, 3, 7, 9][cornerNum];
    }
    //player plays corner, play opposite corner
    else {
      for (var i = 0; i < corners.length; i++) {
        if (MYAPP.currentBoard[corners[i]] === MYAPP.playerOneSymbol) {
          move = 5;
        }
      }
    }
  } else if (MYAPP.numFilledIn === 0) {
    var cornerNum = Math.floor(Math.random() * corners.length + 1);
    move = corners[cornerNum];
  }
  return move ? move : false;
},
  
  playCenter: function() {
    if (MYAPP.currentBoard[5] === '') {
      return 5;
    }
  },
  emptyCorner: function() {
var board = MYAPP.currentBoard;
  var corners = [1, 3, 7, 9];
  var move;
  for (var i = 0; i < corners.length; i++) {
    if (board[corners[i]] === '') {
      move = corners[i];
    }
  }
  return move || false;
},

  emptySide: function() {
  var sides = [2, 4, 6, 8];
  for (var i = 0; i < sides.length; i++) {
    if (MYAPP.currentBoard[sides[i]] === '') {
      return sides[i];
    }
  }
  return false;
}
}

/* End Computer Move Decisions */  

$(document).ready(function() {  
  MYAPP.initializeGame();
});
    </script>
    </body>
</html>

25. By Kartikey Sahu

Made by Kartikey Sahu. JavaScript tic tac toe with scoreboard and option to enter your name. ( Source )

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Tic Tac Toe</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://fonts.googleapis.com/css?family=Muli:400" rel="stylesheet"> 
<style>
    html,
body {
  margin: 0;
  height: 100vh;
  width: 100vw;
  font-family: 'Muli', sans-serif;
  user-select: none;
}

body {
  display: grid;
  grid-template: auto 512px auto / auto 360px auto;
}

#root {
  grid-column-start: 2;
  grid-row-start: 2;
  display: grid;
  grid-template-rows: repeat(3, 3.3fr) 1.1fr;
  border: 1px solid;
}

header {
  font-size: 36px;
  display: grid;
  align-content: center;
  justify-content: center;
}

#base {
  display: grid;
  grid-template: auto 124px auto / auto 124px auto;
}

footer {
  border-bottom: 1px solid;
  display: grid;
  grid-template-columns: 1fr 1fr;
}

footer div {
  display: grid;
  align-content: center;
  justify-content: center;
}

footer div {
  font-size: 32px;
}

#undo,
#board,
#redo {
  grid-row-start: 2;
  display: grid;
  align-content: center;
  justify-content: center;
}

#board {
  grid-template: repeat(3, 40px) / repeat(3, 40px);
  background: #999;
  grid-gap: 1px;
  padding: 1px;
}

button {
  background: white;
  border: 0 none;
  font: inherit;
  transition-duration: 0.3s;
}

#board button:focus {
  outline: 1px dashed #333;
}

#player {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-gap: 1px;
  background: #333;
}

#player div {
  display: grid;
  align-content: center;
  justify-content: center;
}

#player-a,
#player-b {
  transition-duration: 0.3s;
  background-color: lightblue;
}
    </style>
</head>

<body>
  <div id="root">
    <header>Tic Tac Toe</header>
    <div id="base">
      <div id="undo">
        <button onclick="ttt.clear()">Clear</button>
      </div>
      <div id="board">
        <button></button>
        <button></button>
        <button></button>
        <button></button>
        <button></button>
        <button></button>
        <button></button>
        <button></button>
        <button></button>
      </div>
      <div id="redo">
        <button onclick="ttt.newGame()">Restart</button>
      </div>
    </div>
    <footer>
      <div id="score-a">3</div>
      <div id="score-b">5</div>
    </footer>
    <div id="player">
      <div id='player-a'>Player A</div>
      <div id='player-b'>Player B</div>
    </div>
  </div>
  <script>
      alert("X for first player and O for second player")
var
  winWhen = [
    [0, 1, 2],
    [0, 3, 6],
    [0, 4, 8],
    [1, 4, 7],
    [2, 4, 6],
    [2, 5, 8],
    [3, 4, 5],
    [6, 7, 8]
  ],

  ttt = {
    scoreA: 0,
    scoreB: 0,
    playerA: 'Player A',
    playerB: 'Player B',
    state: [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    now: 'X',
    pA: '',
    pB: '',
    sA: '',
    sB: '',
    enabled: true
  },
  btn;

ttt.playerA = prompt("Enter the name of first player", ttt.playerA);
ttt.playerB = prompt("Enter the name of second player", ttt.playerB);

window.onload = function () {
  ttt.pA = document.getElementById('player-a');
  ttt.pB = document.getElementById('player-b');
  ttt.sA = document.getElementById('score-a');
  ttt.sB = document.getElementById('score-b');

  ttt.pA.innerText = ttt.playerA == null ? 'Player A' : ttt.playerA
  ttt.pB.innerText = ttt.playerB == null ? 'Player B' : ttt.playerB

  ttt.sA.innerText = ttt.scoreA;
  ttt.sB.innerText = ttt.scoreB;

  btn = document.querySelectorAll('#board button')
  
  btn[0].addEventListener('click', function(){ttt.clicked(0)})
  btn[1].addEventListener('click', function(){ttt.clicked(1)})
btn[2].addEventListener('click', function(){ttt.clicked(2)})
  btn[3].addEventListener('click', function(){ttt.clicked(3)})
  btn[4].addEventListener('click', function(){ttt.clicked(4)})
  btn[5].addEventListener('click', function(){ttt.clicked(5)})
btn[6].addEventListener('click', function(){ttt.clicked(6)})
  btn[7].addEventListener('click', function(){ttt.clicked(7)})
  btn[8].addEventListener('click', function(){ttt.clicked(8)})
}

ttt.clicked = function (i) {
  if (ttt.state[i] === -1  && ttt.enabled) {
    ttt.state[i] = ttt.now;
    for (var i = 0; i < 9; i++) {
      var value = ttt.state[i];
      if (value !== -1) {
        btn[i].innerText = value;
      }
    }
    var won = ttt.hasWon();
    if (won) {
      if (ttt.now === 'X') {
        ttt.scoreA++;
        ttt.sA.innerText = ttt.scoreA;
      } else {
        ttt.scoreB++;
        ttt.sB.innerText = ttt.scoreB;
      }
      if (ttt.scoreA > ttt.scoreB) {
        ttt.pA.style.backgroundColor = 'greenyellow';
        ttt.pB.style.backgroundColor = 'lightcoral';
      } else if (ttt.scoreA === ttt.scoreB) {
        ttt.pA.style.backgroundColor = 'lightblue';
        ttt.pB.style.backgroundColor = 'lightblue';
      } else {
        ttt.pB.style.backgroundColor = 'greenyellow';
        ttt.pA.style.backgroundColor = 'lightcoral';
      }
    }
    ttt.now = (ttt.now === 'X') ? 'O' : 'X';
  }
}

ttt.hasWon = function () {
  for (var g = 0; g < winWhen.length; g++) {
    if (
      btn[winWhen[g][0]].innerText != '' &&
      btn[winWhen[g][1]].innerText != '' &&
      btn[winWhen[g][2]].innerText != ''
    ) {
      if (
        btn[winWhen[g][0]].innerText == btn[winWhen[g][1]].innerText &&
        btn[winWhen[g][1]].innerText == btn[winWhen[g][2]].innerText
      ) {
        for (k = 0; k < 3; k++) {
          btn[winWhen[g][k]].style.background = "gold"
        }
        ttt.enabled = false
        window.setTimeout(ttt.clear, 1000);
        return true;
      }
    }
  }
  if(ttt.state.indexOf(-1) == -1){
      setTimeout(ttt.clear, 300)
  }
  return false;
}

ttt.fill = function () {
  for (var i = 0; i < 9; i++) {
    btn[i].innerText = '';
  }
}

ttt.clear = function () {
  for (var i = 0; i < 9; i++) {
    btn[i].style.backgroundColor = '#fff'
  }
  ttt.state = new Array(9).fill(-1);
  ttt.fill();
  ttt.now = 'X';
  ttt.enabled = true;
}

ttt.newGame = function () {
  ttt.clear();
  ttt.scoreA = ttt.scoreB = 0;
  ttt.sA.innerText = 
  ttt.sB.innerText = 0;
  ttt.pA.style.backgroundColor = 'lightblue';
  ttt.pB.style.backgroundColor = 'lightblue';
}
      </script>
</body>
</html>