JSFiddle - React, Tailwind, and code Playground

by oneangrypenguin

HTML

<!doctype html>
<html lang="en">

  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
    <title>Tic Tac Toe</title>
  </head>

  <body>
    <nav class="navbar navbar-expand-sm navbar-dark bg-dark">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Tic-Tac-Toe</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDarkDropdown" aria-controls="navbarNavDarkDropdown" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNavDarkDropdown">
          <ul class="navbar-nav">
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbarDarkDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                New Game
              </a>
              <ul id="newGame" class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDarkDropdownMenuLink">
                <li><a class="dropdown-item" href="#">3x3</a></li>
                <li><a class="dropdown-item" href="#">4x4</a></li>
                <li><a class="dropdown-item" href="#">5x5</a></li>
       ...

JavaScript

let game

function Tile(row, x, y) {
  const that = this
  const element = $("<div class='card border-dark m-1 text-white bg-dark tile h1 align-middle card-block' id='" + x + "x" + y + "' style='width:5rem; height: 5rem;'><span class='card-body text-center'></span></div>").appendTo(row).get(0)
  this.owner = 0

  $(element).click(onClick)

  this.disable = function() {
    $(element).off("click")
  }

  function onClick() {
    that.owner = game.currentPlayer

    let text = that.owner === 1 ? "X" : "0"

    $(element).children().first().text(text)
    that.disable()
    game.nextTurn()
  }

}

function Game(boardSize) {
  let size = boardSize
  this.currentPlayer = 0

  let board = []

  function createGrid() {
    $("#board").empty()
    for (let i = 0; i < size; i++) {
      let row = $("<div class='row row-cols-" + size + "'> </div>").appendTo("#board")
      board[i] = []
      for (let j = 0; j < size; j++) {
        board[i][j] = new Tile(row, i, j)
      }
      row.append("<div class='w-100'></div>")
    }
    $("#message").removeClass("alert-success")
    $("#message").addClass("alert-secondary")

  }

  this.nextTurn = function() {
    let winner = this.checkWinner()

    if (winner > 0) {
      $("#message").text("Player " + winner + " wins!")
      $("#message").addClass("alert-success")
      $("#message").removeClass("alert-secondary")
    } else {
      if (this.currentPlayer === 1) {
        this.currentPlayer = 2
        $("#message").text("Player 2")

      } else {
        this.currentPlayer = 1
        $("#message").text("Player 1")
      }
    }
  }

  this.checkWinner = function() {
    function horizontal() {

      let winner = 0

      board.forEach((item, ind) => {
        let check = checkArray(item)
        if (check != 0) winner = check
      })
      return winner
    }

    function vertical() {
      for (let i = 0; i < size; i++) {
        let arr = board.map((item) => {
          return item[i]
        })

        let winner =...