Tic tac toe

In this example below you will see how to do a Tic tac toe with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by Ľubomír Drinka, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright Ľubomír Drinka ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Tic tac toe</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  
<body>
    <div  class="container dialogbox "  style: "display: table;">
    <div class="row ">

        <div class="col-sm-6 border">
          <input type="checkbox" id="Check1">    
          <label for="Check1">X</label>
        </div>
        <div class="col-sm-6 border">
          <input type="checkbox" id="Check2">  
            <label for="Check2">O</label>
        </div>
    </div>

    <div class="row">
        <div class="col-sm-6 border">
             <input type="checkbox" id="Check3">
            <label for="Check3">start human</label>
                   </div>
        <div class="col-sm-6 border"> 
            <input type="checkbox" id="Check4">
            <label for="Check4">start UI</label>
                   </div>
    </div>
    </div>
    <div class="mainbox border" style: "display: table;">
        <div class="row">
            <span id="c4" class="zarovnat border minibox col-xm-3 btn fonts"></span>
            <span id="m1" class="border minibox col-xm-3 btn fonts"></span>
            <span id="c1" class="border minibox col-xm-3 btn fonts"></span>
        </div>
        <div class="row">
            <span id="m4" class="zarovnat border minibox col-xm-3 btn fonts"></span>
            <span id="b3" class="border minibox col-xm-3 btn fonts"></span>
            <span id="m2" class="border minibox col-xm-3 btn fonts"></span>
        </div>
        <div class="row">
            <span id="c3" class="zarovnat border minibox col-xm-3 btn fonts"></span>
            <span id="m3" class="border minibox col-xm-3 btn fonts"></span>
            <span id="c2" class="border minibox col-xm-3 btn fonts"></span>
            <line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
        </div>
    </div>



    <span class=" Monsieur_La_Doulaisefont" style="margin-left: 45%; font-size:35pt "> tictactoe</span>




</body>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/vanderdrilu/tic-tac-toe-NMJWaY */
.minibox {
  width: 100px;
  height: 100px;
}

.border {
  border: 4px solid ivory;
}

.mainbox {
  margin: 2% 45%;
  width: 302px;
  height: 302px;
}

.fonts {
  font-size: 40pt;
  color: ivory;
}

.zarovnat {
  margin-left: 15px;
}

body {
  background-image: url(https://img00.deviantart.net/5bcc/i/2009/337/c/6/work_wallpaper_2_by_blkbtrfli8.jpg);
  background-color: black;
  background-repeat: no-repeat;
}

.dialogbox {
  width: 200px;
  height: 50px;
  padding: 10px;
  margin: 0 47%;
  color: bisque;
}

.Monsieur_La_Doulaisefont {
  font-family: 'Monsieur La Doulaise', cursive;
}


/*Downloaded from https://www.codeseek.co/vanderdrilu/tic-tac-toe-NMJWaY */
$(document).ready(function () {
    var start34 = 3;
    var mark = { enemy: 'X', player: '0' };
    $('#Check1').prop('checked', true);
    $('#Check3').prop('checked', true);
    var arrhistory = [];
    var cornershistory = [];
    var middleshistory = [];
    var arrMyI = [0, 0, 0, 0, 0, 0, 0, 0];
    var arrEnI = [0, 0, 0, 0, 0, 0, 0, 0];
    var arrlines = [
        ['c3', 'b3', 'c1'],
        ['c2', 'b3', 'c4'],
        ['m3', 'b3', 'm1'],
        ['m4', 'b3', 'm2'],
        ['c3', 'm3', 'c2'],
        ['c4', 'm1', 'c1'],
        ['c4', 'm4', 'c3'],
        ['c1', 'm2', 'c2']
    ];
    var matrix = {
        1: "3",
        3: "1",
        4: "2",
        2: "4"
    };
    var tahN = 0;
    var id;
    var endgameBoo = false;
    function total_reset() {
        arrhistory = [];
        cornershistory = [];
        middleshistory = [];
        arrMyI = [0, 0, 0, 0, 0, 0, 0, 0];
        arrEnI = [0, 0, 0, 0, 0, 0, 0, 0];
        endgameBoo = false;
        arrlines.forEach(function (x, i) {
            var point1 = arrlines[i].forEach(function (t) {
                $('#' + t).empty();
                $('#' + t).css('background', 'rgb(15, 14, 14)');
                endgameBoo = false;
            });
        });
        if (start34 == 4)
            addmove('b3', arrMyI, cornershistory, middleshistory, mark.player);
    }
    $('span').dblclick(function () { total_reset(); });
    $('span').click(function () {
        if (endgameBoo === false) {
            var select = $(this);
            id = select.attr('id');
            if (!arrhistory.includes(id)) {
                //vlož ťah súpera
                addmove(id, arrEnI, cornershistory, middleshistory, mark.enemy);
                var maxnum = 0;
                var maxnumEn = 0;
                var indexOfMaxValue = {
                    a: -1
                };
                var indexOfMaxValueEnemy = {
                    a: -1
                };
                var forR = 0;
                if (tahN === 1) {
                    if (id === 'b3') {
                        forR = randomfilterexisted(1, 4, cornershistory);
                        addmove('c' + [forR], arrMyI, cornershistory, middleshistory, mark.player);
                        // } else if (id[0] === 'c') {
                        //     set_to_opposite_corner(cornershistory, id);
                    }
                    else {
                        addmove('b3', arrMyI, cornershistory, middleshistory, mark.player);
                    }
                }
                else {
                    maxnum = matmax(arrMyI, indexOfMaxValue, arrEnI);
                    maxnumEn = matmax(arrEnI, indexOfMaxValueEnemy, arrMyI);
                    if (maxnum >= maxnumEn) {
                        if (maxnum > 1) {
                            //ak sú dve vjednom rade moje
                            findmissingoneinline(indexOfMaxValue.a);
                        }
                        else {
                            // pridaj do vlastn0ho radu
                            if (id[0] == 'm' && middleshistory.length > 0 &&
                                !(middleshistory.includes(id[1]) && middleshistory.includes(matrix[id[1]]))) {
                                set_to_opposite_corner(middleshistory, id);
                            }
                            else if (id[0] == 'c' && cornershistory.length > 0 &&
                                !(cornershistory.includes(id[1]) && cornershistory.includes(matrix[id[1]]))) {
                                set_to_opposite_corner(cornershistory, id);
                            }
                            else if (maxnum === 2 && maxnumEn === 2) {
                                //ak sú dve vjednom rade moje
                                findmissingoneinline(indexOfMaxValue.a);
                            }
                            else {
                                if (maxnumEn == 2) {
                                    //ak má súper dve v jednom rade
                                    findmissingoneinline(indexOfMaxValueEnemy.a);
                                }
                                else if (maxnumEn == 1) {
                                    findmissingFromtwoinline(indexOfMaxValue.a);
                                }
                                else {
                                    findmissingFromtwoinline(indexOfMaxValue.a);
                                }
                            }
                        }
                        //súper je bližšie obrana
                    }
                    else {
                        if (maxnumEn == 2) {
                            //ak má súper dve v jednom rade
                            findmissingoneinline(indexOfMaxValueEnemy.a);
                        }
                        else if (maxnumEn == 1) {
                            findmissingFromtwoinline(indexOfMaxValue.a);
                        }
                    }
                }
            }
        }
        else {
            total_reset();
        }
    });
    function set_to_opposite_corner(movehistory, id) {
        var arrout = [];
        movehistory.forEach(function (element) {
            arrout.push(matrix[element]);
        });
        var ind = 0;
        var positionofcorner = findjointcorner(id);
        var output;
        if (positionofcorner !== 'false') {
            // medzi dvomi stredmi ak je voľný roh treb ho obsadiť
            output = positionofcorner;
        }
        else {
            if (arrout.length < 2)
                ind = Math.round(Math.random());
            output = id[0] + arrout[ind];
        }
        addmove(output, arrMyI, cornershistory, middleshistory, mark.player);
    }
    function findjointcorner() {
        var pos = 'false';
        arrlines.forEach(function (element) {
            if (element[1].includes('m')) {
                if (pos == 'false') {
                    if (arrhistory.includes(element[1])) {
                        arrlines.forEach(function (element2) {
                            if (element2[1] == (id)) {
                                if ((element[0] == element2[0] || element[2] == element2[2] ||
                                    element[0] == element2[2] || element[2] == element2[0]) && element[1] !== element2[1]) {
                                    if (element[0] == element2[0]) {
                                        pos = (element[0]);
                                    }
                                    else if (element[2] == element2[2]) {
                                        pos = element[2];
                                    }
                                    else if (element[0] == element2[2]) {
                                        pos = (element[0]);
                                    }
                                    else if (element[2] == element2[0]) {
                                        pos = element[2];
                                    }
                                }
                            }
                        });
                    }
                }
            }
        });
        return pos;
    }
    function findmissingoneinline(index) {
        //ak napr ['c3', 'b3', 'c1'] chýbav histórii ťahov zadaj ako ťah domojich ťahov
        arrlines[index].forEach(function (element) {
            if (!arrhistory.includes(element)) {
                addmove(element, arrMyI, cornershistory, middleshistory, mark.player);
            }
        });
    }
    function findmissingFromtwoinline(index) {
        //ak napr ['c3', 'b3', 'c1'] chýba v dva histórii ťahov zadaj ako n8hodnz 1,2 ťah do mojich ťahov
        var arrout = [];
        arrlines[index].forEach(function (element) {
            if (!arrhistory.includes(element)) {
                arrout.push(element);
            }
        });
        var ind = 0;
        if (arrout.length === 2)
            ind = Math.round(Math.random());
        var output = arrout[ind];
        addmove(output, arrMyI, cornershistory, middleshistory, mark.player);
    }
    function matmax(array1, indexmaxval, array2) {
        //nájdi čísloslo v arr, ktoré je najväčšie a nie je obsadené v mojom arr
        //a v ktorom index teda diagonále 4i smere je najväčšie číslo
        var temp = 0;
        var arrlowerthan3 = [];
        array1.forEach(function (element, i) {
            var threeline = element + array2[i];
            if (threeline < 3) {
                arrlowerthan3.push([element, i]);
                if (element > temp && array2[i] < element) {
                    temp = element;
                    indexmaxval.a = i;
                }
            }
        });
        if (indexmaxval.a === -1) {
            arrlowerthan3.forEach(function (element, i) {
                if (element[0] > temp && array2[element[1]] <= element[0]) {
                    temp = element[0];
                    indexmaxval.a = element[1];
                }
            });
        }
        return temp;
    }
    //includes(result) === true  &&
    //  &&  .includes(result) === true
    function randomfilterexisted(min, max, occupied) {
        var result = 0;
        while (result === 0 && occupied.includes(result) === false) {
            result = Math.floor(Math.random() * max + min);
        }
        return result;
    }
    function addmove(id, arr, cornesarr, middlearr, player) {
        if (!arrhistory.includes(id)) {
            arrhistory.push(id);
            tahN = arrhistory.length;
            $('#' + id).text(player);
        }
        if (id[0] == 'b') {
        }
        else if (id[0] == 'c') {
            if (!cornesarr.includes(id[1])) {
                cornesarr.push(id[1]);
            }
        }
        else if (id[0] == 'm') {
            if (!middlearr.includes(id[1])) {
                middlearr.push(id[1]);
            }
        }
        arrlines.forEach(function (element, i) {
            if (element.includes(id)) {
                arr[i]++;
            }
        });
        checkwin(arr, player);
    }
    function checkwin(arr, player) {
        arr.forEach(function (x, i) {
            if (x >= 3) {
                var point1 = arrlines[i].forEach(function (t) {
                    $('#' + t).css('background', 'green');
                    endgameBoo = true;
                });
            }
        });
    }
    $('input').click(function () {
        var cross = {
            1: 2,
            2: 1,
            3: 4,
            4: 3
        };
        var select = $(this);
        cid = select.attr('id');
        var nID = cid[5];
        if ($(this).prop('checked')) {
            $('#Check' + cross[nID]).prop('checked', false);
        }
        else {
            $('#Check' + cross[nID]).prop('checked', true);
        }
        if (nID == 1) {
            mark.player = 'O';
            mark.enemy = 'X';
        }
        else if (nID == 2) {
            mark.player = 'X';
            mark.enemy = 'O';
        }
        else if (nID == 3) {
            start34 = 3;
        }
        else if (nID == 4) {
            start34 = 4;
        }
        //arrMyI.red
        total_reset();
    });
});

Comments