Guess 2/3 game: sending data from Flash to a remote database

I wrote a simple game to learn how to store on and retrieve data from a server-side database. The rules are simple: you have to guess 2/3 of the average of the guesses of all the players. So, for example, if you think that the other players guessed on average 100, your guess should be 67. The 2/3 rule is there to avoid the trivial strategy of  submitting the same number over and over again. According to game theory, the game has a Nash equilibrium at 0, which in this case does not correspond to a rational strategy. Wikipedia has some information and links about the game. Give it a try:

Get Adobe Flash player

The score you see after submitting is the distance from your guess to the true 2/3 of the average. Since you get some information about your and others’ score, it should be possible to find a strategy to win in a small number of trials… Let me know if you find one!

Communicating with the server

To implement the game, I created a MySQL table in a database on the server that is used to store the players’ name and guess. The database is accessed by calling a server-side PHP script from the game Actionscript client.

The PHP script gets the player’s information and stores it in the database; then it computes the 2/3 of the average of all entries, and returns the score and rank of the current player, along with the top scores in the database. The script receives the data as a HTTP request (the ?var1=value1&var2=value2 thing you see in many dynamical web pages), and returns an XML fragment.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php

// submit name, guess, ip, time to the Guess 2/3 database

// input variables:
// name: player's name
// guess: the guessed 2/3 of the average
// ntop: the number of top scores to be sent back

// this is how to obtain and verify the HTTP variables
if (!isset($_REQUEST["name"])) { die("Argument 'name' needed."); }
$name   = $_REQUEST["name"];
if (!isset($_REQUEST["guess"])) { die("Argument 'guess' needed."); }
$guess  = $_REQUEST["guess"];
if (!isset($_REQUEST["ntop"])) { die("Argument 'ntop' needed."); }
$ntop   = $_REQUEST["ntop"];
// some server data
$ip     = $_SERVER["REMOTE_ADDR"];
// the request time is used as unique identifier for every entry
$time   = $_SERVER["REQUEST_TIME"];

$dbh=mysql_connect ("localhost", "username", "password")
    or die ('Error connecting to the database:' . mysql_error());
mysql_select_db ("dabasename");

// insert new entry in database
// ============================

// this is the MySQL query to insert a new guess in the database
$sql = "INSERT INTO Guess23(name, guess, ip, time)
    VALUES ('{$name}', '{$guess}', '{$ip}', '{$time}')"
;
mysql_query($sql) or die (mysql_error());

// compute top scores and return XML fragment with top results
// ===========================================================

// compute 2/3 of the average
// SQL query to compute 2/3 of the average of the 'guess' column
$sql = 'SELECT (avg(guess)*2/3) AS avg FROM `Guess23`';
$qry = mysql_query($sql);
$avg = mysql_fetch_row($qry);

// SQL query to get all guesses so far and sort them by distance
// from the real target value, here called 'diff'
$sql = "SELECT name, guess, time, abs(guess-'$avg[0]') AS diff FROM `Guess23` ORDER BY diff ASC";
$hit = mysql_query($sql) or die(mysql_error());

// the following loop generates the XML code with the top scores
// in the loop, we also look for the current player's entry to
// determine her ranking
$currentrank = 0;
$rank = 1;
print "<table>\n";
// top scores
while (($row = mysql_fetch_array($hit)) && ($currentrank==0 || $rank<=$ntop)) {
  if ($rank<=$ntop) {
    print "<entry rank='{$rank}'>\n";
    print "\t<name>{$row['name']}</name>\n";
    print "\t<score>{$row['diff']}</score>\n";
    print "</entry>\n";
  }
  if ($row['time'] == $time) {
    $currentrank = $rank;
    $currentscore = $row['diff'];
  }
  $rank = $rank + 1;
}

// current score
print "<current rank='{$currentrank}'>\n\t<name>{$name}</name>\n\t<score>{$currentscore}</score>\n</current>";
print "</table>\n";

mysql_close();

?>

Calling the script from AS3 is relativelty easy. The remote call is done by a URLLoader object; the actual request is stored in a URLRequest object, and the request variables are wrapped in a URLVariables instance. I had an annoying problem with testing the code: for some reason, Flash always caches the requests. I looked around and it seems that the only workaround is to add a dummy variable to the request with a value that changes constantly, e.g., the current time.

This is the code for the communication with the server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public function submitGuess(name:String, guess:uint, ntop:int):void {
    var request:URLRequest = new URLRequest("http://www.masterbaboon.com/php/guess23/guess23submit.php");
    var httpHeader : URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
    request.requestHeaders.push(httpHeader);

    // request variables: name of player, guess, number of top scores to return
    var vars:URLVariables = new URLVariables();
    vars.name = name;
    vars.guess = guess;
    vars.ntop = ntop;
    // this is to trick AS3 into not caching the URL request
    vars.nocache = Number(new Date().getTime());

    request.method = URLRequestMethod.GET;
    request.data = vars;

    // send to server and call loadingComplete when complete
    var loader:URLLoader = new URLLoader();

    // the results of the request is not returned immediately, but
    // we can monitor the COMPLETE event dispatched by the loader
    loader.addEventListener(Event.COMPLETE, loadingComplete);
    try {
        loader.load(request);
    } catch (e:Error) {
        trace("An error has occurred while communicating with the server.");
        trace(e);
    }
}

public function loadingComplete(e:Event):void {
    // this is how to access the data returned from the request
    data = XML(e.target.data);
    // switch frame
    gotoAndStop("highScoreFrame");
}

You’re welcome to download the whole code.

4 Responses to “Guess 2/3 game: sending data from Flash to a remote database”


  1. 1 Blu

    You will never know it but I scored 0. I did guess it perfectly.

  2. 2 mohit varma

    Hi, I am tying to make a map in flash and wants to store some data in mysql database on some events on map. How can I achieve this please help me ASAP

  3. 3 pacman game

    The best pacman games on the internet. video games.

  1. 1 Guess 2/3 game: sending data from Flash to a remote database at … | cheapdirtdomain.com

Leave a Reply