Tic Tac Toe

The Tic tac toe is a classical game where two players take turns marking the spaces in a three-by-three grid with X or O. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner. In this tutorial we will explan how to create a basic version of the game using LimonadeJS.

A working example


Source code

var Tictactoe = function() {
var text = [
    'Click play to start',
    'Turn to play',
    'Won the game',
]
// Initializing self.
var self = {
    // Propertie to set the turn.
    turn: '',
    // Propertie to define if bot will play.
    bot: true,
    // Propertie to store boxes marked and the player who's marked it..
    game: [],
    // Propertie to set what text will appear in the template.
    text: text[0],
    // Propertie to define if already reached a winner.
    winner: false,
}
/**
 * Checking if the span's id are the same as the playerSign. 
 * @param {number} val1 - Id of the span selected.
 * @param {number} val2 - Id of the span selected.
 * @param {number} val3 - Id of the span selected.
 * @returns Returns the id in win case.
 */
var checkMatching = function(val1, val2, val3) {
    // Verify if all the spans was marked by the same player.
    if (self.game[val1] == self.game[val2] && self.game[val2] == self.game[val3]) {
        return self.game[val1];
    }
}
/**
 * self.clickedBox recieve the element clicked by the user and marks it with X or O depending the turn.
 * @param {element} element - used to determine what span will be marked.
 **/
var clickedBox = function(element) {
    // Verify if a winner is defined to stop the game.
    if (self.winner) {
        return false;
    }
    // Marks the box clicked according the player's turn.
    element.innerHTML = self.turn;
    // Increase the self.game array with the boxes already clicked.
    self.game[element.id] = self.turn;
    // Switch the text element to refers the player's turn.
    self.text = text[1];
    // Switch player's turn.
    if (self.turn == 'x') {
        self.turn = 'o';
    } else {
        self.turn = 'x';
    }
    // Variable to check if some player won the game.
    var winner = checkMatching(1, 2, 3) || checkMatching(4, 5, 6) ||
        checkMatching(7, 8, 9) || checkMatching(1, 4, 7) ||
        checkMatching(2, 5, 8) || checkMatching(3, 6, 9) ||
        checkMatching(1, 5, 9) || checkMatching(3, 5, 7);
    if (winner) {
        self.turn = winner;
        // Switch the text element to refers the winner.
        self.text = text[2];
        self.winner = true;
    }
}
/**
 * This will identifier the element clicked in the div if its a span, mark a boxes,
 * and if its a button, execute self.play. 
 * @param {element} o - Div element.
 */
self.grid = function(o) {
    // Add an eventListener to wait for a click in the element.
    o.addEventListener('click', function(e) {
        // Create a var called element to store the target of the event e.
        var element = e.target;
        // Verify the tagName of the element.
        if (element.tagName == 'SPAN') {
            // Call the clickedBox function.
            clickedBox(element, o);
            // If self.bot == true, this will do the bot move.
            if (self.bot) {
                // Define the pointerEvents to none, so the user cannot click while bot's turn.
                o.style.pointerEvents = 'none';
                // Set a timeout to the bot's turn.
                setTimeout(() => {
                    // Variable to store the spans not yet marked.
                    var result = o.querySelectorAll('span:empty');
                    // Variable to select one of the not marked spans. 
                    var randomBox = result[Math.floor(Math.random() * result.length)];
                    clickedBox(randomBox, o);
                    // Make the pointerEvents clickable again.
                    o.style.pointerEvents = '';
                }, 1000);
            }
        } else if (element.tagName == 'BUTTON') {
            self.play(o);
        }
    });
}
/**
 * Set all the game elements to the initial state.
 * @param {element} o - Div where is the game elements.
 */
self.play = function(o) {
    // Define the winner like false again.
    self.winner = false;
    self.turn = 'x';
    // Remove the elements from the game array. 
    self.game = [];
    // Switch the text element to refers the player's turn.
    self.text = text[1];
    // Get all the spans elements to remove the marks.
    var result = o.querySelectorAll('span');
    for (var i = 0; i < result.length; i++) {
        result[i].innerHTML = '';
    }
}
// Game template
let template = `
<div>
    <h1>Tic tac toe </h1>
    <h2>Bot </h2>
    <label class="jswitch"> <input type="checkbox" value='1' checked="checked" @bind='self.bot'> <i> </i> </label> 
    <div class="play-board">
        <div style="margin-top: 10px; margin-left: 70px; font-size: 20px">
            <span style="text-transform: uppercase">{{self.turn}} </span> 
            <span>{{self.text}} </span>
        </div>
        <div @ready="self.grid(this)" class="play-area">
            <section>
                <span id="1"> </span>
                <span id="2"> </span>
                <span id="3"> </span>
            </section>
            <section>
                <span id="4"> </span>
                <span id="5"> </span>
                <span id="6"> </span>
            </section>
            <section>
                <span id="7"> </span>
                <span id="8"> </span>
                <span id="9"> </span>
            </section>
            <div class="btn"> <button onclick="this.innerText = 'Restart'">Play </button> </div>
        </div>
    </div>
</div>
`;
return lemonade.element(template, self);
}

See this example on codesandbox

Acess tictactoe game github here