JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<div class="wrap">
    <div id="ttti"></div>
</div>
<button id="resetGame">Reset Game</button>

SCSS

@mixin clearfix(){
    &:before{
        content: '';
        display: table;
    }
    &:after{
        content: '';
        clear: both;
        display: block;
    }
}

$color-o: #8058a3;
$color-x: #edc455;

label{
    display: block;
}

#ttti{
    width: 100%;
    max-width: 500px;
    position: relative;
    margin: 0 auto;
    clear: both;
    @include clearfix;
    & > div{
        width: 33.33%;
        float: left;
        background-color: #fff;
        transition: background-color 300ms;
        border: 1px solid #ccc;
        padding: 1px;
        margin-right: -1px;
        margin-bottom: -1px;
        position: relative;
        @include clearfix;
        perspective: 350px;
        & > span{
            display: block;
            width: 33.33%;
            float: left;
            padding-top: 33.33%;
            position: relative;
            cursor: pointer;
            transform-style: preserve-3d;
            transform-origin: center center;
            transform: rotateX(0deg);
            transition: transform 300ms;
            &:after,
            &:before{
                content: '';
                position: absolute;
                top: 1px;
                bottom: 1px;
                right: 1px;
                left: 1px;
                background-color: #e9e9e9;
                transition: background-color 300ms;
                z-index: 2;
                backface-visibility: hidden;
            }
            &:after{
                z-index: 1;
                transform: rotateX(180deg);
            }
            &:hover,
            &:focus{
                &:before{
                    background-color: #f5f5f5;
                }
            }
            &.marked{
                cursor: default;
                transform: rotateX(180deg);
                z-index: 3;
            }
            &.o:after{
                background-color: $color-o;
            }
            &.x:after{
                background-color:...

JavaScript

/**
 * TTTI
 */

var ttti = {
    wrap: document.getElementById('ttti'),
    init: function () {
        ttti.buildGrid();
        ttti.updateGrid();
    },
    buildGrid: function () {
        for (var i = 0; i < 9; i++) {
            var subGame = document.createElement('div');
            subGame.setAttribute('class', 'g-' + (i + 1));
            for (var n = 0; n < 9; n++) {
                var tile = document.createElement('span');
                tile.setAttribute('class', 't-' + (n + 1));
                tile.addEventListener('click', function () {
                    ttti.clickHandle(this);
                });
                subGame.appendChild(tile);
            }
            ttti.wrap.appendChild(subGame);
        }
    },
    updateGrid: function () {
        for (var i = 1; i <= 9; i++) {
            if (ttti.game.obj[i]) {
                for (var n = 1; n <= 9; n++) {
                    if (ttti.game.obj[i][n]) {
                        var tile = ttti.wrap.querySelector('.g-' + i + ' .t-' + n);
                        if (!tile.className.match(/\s(marked)/i)) {
                            tile.className = tile.className + ' marked ' + ttti.game.obj[i][n].replace(/[^a-z0-9]*/ig, '');
                        }
                    }
                }
            }
        }
        ttti.subGameHighlight();
        ttti.checkWins();
    },
    checkWins: function () {
        var combinations = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
            [1, 4, 7],
            [2, 5, 8],
            [3, 6, 9],
            [1, 5, 9],
            [3, 5, 7]
        ];
        var wins = [];
        for (var i = 1; i <= 9; i++) {
            for (var n = 0; n < combinations.length; n++) {
                if (typeof ttti.game.obj[i] === 'object') {
                    if (ttti.game.obj[i][combinations[n][0]] && ttti.game.obj[i][combinations[n][1]] && ttti.game.obj[i][combinations[n][2]]) {
                        if...