Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

Two Player TicTacToe 2D Game using jQuery

4.70/5 (17 votes)
2 Sep 2014CPOL5 min read 44K   1.1K  
Two player tictactoe 2D game using jQuery

Sample Image - maximum width is 600 pixels

Introduction

Tic-Tac-Toe is a very simple paper-pencil game. In this example, I've shown how to build a 2D Tic-Tac-Toe using jQuery on HTML.

Background

Tic-Tac-Toe is about Os and Xs. The rule of the game is very simple. On a 3x3 grid, a player has to match 3 consecutive Os or Xs horizontally/vertically/diagonally. I've designed a very simple interface and used jQuery for the gameplay. In the following section, I'm going to explain the codes.

Using the Code

Here, I will explain the blocks of code.

HTML
<!DOCTYPE html>
<html>
<head>
    <title>TicTacToe</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

<div id="game-wrap">
    
    <div class="row">
        <div class="col"></div>
        <div class="col"></div>
        <div class="col"></div>
    </div>

    <div class="row">
        <div class="col"></div>
        <div class="col"></div>
        <div class="col"></div>
    </div>

    <div class="row">
        <div class="col"></div>
        <div class="col"></div>
        <div class="col"></div>
    </div>

</div>

<div id="panel">
    <input type="text" id="player-1-inp" placeholder="Enter player 1">
    <input type="text" id="player-2-inp" placeholder="Enter player 2">
    <button id="playButton">Play!</button>
    <h1 id="board"></h1>
</div>

<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>

Here, I've created a 3x3 grid using simple HTML divs. I took three row divs and inside every row div, I've taken three col divs. I kept the rows and cols name same because my plan is to use this structure as a 2D grid later. Under the grid, I've kept a panel div where players will set their name, start the game and see game state messages.

CSS
body{
background: #323232;
}

#game-wrap{
    width: 450px;
    height: 455px;
    margin: 0 auto;
    background: gray;
    margin-top: 50px;
    border-left: 5px solid gray;
    border-top-right-radius: 20px;
    border-top-left-radius: 20px;
}

.row{
    width: 100%;
    height: 150px;
}
.col{
    width: 32%;
    height: 145.5px;
    border: 3px solid white;
    float: left;
    text-align: center;
    font-size: 150px;
    font-family: helvetica;
    color: white;
    cursor: pointer;
}
.matched{
    color: maroon;
}
.player-1-color{
    color: maroon;
}
.col:nth-child(1){
    border-left: none;
}
.col:nth-child(3){
    border-right: none;
}

.row:nth-child(1) .col{
    border-top: none;
    margin-top: 3px;
}
.row:nth-child(3) .col{
    border-bottom: none;
    margin-bottom: 3px;
}
#panel{
    width: 435px;
    padding: 10px;
    margin: 0 auto;
    background: brown;
    border-bottom-right-radius: 20px;
    border-bottom-left-radius: 20px;
}
#board{
    font-size: 30px;
    font-family: helvetica;
    color: whitesmoke;
    margin-top: 10px;
}

This is the CSS design of the game. The code explains itself. I assume that people working with jQuery have knowledge about CSS.

The jQuery Part

In this part, I will write multiple blocks of code respectively and I will explain them seperately. But all of them are from the same .js file. Initially, we need to create some functions and do some initialization before we jump into the main gameplay.

JavaScript
var player1Name="" , player2Name="", turn = "";
var grid =  [[0,0,0],[0,0,0],[0,0,0]];
var hasWinner = 0, moveCount=0;

function boardMsg(x){
    return $("#board").text(x);
}

Here, we take some new variables for player names, for keeping track of game turn, a 3x3 array for mapping the moves of players, flag variables for finding winners, flag variables for counting the total number of moves (max moveCount will be 9) and finally a function for writing on the panel.

JavaScript
function setTurn(){
    var r = Math.floor((Math.random() * 2) + 1);
    hasWinner=0;
    if(r==1){
        turn = player1Name;
        boardMsg(player1Name+"'s turn now!");
    }
    else{
        turn = player2Name;
        boardMsg(player2Name+"'s turn now!");
    }
}

Then, we write a function for setting the turn randomly for player. Because everytime we don't want to give a player the first chance to make a move. Using random number, we set the turn and also we set the winner flag into 0 as the game has begun just now.

JavaScript
function init(){
        turn = "";
        grid =  [[0,0,0],[0,0,0],[0,0,0]];
        boardMsg("");
        $(".col").map(function() {
            $(this).text("");
        }).get();
        hasWinner = 0;
        moveCount=0;
}

Now, we have to write an initializing function like this because if the game has been playing for the second time or more than that, everytime the players replay, we need to clear the old values like the turn, grid array, panel messages, the grids Os/Xs and the flags.

JavaScript
$("#playButton").click(function (){

    if(hasWinner==1){
        init();
    }

    player1Name = $("#player-1-inp").val();
    player2Name = $("#player-2-inp").val();

    if(player1Name=="" || player2Name==""){
        alert("Please set player all the names.");
        return;
    }

    setTurn();
});

This function is the click event of the play button for taking the values of the players from the input tag. If there was a winner, that means this click is for the play again button. So we initalize the necessary values again. And then, we will check if the players set their names. Finally, we set the turn.

JavaScript
$(".col").click(function (){

    if(player1Name=="" || player2Name==""){
        alert("Please set player all the names.");
        return;
    }

    var row = $(this).parent().index();
    var col = $(this).index();

    if(grid[row][col]!==0){
        alert("This position is taken. Please try other position.");
        return;
    }
    if(hasWinner==1){
        alert("Please click play again");
        return;
    }

    if(turn==player1Name){
        moveCount++;
        $(this).text("O");
        grid[row][col] = 1;
        var ifWon = winnerCheck(1,player1Name);
        if(!ifWon){
            if(moveCount>=9){
                boardMsg("Match Drawn!");
                moveCount=0;
                $("#playButton").text("Play again");
                hasWinner=1;
                return;
            }else{
                turn = player2Name;
                boardMsg(player2Name+"'s turn now!");
            }
            return;    
        }
        else{
            return;
        }        
    }
    else if(turn==player2Name){
        moveCount++;
        $(this).text("X");
        grid[row][col] = 2;
        var ifWon = winnerCheck(2,player2Name);
        if(!ifWon){
            if(moveCount>=9){
                boardMsg("Match Drawn!");
                moveCount=0;
                $("#playButton").text("Play again");
                hasWinner=1;
                return;
            }else{
                turn = player1Name;
                boardMsg(player1Name+"'s turn now!");
            }
            return;    
        }
        else{
            return;
        }        
    }
});

This is the click event of the grid units. Here we use the jQuery class selector click function on every .col class. If a player clicks on any .col div, then we will have conditions for checking who is playing now. The first condition is for player1. Then, we take the row-col position of the grid unit using the jQuery index() and parent(). If the position is taken, then we will move forward. Or we will check the turn to determine which player is playing. After checking the turn, we will increament the move count because this is one successful move. Then we put 1 into the grids [row][col] position while the player just clicked the [row][col] position of the real grid. We'll pass 1 and the player name into our win checking function which is coming next. If the player does not win, then we will check if we are out of moves and the game has been drawn or not. If it's drawn, then we will send message to the panel and change the flag values. Here, though the game is drawn, I've set 1 into hasWinner flag because in the setTurn function, we need to pass the condition for init() if we need to create a new game. Then if it's not a draw, then we pass the turn to the second player and send a message to the panel. And out of the draw condition, if the player won then nothing will happen just it will stop the function. So carefully check that I've written two if conditions for two players. Inside the conditions, everything is the same except some values like while the condition is for player 1, we are putting 1 into the grid, passing 1 and player 1s name inside the win checking function and giving the turn to the player 2. For player 2, all these things will be opposite.

JavaScript
function winnerCheck(n,playerName){
    if(

        (grid[0][0]==n && grid[0][1]==n && grid[0][2]==n) ||
        (grid[1][0]==n && grid[1][1]==n && grid[1][2]==n) ||
        (grid[2][0]==n && grid[2][1]==n && grid[2][2]==n) ||

        (grid[0][0]==n && grid[1][0]==n && grid[2][0]==n) ||
        (grid[0][1]==n && grid[1][1]==n && grid[2][1]==n) ||
        (grid[0][2]==n && grid[1][2]==n && grid[2][2]==n) ||

        (grid[0][0]==n && grid[1][1]==n && grid[2][2]==n)||
        (grid[0][2]==n && grid[1][1]==n && grid[2][0]==n)


        ){
        boardMsg(playerName+" won the game!");
        hasWinner = 1;
        moveCount=0;
        $("#playButton").text("Play again");
        return true;
    }
    return false;
}

The last function is for checking the winner. In this function, we have passed a number and the player name as a parameter. Then we check that if on the grid, if horizontally/vertically/diagonally there are three consecutive ns. If there is any one condition matched, then that player won the game. So while we pass 1 and player 1 name inside the function, it will check if player 1 won the game and while we pass 2 and player 2s name, then it will check if player 2 won the game. Then we send message to the panel and update the flags. Because the UI should stop the game now. Then, we change the text of the button into 'Play again'. Finally, we return true. If all 8 conditions are false, then we return false. According to the return value, the click function of the grid units will work which I've explained earlier.

Play this game on jsfiddle.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)