AJAX Tutorial: 2 Player Tic-Tac-Toe Game (no database required)

Comments 7 Standard

If you haven’t read the first tutorial, the PHP version of this game without AJAX, then you should start there. This tutorial assumes you’ve already read the first one so I’m not going to explain how I actually go about programming the game. Instead this will focus on how you modify the original game so it works with AJAX. That means you won’t need to refresh the page between each player’s turn.

Download the Working Source Code
.zip archive

Getting jQuery

First thing is first we’ll need to get the jQuery library before we start updating any code. For those of you that don’t know, jQuery is code library that makes doing JavaScript quick and pretty painless. You can download or link to a copy offered on a Content Delivery Network (CDN) like Google Code. Personally I recommend downloading a copy if you’re going to post this game on a high traffic/visibility website. Sometimes if you link to a copy of jQuery on a CDN your site can experience lag and/or delays if the CDN is slow and your game won’t work at all if the CDN is down. On the other hand if you have a small website or limited space to store your files then there’s no need to download a copy of jQuery, linking to it is a better option. In this tutorial I’ve downloaded and included the jQuery file in the js folder of the .zip archive.

Setting Up For AJAX

Because we want our game to display using AJAX we need to create a new JavaScript file called hangman.js. This is what we’ll use to make all of our AJAX calls and respond to the player’s input.

Now that we have two JavaScript files we have to update our index.php file so it knows both of those JavaScript files are necessary to run the game. In the <head> tag, under the link to our stylesheet, we add two lines of code that tell our browser to load our JavaScript files:

<head>
        <title>Tic Tac Toe</title>
        <link rel="stylesheet" type="text/css" href="inc/style.css" />
        <script language="Javascript" src="js/jquery-1.7.1.min.js"></script>
        <script language="Javascript" src="js/tic-tac-toe.js"></script>
</head>

We also need to remove our $_SESSION[‘game’][‘tictactoe’] check from the top of our index file. Our AJAX calls will be running the game so it’s no longer necessary here. However we leave the session_start() at the top of the page so that if the player accidentally refreshes the page they don’t loose the game they had in progress.

Next we remove the code inside of our <div id=”content”> and set that aside for later because we’ll need to use parts of it in our AJAX. In it’s place we’re going to enter a loading message. This is what the page will display before the AJAX calls have finished processing.

<body>
        <div id="content">
        <center>Loading Tic-Tac-Toe.... please wait.</center>
        </div>
</body>

Writing the Tic-tac-toe.js File

Now it’s time to jump into jQuery and AJAX.

$(document).ready(function() {

    //start the game when the page loads
    playGame();

});

jQuery uses a special function to check when the page has finished loading. Anything you put inside of this function will run as soon as the page is loaded, or in response to something someone has done on the page, like mouse clicks or using the keyboard. For this tutorial all we need it to do is call our AJAX function that will load and display the game to the content div on our index.php file.

/***
* Purpose: play tic-tac-toe
* Preconditions: none
* Postconditions: new game has started or existing game is in play
***/
function playGame()
{
    $.ajax({
        url: 'ajax/index.php',
        data: {type: 'playGame'},
        success: function( data ) {
            $("#content").html(data);
        }
    });
}

Inside of our playGame() function we use AJAX to tell the browser to load our ajax file and send it some data (the type of action we’re doing, whether or not to start a new game, the player taking their turn). Then we use a success callback function to load the results of our ajax call onto the page. A callback function is a function that runs as a result of being called by another process. In this case our callback function, success, is loading the data we’ve retrieved through AJAX and putting it into the content div’s HTML property.

/***
* Purpose: place an X or O on the board
* Preconditions: none
* Postconditions: game status updated
***/
function makeMove()
{    
    var selected_spot = null;

    //find the first spot on the board they have an X or O inside of
    $(".board_spot").each(function() {
        if ($(this).val()) {
            //they have a value in this spot, break out of the loop
            selected_spot = $(this);
            return false;
        }
    });

    //make sure they've selected a spot
    if (selected_spot == null) {
        alert("You must select a spot on the board first.");
        return false;
    }

    //make sure we only get an X or O value
    if ($(selected_spot).val() != "X" && $(selected_spot).val() != "O") {
        alert("Invalid selection made. Please try again.");
        return false;
    }

    //pass the spot and the value they selected to our ajax file
    $.ajax({
        url: 'ajax/index.php',
        data: {type: 'playGame', spot:$(selected_spot).attr("name"), value:$(selected_spot).val()},
        success: function( data ) {
            $("#content").html(data); 
        }
    });
}

If we want to respond to someone trying to pick a spot we use a fairly similar process. First we loop through all of the input boxes on the page (we’ve added a call called board_spot to them in our displayBoard class function) and save the first one that has a value into our selected_spot variable. Then we check to make sure they’ve selected a spot and that the value in the spot is either an X or an O. Finally we send the spot they selected and the value to our ajax file.

/***
* Purpose: start a brand new game
* Preconditions: none
* Postconditions: new game has started
***/
function newGame()
{
    $.ajax({
        url: 'ajax/index.php',
        data: {type: 'playGame', newgame: true},
        success: function( data ) {
            $("#content").html(data);
        }
    });
}

The last piece of our ajax file is the newGame function. When the game is over we want to make sure we use AJAX to update the game state and then refresh the page to a new game.

Writing the AJAX File

Now that our JavaScript file will send AJAX requests we need to write the file on the other end of the request — the file that responds to the data we’re sending it. Create a new folder and name is ajax. Inside of it make an index.php file. Inside of the file put the following:

<?php
/***
* File: ajax/index.php
* Author: design1online.com, LLC
* Created: 4.26.2012
* License: Public GNU
* Description: respond to ajax calls
***/

//include the required files
require_once('../oop/class.game.php');
require_once('../oop/class.tictactoe.php');

//this will keep the game data as they make a new ajax request
session_start();

//respond to AJAX requests
echo doAction($_GET);

function doAction($getdata)
{
    switch ($getdata['type'])
    {
        case "playGame":
            return playGame($getdata['spot'], $getdata['value']);
        default:
            return "Invalid option selected.";
    }
}

/***
* Purpose: Display and play the game
* Preconditions: a game exists
* Postconditions: the current game is displayed to the screen
***/
function playGame($spot, $value)
{    
    //if they haven't started a game yet let's load one
    if (!$_SESSION['game']['tictactoe'])
        $_SESSION['game']['tictactoe'] = new tictactoe();

    echo "<h2>Let's Play Tic Tac Toe!</h2>";
    $_SESSION['game']['tictactoe']->playGame($spot, $value);
}

In this file we have two functions, doAction and playGame. Both functions take the $_GET data sent by our AJAX calls and do various things depending on the data sent to them. doAction is run every time this ajax file loads. It decides which function it needs to call, depending on the type we’ve sent it, and then returns the result to the screen.

Now pull up that code I had you set aside earlier. We’re going to move that into our playGame function with a few adjustments. We no longer need the <form> tags around our game data. In addition instead of sending $_POST data to our hangman object we’re now sending $_GET data. The $_GET data contains the information we were previously posting from the <form> tags. Since AJAX is refreshing what appears inside of our content div there’s no reason to use our <form> and $_POST variables anymore.

Last But Not Least

We’re almost done! Before we can view our handy work we need to open our tic tac toe OOP file. Anywhere we had a $_POST statement we need to change that to a $_GET since we’re no longer using the $_POST variable. We also need to adjust the move() function so it accepts both the spot and the value of that spot. Our new move function looks like this:

/**
    * Purpose: trying to place an X or O on the board
    * Preconditions: the position they want to make their move, the X or O value
    * Postconditions: the game data is updated
    **/
    function move($spot, $value)
    {            

        if ($this->isOver())
            return;

        if ($value == $this->player)
        {    
            //update the board in that position with the player's X or O 
            $coords = explode("_", $spot);
            $this->board[$coords[0]][$coords[1]] = $this->player;

            //change the turn to the next player
            if ($this->player == "X")
                $this->player = "O";
            else
                $this->player = "X";

            $this->totalMoves++;
        }

        if ($this->isOver())
            return;
    }

Finally, we need to update our new game and take turn buttons so they run the newGame and playGame javascript functions we wrote earlier:

<input type=\"submit\" name=\"move\" value=\"Take Turn\" onClick=\"makeMove();\" /><br/>

<div id=\"start_game\"><input type=\"submit\" name=\"newgame\" value=\"New Game\" onClick=\"newGame()\" /></div>"

Conclusion

Well, that wasn’t so hard now was it? Try the working version to see what it’s like! In this tutorial we took our existing PHP Tic Tac Toe game and modified it to use AJAX. If you play the game you’ll see the page no longer has to refresh each time you click the take turn button or when you hit the new game button. To accomplish this we first downloaded jQuery, created a JavaScript file to make AJAX requests, wrote a file to return a response to our AJAX requests, and then updated our tic tac toe class to use $_GET and our new JavaScript functions.

Advertisements

7 thoughts on “AJAX Tutorial: 2 Player Tic-Tac-Toe Game (no database required)

  1. This demo also shows an error :/
    Fatal error: Cannot re-assign auto-global variable _GET in /var/www/html/examples/tic_tac_toe_ajax/ajax/index.php on line 20

  2. Would this method require a database if it were more than 1 game happening at the same time?

  3. You would have to modify it but ultimately the answer is no, make multiple instances of it and you could have multiple games going at once.

  4. I gotcha, also does your code require both players to be using the same computer or can the game be played over the Internet by players in different locations? Im assuming the game could be played over the Internet since you are updating a php file on the server?

  5. They have to be on the same computer. If you wanted them to be able to play from different computers that would require a database so you can save and load the games and redraw them at their saved state.

  6. Pingback: mastering mastermind - rweber.net

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s