Tic Tac Toe Game using HTML, CSS and JavaScript – Coding Torque

Share your love

Welcome to Coding Torque. In this blog, we are going to create a Tic Tac Toe Game using HTML, CSS and JavaScript. You should create this project if you are an intermediate-level javascript developer.

Before we start, here are some JavaScript Games you might like to create:

1.Ā Snake Game using JavaScript

2.Ā 2D Bouncing Ball Game using JavaScript

3.Ā Rock Paper Scissor Game using JavaScript

4.Ā Tic Tac Toe Game using JavaScript

5. Whack a Mole Game using JavaScript

 

I would recommend you don’t just copy and paste the code, just look at the code and type by understanding it.

 

HTML CodeĀ 

Starter Template

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

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

    <!-- CSS -->
    <link rel="stylesheet" href="style.css">

    <title>Tic Tac Toe Game using JavaSript using JavaScript with Source Code - @code.scientist x @codingtorque
    </title>
</head>

<body>
    <!-- Further code here -->

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

</html>

 

Paste the below code in your <body> tag

<table id="scoreboard" align="center">
    <tr>
        <td> Player 1 </td>
        <td width="30"> &nbsp; </td>
        <td> Player 2 </td>
    </tr>
    <tr>
        <td class="score" id="player1">
            0
        </td>
        <td> &nbsp; </td>
        <td class="score" id="player2">
            0
        </td>
    </tr>
</table>

<div id="placeholder"></div>

<button onclick="restart()">
    Reset
</button>
<select onchange="restart(this.value)">
    <option value="2">
        2 X 2
    </option>
    <option value="3" selected="">
        3 X 3
    </option>
    <option value="4">
        4 X 4
    </option>
    <option value="5">
        5 X 5
    </option>
    <option value="6">
        6 X 6
    </option>
</select>

Output Till Now

CSS CodeĀ 

Create a fileĀ style.css and paste the code below.

body {
  font: normal 16px comic sans ms;
  text-align: center;
}

#tic-tac-toe {
  cell-spacing: 0px;
  border-spacing: 0px;
  border-collapse: separate;
  margin: 30px auto;
}

#tic-tac-toe td {
  border: 2px solid #000;
  height: 100px;
  width: 100px;
  text-align: center;
  font: bold 60px comic sans ms;
}

#tic-tac-toe tr:first-child td {
  border-top: none;
}

#tic-tac-toe tr:last-child td {
  border-bottom: none;
}

#tic-tac-toe tr td:first-child {
  border-left: none;
}

#tic-tac-toe tr td:last-child {
  border-right: none;
}

#tic-tac-toe td.X {
  color: #ed676b;
}

#tic-tac-toe td.O {
  color: #23916b;
}

#scoreboard .score {
  text-align: center;
  font-size: 30px;
}

#scoreboard .score#player1 {
  color: #ed676b;
}

#scoreboard .score#player2 {
  color: #23916b;
}

 

Output Till Now

tic tac toe game using javascript with source code

JavaScript CodeĀ 

Create a fileĀ script.jsĀ and paste the code below.
function TicTacToe(placeholder, grid_size, callback) {

    // Save the placeholder element 
    this.placeholder = placeholder;

    // Paint the placeholder with board
    this.paint(grid_size);

    // Save the callback
    this.callback = callback;

    // Save player scores
    this.scores = {
        X: 0,
        O: 0
    };

    this.marks = {
        X: "X",  // Player 1 mark
        O: "O",  // Player 2 mark
        count: 0 // Number of moves made by player
    };

    return this;
}

TicTacToe.prototype.paint = function(grid_size) {

    var self = this;

    // Get number of columns, considering board as N x N board (3 x 3)
    self.grid_size = grid_size;

    var html = '<table id="tic-tac-toe" align="center">';
    
    for(var i = 0; i < grid_size; i++) {
        html += '<tr>';
        for(var j = 0; j < grid_size; j++) {
            html+= '<td></td>';
        }
        html += '</tr>';
    }

    html += '</table>';
    
    self.placeholder.innerHTML = html;

    // Find all columns from the board
    self.columns = self.placeholder.getElementsByTagName("td");

    // Go through all the columns and add click event
    for(i = 0; i < this.columns.length; i++) {
        self.columns[i].addEventListener("click", markHandler);
    }

    // on click mark the column "<td>"
    function markHandler(e) {
        self.mark(e.target);
    }

};

TicTacToe.prototype.mark = function(column) {

    // Stop if column is not empty
    if(column.innerHTML) {
        return;
    }

    // Count the move
    this.marks.count++;

    // Get the mark based on the count
    var current_mark = this.marks.count % 2 === 1 ? this.marks.X : this.marks.O;

    // Fill the column with mark
    column.innerHTML = current_mark;
    column.classList.add(current_mark);

    // Check if this player (X or O) won
    if(this.didWin(current_mark)) {
        // Increment the player score
        if(this.marks.count % 2 === 1) {
            this.scores.X++;
        } else {
            this.scores.O++;
        }
        // Send current mark and scores
        this.callback(current_mark, this.scores);
    } else if(this.marks.count === this.columns.length) {
        // Send result as draw
        this.callback("draw");
    }

};

//  Board:
//  _____________
//	| 0 | 1 | 2 |
//  |---|---|---|
//  | 3 | 4 | 5 |
//	|---|---|---|
//	| 6 | 7 | 8 |
//  -------------
// 
// We need to go through all columns like
// 
// 012, 345, 678 - Horizontal
// 036, 147, 258 - Vertical
// 048, 246      - Diagonal
//
// If mark is present in all columns of any combinations then user won
//
// Instead of going through each combination manually we can make use of loops,
// So that it can be used for any grids like 7 X 7
//

TicTacToe.prototype.didWin = function(mark) {

    // Take count of columns
    var grid_size = this.grid_size;

    // Declare variables to count the presence of the mark
    var horizontal_count,
        vertical_count,
        right_to_left_count = 0,
        left_to_right_count = 0;


    // Loop 1
    for(var i = 0; i < grid_size; i++) {

        // Empty the count
        horizontal_count = vertical_count = 0;

        // Loop 2
        for(var j = 0; j < grid_size; j++) {
            // i * grid_size + j ===> "0,1,2", "3,4,5", "6,7,8"
            if(this.columns[i * grid_size + j].innerHTML == mark) {
                horizontal_count++;
            }
            // j * grid_size + i ===> "0,3,6", "1,4,7", "2,5,8"
            if(this.columns[j * grid_size + i].innerHTML == mark) {
                vertical_count++;
            }
        }
        // If horizontal or vertical combination is found the return true
        if(horizontal_count == grid_size || vertical_count == grid_size) {
            return true;	
        }

        // i * grid_size + i ===> "0,4,8"
        if(this.columns[i * grid_size + i].innerHTML == mark) {
            right_to_left_count++;
        }

        // (grid_size - 1) * (i+1) ===> "2,4,6"
        if(this.columns[(grid_size - 1) * (i+1)].innerHTML == mark) {
            left_to_right_count++;
        }

    } // End of loop

    // If mark is present diagnolly
    if(right_to_left_count == grid_size || left_to_right_count == grid_size) {
        return true;	
    }

    return false;
};

TicTacToe.prototype.empty = function() {
    // Go through all columns and empty them
    for(var i = 0; i < this.columns.length; i++) {
        this.columns[i].innerHTML = '';
        this.columns[i].classList.remove(this.marks.X);
        this.columns[i].classList.remove(this.marks.O);

    }
    // Reset the count
    this.marks.count = 0;
};

TicTacToe.prototype.reset = function() {
    this.empty();
    this.scores = {
        X: 0,
        O: 0
    };
};

var placeholder = document.getElementById("placeholder");

var tictactoe = new TicTacToe(placeholder, 3, onResult);

function onResult(result, scores) {
    if(result == 'draw') {
        alert("It's a draw !");
    } else {
        alert(result + " has won");
        updateScores(scores.X, scores.O);
    }
    tictactoe.empty();
}

function updateScores(X, O) {
    document.querySelector("#scoreboard #player1").innerHTML = X;
    document.querySelector("#scoreboard #player2").innerHTML = O;	
}

function restart(grid_size) {
    tictactoe.reset();
    updateScores(0, 0);
    if(grid_size) {
        tictactoe.paint(grid_size);
    }
}

 

Written by: Piyush Patil
Code Credits:Ā @captain-mad
If you have any doubts or any project ideas feel free to Contact Us
Hope you find this post helpfulšŸ’–
Share your love