0

I am writing a tic tac toe game and implementing Ajax and Php, both of which are new to me. I have looked at a few other discussions but can't seem to find my answer. My js file is calling the php, which is in turn calling a database and pulling questions and answers--The user has to answer the question to play his/her turn. However, my program returns the answer to the next question asked, not the current question.

Here is my php:

$con = mysql_connect('localhost', '412ygutstei', '412ygutstei');
if ($con)
if (!$con) {
    die('Could not connect: ' . mysql_error());
}
$questionNum = $_POST['q_id'];  
mysql_select_db("ygutstei_db", $con);

$result = mysql_query("SELECT q_id, question_type, text,description, answer FROM questions,questiontype WHERE q_id=".$questionNum."");
$row = mysql_fetch_array($result);
$question = $row['description']." ".$row['text']."?|".$row['answer'];
echo($question);

mysql_close($con);

my js functions, which will call php:

function countDown() {
var element = document.getElementById(elem);

element.innerHTML = secs;
if(secs == 15){
    document.getElementById('playerDisplay').innerHTML= printEquation();
}
if(secs == 0){
    clearInterval(clock);
    turn++; 
    startTimer();       
    document.getElementById(answer).value = "";     
}
else{
    secs--;                     
}

}

var expect = ""; var randomQNumber; var correctAnswer; var askQuestion = "";

function printEquation(){
    randomQNumber = randNumber(1,8);

    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
        xmlhttp=new XMLHttpRequest(); 
    } 
    else {// code for IE6, IE5 
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
    xmlhttp.onreadystatechange=function() { 
        if (xmlhttp.readyState==4 && xmlhttp.status==200) { 
            var elements = xmlhttp.responseText.split("|");
            //elements[0] = document.getElementById("question")
            correctAnswer = elements[1];
            expect = correctAnswer;
            askQuestion = elements[0];
            //alert(correctAnswer); 
        }
    } 
    xmlhttp.open("POST","G_TicTacToe.php",true); 
    xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    xmlhttp.send("q_id="+randomQNumber);            

    if(turn % 2 == 0){
        return "X Plays: " + askQuestion + " = "; 
    }
    else{
        return "O Plays: " + askQuestion + " = ";
    }
}

function matchAnswer(a) {
var b = document.getElementById(a).value;
document.getElementById(a).innerHTML = b;
if(expect.toUpperCase() == b.toUpperCase()){
    clearInterval(clock);
    answeredQuestion = true;
    window.alert("Correct! ");
    document.getElementById(a).value = "";
    click();    
}
else{
    clearInterval(clock);
    window.alert("Incorrect! The correct answer was: " + expect);
    document.getElementById(a).value = "";
    playerTurn();
    startTimer();
}

html code that calls matchAnswer():

<input type="text" id="answer">
            <button id="equals" onclick="matchAnswer('answer');";>Answer</button>
        </div>
        <div class="playerAnswer">      

        </div>

ex: if output is: X Plays: What is the name of State1? - answer Illinois, it will return the answer for the next question, "What's my favorite animal? - i.e. penguin.

Any suggestions would be greatly appreciated. If more code is needed, please let me know.

Yehuda Gutstein
  • 381
  • 10
  • 27
  • 2
    You are using [an **obsolete** database API](http://stackoverflow.com/q/12859942/19068) and should use a [modern replacement](http://php.net/manual/en/mysqlinfo.api.choosing.php). You are also **vulnerable to [SQL injection attacks](http://bobby-tables.com/)** that a modern API would make it easier to [defend](http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection-in-php) yourself from. – Quentin Nov 14 '12 at 09:47
  • On a side note, if you are going to be using ajax, you'd be insane not to use jQuery's ajax tools. All of that `xmlhttp` stuff goes away and your ajax is compacted into a line or two of code. Take a look: http://stackoverflow.com/questions/10360304/ajax-basics-for-beginners – Dutchie432 Nov 14 '12 at 11:21
  • @Quentin: really? for a tic tac toe game? sql injection? really? the guy just started learning PHP and your bitching about sql injections isn't helping. – Davorin Nov 14 '12 at 11:24
  • @Davorin — Best to squash bad habits early. There's little point in learning the wrong way to do something before the right way. Even if security doesn't matter, having the application throw errors if someone types a `'` isn't good. – Quentin Nov 14 '12 at 11:27
  • @Quentin He'll have time to learn when he (she) gets into more "serious" stuff ;) – Davorin Nov 14 '12 at 11:32

1 Answers1

1

I'll go thrugh your code and leave some comments (some pretty obvious, but bear with me). Maybe you'll find them helpful.

These variable are global. They can be changed from any function at any time.

var expect = ""; var randomQNumber; var correctAnswer; var askQuestion = "";

The next part is straightforward xhr initialisation.

function printEquation(){
    randomQNumber = randNumber(1,8);

    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari 
        xmlhttp=new XMLHttpRequest(); 
    } 
    else {// code for IE6, IE5 
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

When doing ajax you should know about (async) events and callbacks. In this part you are attaching a callback function to an event. The callback is run asynchronously, which means you don't know exactly when it will run. It might run after or before the rest of the code (or any other code there is).

    xmlhttp.onreadystatechange=function() { 
        if (xmlhttp.readyState==4 && xmlhttp.status==200) { 
            var elements = xmlhttp.responseText.split("|");
            //elements[0] = document.getElementById("question")
            correctAnswer = elements[1];
            expect = correctAnswer;
            askQuestion = elements[0];
            //alert(correctAnswer); 
        }
    } 

The following code is certainly executed before the callback above, because you have yet to send the request to the server.

    xmlhttp.open("POST","G_TicTacToe.php",true); 
    xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    xmlhttp.send("q_id="+randomQNumber);

This part prints out the current value of askQuestion . I'm not sure where in the code you check for answers, but when the ajax response from the server comes and the above callback gets executed, the correctAnswer variable will hold the value for the next question, not this one.

    if(turn % 2 == 0){
        return "X Plays: " + askQuestion + " = "; 
    }
    else{
        return "O Plays: " + askQuestion + " = ";
    }
}

I'm not sure if this helps you. You can add the rest of your code to the question and I'll give you a proper answer.

Update

Seems to me that you're doing it all wrong. you should first load the question and then set the timer.

This line here, it return the existing askQuestion, but loads the next question and answer.

document.getElementById('playerDisplay').innerHTML= printEquation();

Ajax calls don't work like you expect, it isn't a function that returns a result. Instead, when you send a request it calls you back when it is ready. This is all wrong.

This is what you should be doing:

  1. Send an ajax call to get the question (xmlhttp.send)
  2. When the server responds with the question (onreadystatechange event) start the timer and show the question
  3. User now sees the question and can click on the button
  4. User answers or the clock times out
  5. Back to 1
Community
  • 1
  • 1
Davorin
  • 1,160
  • 15
  • 31
  • Thanks for taking the time to respond. I have added matchAnswer, and the bit of html code which calls it (via onclick()). As far as what you wrote about askQuestion, is there somewhere else that I need to locate it, so that the variable returns the value for the current question? – Yehuda Gutstein Nov 14 '12 at 15:05
  • so right now, my html calls startTimer() onload, which in trun calls countDown(), which calls printEquation(). You're saying I want to change that, and have a function containing the ajax called onload, which calls startTimer(), etc. ? – Yehuda Gutstein Nov 14 '12 at 18:26
  • yes. additionally, the timer needs to start when you receive the data from the server, which happens in the xmlhttp.onreadystatechange callback. it will be hard to get this working until you understand javascript events and callbacks. if you don't, please take a whole day and google it, read about it. then get back to your code. – Davorin Nov 14 '12 at 18:47
  • Thanks, I will see what I can do with this. So far, I have the answer matching up with the question, but no question yet for the 1st player. I appreciate your advice. – Yehuda Gutstein Nov 14 '12 at 19:35