commit 6febacce175ee177a7fca8ce74fbd15247896e3e
parent 5842d02c611ff4f0c73fee467be6b4f00a965cb1
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Wed, 18 May 2011 12:38:40 +0200
Client presque terminé.
Diffstat:
8 files changed, 157 insertions(+), 418 deletions(-)
diff --git a/code/serveur/dump2mysql.sh b/code/serveur/dump2mysql.sh
@@ -1,48 +0,0 @@
-#!/bin/sh
-
-echo " dump2sql.sh : conversion des dumps de JeuxDeMots vers du sql (mysql)." >&2
-echo " La progression est affichée avec pv. Si vous n'avez pas pv, supprimez la ligne correspondante dans ce script." >&2
-echo " Et c'est parti !" >&2
-echo >&2
-
-# game_played(type) : 0=partie de référence initiale, 1=partie d'un joueur.
-
-cat <<EOF
-start transaction;
-create database if not exists pticlic;
-use pticlic;
-create table node(eid integer auto_increment, name varchar(255), type integer, weight integer, primary key(eid));
-create table relation(rid integer auto_increment, start integer, end integer, type integer, weight integer, primary key(rid));
-create table type_node(name varchar(255), num integer, primary key(num));
-create table type_relation(name varchar(255), num integer, extended_name varchar(16384), info varchar(16384), primary key(num));
-create table user(login varchar(255), mail varchar(255), hash_mdp char(32), primary key(login));
-create table game(pid integer auto_increment, eid_central_word integer, relation_1 integer, relation_2 integer, relation_3 integer, relation_4 integer, reference_played_game integer, primary key(pid));
-create table game_cloud(pid integer, num integer, eid_word integer);
-create table game_played(pid integer, type integer, num integer, relation integer, weight integer);
-EOF
-
-# tr : pour virer le CRLF qui traîne
-# Le gros tas de sed / tr : pour virer le newline dans une des description étendue
-cat "$1" \
-| iconv -f iso-8859-1 -t utf-8 \
-| tr '\r' ' ' \
-| sed -e 's/X/XX/g' | sed -e 's/A/Xa/g' | tr '\n' 'A' | sed -e 's/A")/")/g' | tr 'A' '\n' | sed -e 's/Xa/A/g' | sed -e 's/XX/X/g' \
-| pv -s $(wc -c < "$1") \
-| sed -e "s#'#''#g" \
-| sed -e 's/\\//g' \
-| sed -E -e 's#^/?// [0-9]+ occurrences of relations ([a-z_]+) \(t=([0-9]+) nom_etendu="([^"]+)" info="([^"]+)"\)$#insert into type_relation(name, num, extended_name, info) values('\''\1'\'', \2, '\''\3'\'', '\''\4'\'');#' \
-| sed -E -e 's#^/?// [0-9]+ occurrences of nodes ([a-z_]+) \(t=([0-9]+)\)$#insert into type_node(name, num) values('\''\1'\'', \2);#' \
-| sed -E -e 's#^eid=([0-9]+):n="(.*)":t=([0-9]+):w=(-?[0-9]+)$#insert into node(eid, name, type, weight) values(\1, '\''\2'\'', '\''\3'\'', '\''\4'\'');#' \
-| sed -E -e 's#^rid=([0-9]+):n1=([0-9]+):n2=([0-9]+):t=([0-9]+):w=(-?[0-9]+)#insert into relation(rid, start, end, type, weight) values(\1,\2,\3,\4,\5);#' \
-| grep -v 'insert into node(eid, name, type, weight) values(0,' \
-| grep -v '^//' \
-| grep -v '^$'
-
-cat <<EOF
-create index i_relation_start on relation(start);
-create index i_relation_end on relation(end);
-create index i_relation_type on relation(type);
-create index i_relation_start_type on relation(start,type);
-create index i_relation_end_type on relation(end,type);
-commit;
-EOF
diff --git a/code/serveur/dump2sqlite.sh b/code/serveur/dump2sqlite.sh
@@ -29,14 +29,16 @@ create table type_relation(name, num, extended_name, info);
create table user(login primary key, mail, hash_passwd, score, ugroup);
create table game(gid integer primary key autoincrement, eid_central_word, relation_1, relation_2, difficulty, author);
create table game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash);
-create table played_game(pgid integer primary key autoincrement, gid, nonce, login, timestamp);
-create table played_game_cloud(pgid, gid, type, num, relation, weight, score);
+create table played_game(pgid, gid, login, timestamp, primary key(login, pgid));
+create table played_game_sequence(id integer primary key autoincrement);
+create table played_game_cloud(pgid, login, gid, type, num, relation, weight, score);
create table colon_nodes(eid);
create table random_cloud_node(eid,nbneighbors);
create table random_center_node(eid);
create table user_info(user, key, value, primary key (user, key));
insert into user(login, mail, hash_passwd, score, ugroup) values('$(echo "$user" | sed -e "s/'/''/g")', 'foo@isp.com', '$(echo "$passwd" | dd bs=1 count="${#passwd}" | (if which md5sum >/dev/null 2>&1; then md5sum; else md5; fi) | cut -d ' ' -f 1)', 0, 1);
+insert into user(login, mail, hash_passwd, score, ugroup) values('bot', 'no mail', 'no password', 0, 1);
EOF
# tr : pour virer le CRLF qui traîne
diff --git a/code/serveur/php/jeu.php b/code/serveur/php/jeu.php
@@ -32,6 +32,9 @@
#score { text-align:center; }
.marginBox { width: 90%; height: 90%; top: 5%; left:5%; position:absolute; }
#message { left:25%; top:5%; width:50%; height:15%; position:absolute; border-radius:0.5em; text-align:center; opacity:0.9; }
+
+ .transition { transition: all 0.7s linear; -moz-transition: all 0.7s linear; -webkit-transition: all 0.7s linear; }
+ .transition-bg { transition: background-color 0.7s linear; -moz-transition: background-color 0.7s linear; -webkit-transition: background-color 0.7s linear; }
#splash, #nojs { background-color:black; color: white; }
/* couleurs green */
@@ -39,7 +42,7 @@
#message { background-color:#f0f8d0; color:black; border:medium solid #4a4; }
#mc-caption { color:#8b4; }
#mn-caption-box { background-color:#f0f8d0; }
- #mn-caption { color: #4a4; }
+ .mn-caption { color: #4a4; }
.borderbar { background-color: #4a4; }
.relationBox { background-color:#f0f8d0; border-color: #4a4; }
.highlight { background-color:#f0f8d0; border-color:#4a4; }
@@ -50,7 +53,7 @@
.black #message { background-color:#222; color:white; border:medium solid #ccc; }
.black #mc-caption { color:white; }
.black #mn-caption-box { background-color:#222; }
- .black #mn-caption { color: #ccc; }
+ .black .mn-caption { color: #ccc; }
.black .borderbar { background-color: #ccc; }
.black .relationBox { background-color:#222; border-color: #ccc; }
.black .highlight { background-color:#222; border-color:#ccc; }
@@ -69,7 +72,7 @@
<div class="borderbar" style="height:5%; width:100%; top:52.5%; position:absolute;"></div>
<div id="mn-caption-box" style="top:57.5%; height:37.5%; width:100%; position:absolute;"></div>
<div style="width: 90%; height:25%; top:63.75%; left: 5%; position:absolute;" class="fitFont">
- <div id="mn-caption" class="mn center">Mot du nuage</div>
+ <div class="mn mn-caption center setFont">Mot du nuage</div>
</div>
<div class="borderbar" style="height:5%; width:100%; top:95%; position:absolute;"></div>
</div>
diff --git a/code/serveur/php/ressources/backend.inc b/code/serveur/php/ressources/backend.inc
@@ -11,12 +11,11 @@ require_once("ressources/db.inc");
* cgBuildResultSets($cloudSize, $centerEid, $r1, $r2);
* cgChooseRelations();
* cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights);
-* cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty);
+* insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty, $userName);
* randomGameCore();
* randomGame();
* formatWord($word);
-* game2json($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true);
-* game2array($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true);
+* game2json($user, $pgid);
* createGame($nbParties, $mode);
* createGameCore($cloudSize);
* getGame($user, $nbGames, $mode);
@@ -31,6 +30,9 @@ require_once("ressources/db.inc");
* getNodeEid($node);
*/
+function longStrVal($str) {
+ return preg_match('/^-?[0-9]+$/', ''.$str) ? ''.$str : '0';
+}
/** Vérifie la validité du couple nom d'utilisateur / mot de passe.
* @param user : Le nom d'utilisateur.
@@ -151,7 +153,8 @@ function cgBuildResultSets($cloudSize, $centerEid, $r1, $r2)
*/
function cgChooseRelations()
{
- $relations = array(5, 7, 9, 10, 13, 14, 22);
+ global $stringRelations;
+ $relations = array_values(array_diff(array_keys($stringRelations), array(-1, 0)));
$r1 = rand(0,count($relations)-1);
$r2 = rand(0,count($relations)-2);
@@ -250,57 +253,10 @@ function cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights)
}
-/** Insère la partie dans la base de données.
-* @param centerEid : Identifiant du mot central.
-* @param cloud : Le nuage.
-* @param r1 : Le type de la relation 1.
-* @param r2 : Le type de la relation 2.
-* @param totalDifficulty : La difficulté totale.
-*/
-function cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty)
-{
+function getSequencePlayedGame() {
$db = getDB();
- // Insère dans la base une partie avec le mot central $centerEid, le nuage $cloud et les relations $r1 et $r2
- $db->exec("begin transaction;");
- $db->exec("INSERT INTO game(gid, eid_central_word, relation_1, relation_2, difficulty)
- VALUES (null, $centerEid, $r1, $r2, $totalDifficulty);");
- $gid = $db->lastInsertRowID();
-
- $t = time();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid1 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid2 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid0 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgidT = $db->lastInsertRowID();
-
- // TODO : R0 et Trash + corrections
- foreach ($cloud as $c)
- {
- $totalWeight = $c['probaR1'] + $c['probaR2'] + $c['probaR0'] + $c['probaTrash'];
- $db->exec("INSERT INTO game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash)
- VALUES ($gid, ".$c['pos'].", ".$c['d'].", ".$c['eid'].", $totalWeight, ".$c['probaR1'].", ".$c['probaR2'].", ".$c['probaR0'].", ".$c['probaTrash'].");");
-
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid1, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
-
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid2, $gid, 0, ".$c['pos'].", $r2, ".$c['probaR2'].", 0);");
-
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid0, $gid, 0, ".$c['pos'].", 0, ".$c['probaR0'].", 0);");
-
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgidT, $gid, 0, ".$c['pos'].", -1, ".$c['probaTrash'].", 0);");
- }
-
- $db->exec("commit;");
+ $db->exec("INSERT INTO played_game_sequence(id) values(null);");
+ return -intval($db->lastInsertRowID());
}
function decodeAndInsertGame($user,$game) {
@@ -337,28 +293,29 @@ function decodeAndInsertGame($user,$game) {
}
}
-function insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty,$userName)
+function insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty, $userName)
{
$db = getDB();
+ $sqlUserName = SQLite3::escapeString($userName);
// Insère dans la base une partie avec le mot central $centerEid, le nuage $cloud et les relations $r1 et $r2
$db->exec("begin transaction;");
$db->exec("INSERT INTO game(gid, eid_central_word, relation_1, relation_2, difficulty, author)
- VALUES (null, $centerEid, $r1, $r2, $totalDifficulty, '$userName');");
+ VALUES (null, $centerEid, $r1, $r2, $totalDifficulty, '".$sqlUserName."');");
$gid = $db->lastInsertRowID();
$t = time();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid1 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid2 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgid0 = $db->lastInsertRowID();
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
- VALUES (null, $gid, -1, null, $t);");
- $pgidT = $db->lastInsertRowID();
+ $pgid1 = getSequencePlayedGame();
+ $db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)"
+ ." VALUES ($pgid1, $gid, '".$sqlUserName."', $t);");
+ $pgid2 = getSequencePlayedGame();
+ $db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)"
+ ." VALUES ($pgid2, $gid, '".$sqlUserName."', $t);");
+ $pgid0 = getSequencePlayedGame();
+ $db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)"
+ ." VALUES ($pgid0, $gid, '".$sqlUserName."', $t);");
+ $pgidT = getSequencePlayedGame();
+ $db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)"
+ ." VALUES ($pgidT, $gid, '".$sqlUserName."', $t);");
// TODO : R0 et Trash + corrections
foreach ($cloud as $c)
@@ -367,17 +324,17 @@ function insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty,$userN
$db->exec("INSERT INTO game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash)
VALUES ($gid, ".$c['pos'].", ".$c['d'].", ".$c['eid'].", $totalWeight, ".$c['probaR1'].", ".$c['probaR2'].", ".$c['probaR0'].", ".$c['probaTrash'].");");
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid1, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
+ $db->exec("INSERT INTO played_game_cloud(pgid, login, gid, type, num, relation, weight, score)
+ VALUES ($pgid1, '".$sqlUserName."', $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid2, $gid, 0, ".$c['pos'].", $r2, ".$c['probaR2'].", 0);");
+ $db->exec("INSERT INTO played_game_cloud(pgid, login, gid, type, num, relation, weight, score)
+ VALUES ($pgid2, '".$sqlUserName."', $gid, 0, ".$c['pos'].", $r2, ".$c['probaR2'].", 0);");
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgid0, $gid, 0, ".$c['pos'].", 0, ".$c['probaR0'].", 0);");
+ $db->exec("INSERT INTO played_game_cloud(pgid, login, gid, type, num, relation, weight, score)
+ VALUES ($pgid0, '".$sqlUserName."', $gid, 0, ".$c['pos'].", 0, ".$c['probaR0'].", 0);");
- $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
- VALUES ($pgidT, $gid, 0, ".$c['pos'].", -1, ".$c['probaTrash'].", 0);");
+ $db->exec("INSERT INTO played_game_cloud(pgid, login, gid, type, num, relation, weight, score)
+ VALUES ($pgidT, '".$sqlUserName."', $gid, 0, ".$c['pos'].", -1, ".$c['probaTrash'].", 0);");
}
$db->exec("commit;");
@@ -438,108 +395,72 @@ function formatWord($word) {
return $res;
}
-/** Formate une partie en JSON en l'imprimant.
-* @param user : l'utilisateur.
-* @param gameId : L'identifiant d'une partie.
-* @param pgidNonce : pgid ou nonce de la partie. Peut être -1 uniquement si $doPlayedGame = true
-* @param doPlayedGame : enregistrer un nouveau pgid ?
-*/
-function game2json($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true)
-{
- global $stringRelations;
- $db = getDB();
- // TODO : factoriser avec game2array().
+function makePlayedGameRow($user, $gid, $pgid) {
// TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
- if ($doPlayedGame) {
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp) VALUES (null, ".intval($gameId).", ".$pgidNonce.", '".SQLite3::escapeString($user)."', -1);");
- $pgidNonce = $db->lastInsertRowID();
- }
-
- // TODO Yoann : faire des tests d'erreur pour ces select ?
- $game = $db->query("select gid, (select name from node where eid = eid_central_word) as name_central_word, eid_central_word, relation_1, relation_2 from game where gid = ".$gameId.";");
- $game = $game->fetchArray();
+ getDB()->exec("INSERT INTO played_game(pgid, gid, login, timestamp) VALUES (".longStrVal($pgid).", ".intval($gid).", '".SQLite3::escapeString($user)."', -1);");
+}
- $retstr = "";
- $retstr .= '{"gid":'.$gameId.',"pgid":'.$pgidNonce.',"relations":[';
- $retstr .= '{"id":'.$game['relation_1'].', "name":'.json_encode(''.formatWord($stringRelations[$game['relation_1']])).'}';
- $retstr .= ', {"id":'.$game['relation_2'].', "name":'.json_encode(''.formatWord($stringRelations[$game['relation_2']])).'}';
- $retstr .= ', {"id":0, "name":'.json_encode(''.formatWord($stringRelations[0])).'}';
- $retstr .= ', {"id":-1, "name":'.json_encode(''.formatWord($stringRelations[-1])).'}],';
- // $retstr .= '{"gid":'.$gameId.',"pgid":'.$pgidNonce.',"cat1":'.$game['relation_1'].',"cat2":'.$game['relation_2'].',"cat3":0,"cat4":-1,';
- $retstr .= '"center":{"id":'.$game['eid_central_word'].',"name":'.json_encode(''.formatWord($game['name_central_word'])).'},';
-
- $cloudsize = 0;
- $tmp_retstr = '';
- $notfirst = false;
- $res = $db->query("select eid_word,(select name from node where eid=eid_word) as name_word from game_cloud where gid = ".$gameId.";");
- while ($x = $res->fetchArray())
- {
- if ($notfirst)
- $tmp_retstr .= ",";
- else
- $notfirst=true;
+function getGidFromPgid($user, $pgid) {
+ return getDB()->querySingle("SELECT gid FROM played_game WHERE pgid = ".longStrVal($pgid)." and login = '".SQLite3::escapeString($user)."';");
+}
- $tmp_retstr .= '{"id":'.$x['eid_word'].',"name":'.json_encode("".formatWord($x['name_word'])).'}';
- $cloudsize++;
+function makePgid($user, $gid = null, $pgid = null) {
+ if ($gid === null && $pgid === null) {
+ $gid = randomGame();
+ $pgid = getSequencePlayedGame();
+ makePlayedGameRow($user, $gid, $pgid);
+ } elseif ($gid === null) {
+ // On essaie de voir si ce pgid est déjà connu.
+ $gid = getGidFromPgid($user, $pgid);
+ if ($gid === null) {
+ $gid = randomGame();
+ makePlayedGameRow($user, $gid, $pgid);
+ }
+ } elseif ($pgid === null) {
+ $pgid = getSequencePlayedGame();
+ makePlayedGameRow($user, $gid, $pgid);
+ } else {
+ if ($gid != getGidFromPgid($user, $pgid)) throw new Exception("Cette partie n'est pas associée à votre nom d'utilisateur.", 4);
}
- $retstr .= '"cloudsize":'.$cloudsize.',"cloud":[';
- $retstr .= $tmp_retstr;
-
- $retstr .= "]}";
- return $retstr;
+ return array($gid, $pgid);
}
-/** Récupère une partie sous forme de tableau.
-* @param user : Login de l'utilisateur demandant la partie.
+/** Formate une partie en JSON en l'imprimant.
+* @param user : l'utilisateur.
* @param gameId : L'identifiant d'une partie.
-* @param pgidNonce : pgid ou nonce de la partie. Peut être -1 uniquement si $doPlayedGame = true
-* @param doPlayedGame : enregistrer un nouveau pgid ?
*/
-function game2array($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true)
+function game2json($user, $pgid = null)
{
+ global $stringRelations;
$db = getDB();
- // TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
- if ($doPlayedGame) {
- $db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp) VALUES (null, ".intval($gameId).", ".$pgidNonce.", '".SQLite3::escapeString($user)."', -1);");
- $pgidNonce = $db->lastInsertRowID();
- }
+
+ list($gid, $pgid) = makePgid($user, null, $pgid);
- // TODO Yoann : faire des tests d'erreur pour ces select ?
- $game = $db->query("select gid, (select name from node where eid = eid_central_word) as name_central_word, eid_central_word, relation_1, relation_2 from game where gid = ".$gameId.";");
+ // TODO Yoann : faire des tests d'erreur pour ces select ?
+ $game = $db->query("select gid, (select name from node where eid = eid_central_word) as name_central_word, eid_central_word, relation_1, relation_2 from game where gid = ".$gid.";");
$game = $game->fetchArray();
- $ret = array();
- $ret['gid'] = $gameId;
- $ret['pgid'] = $pgidNonce;
- $ret['cat1'] = $game['relation_1'];
- $ret['cat2'] = $game['relation_2'];
- $ret['cat3'] = 0;
- $ret['cat4'] = -1;
- $ret['center'] = array('id' => $game['eid_central_word'], 'name' => formatWord($game['name_central_word']));
- $ret['cloud'] = array(); // TODO ! compter dynamiquement.
-
- $res = $db->query("select eid_word,(select name from node where eid=eid_word) as name_word, num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash from game_cloud where gid = ".$gameId.";");
-
+ $ret = array(
+ "gid" => $gid,
+ "pgid" => $pgid,
+ "relations" => array(
+ array("id" => $game['relation_1'], "name" => ''.$stringRelations[$game['relation_1']]),
+ array("id" => $game['relation_2'], "name" => ''.$stringRelations[$game['relation_2']]),
+ array("id" => 0, "name" => ''.$stringRelations[0]),
+ array("id" => -1, "name" => ''.$stringRelations[-1])
+ ),
+ "center" => array("id" => $game['eid_central_word'], "name" => formatWord($game['name_central_word'])),
+ "cloud" => array()
+ );
+
+ $res = $db->query("select eid_word,(select name from node where eid=eid_word) as name_word from game_cloud where gid = ".$gid.";");
while ($x = $res->fetchArray())
{
- $ret['cloud'][$x['num']] = array(
- 'id' => $x['eid_word'],
- 'name' => formatWord($x['name_word']),
- 'difficulty' => $x['difficulty'],
- 'totalWeight' => $x['totalWeight'],
- 'probaR1' => $x['probaR1'],
- 'probaR2' => $x['probaR2'],
- 'probaR0' => $x['probaR0'],
- 'probaTrash' => $x['probaTrash'],
- 'probas' => normalizeProbas($x)
- );
+ $ret['cloud'][] = array("id" => $x['eid_word'], "name" => ''.formatWord($x['name_word']));
}
-
- $ret['cloudsize'] = count($ret['cloud']);
- return $ret;
+ return json_encode($ret);
}
-
/** Création d'un lot de parties suivant un mode donnée.
* @param nbParties : le nombre de parties à créer.
* @param mode : Le mode de jeu pour les parties à créer.
@@ -563,33 +484,9 @@ function createGameCore($cloudSize)
$r1 = cgChooseRelations(); $r2 = $r1[1]; $r1 = $r1[0];
$sources = cgBuildResultSets($cloudSize, $centerEid, $r1, $r2); $sumWeights = $sources[1]; $sources = $sources[0];
$cloud = cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights); $totalDifficulty = $cloud[1]; $cloud = $cloud[0];
- cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty);
+ insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty, 'bot');
}
-/** Récupération d'une partie.
-* @param user : L'identifiant de l'utilisateur.
-* @param nbGames : Le nombre de parties à récupérer.
-* @param mode : Le mode de jeu des parties à récupérer.
-*/
-function getGame($user, $pgidNonce = null)
-{
- $nonce = "-1";
- if ($pgidNonce !== null) {
- if (substr($pgidNonce, 0, 1) == '-') {
- $temp = getDB()->querySingle("SELECT gid,pgid FROM played_game WHERE nonce = ".preg_replace('/[^0-9]/', '', $pgidNonce)." and login = '".SQLite3::escapeString($user)."';", true);
- $gid = $temp['gid'];
- $nonce = $temp['pgid'];
- if ($gid == null) { $nonce = preg_replace('/[^0-9]/', '', $pgidNonce); $pgidNonce = null; }
- } else {
- $nonce = intval($pgidNonce);
- $gid = getDB()->querySingle("SELECT gid FROM played_game WHERE pgid = ".$pgidNonce." and login = '".SQLite3::escapeString($user)."';");
- if ($gid == null) throw new Exception("Cette partie n'est associée à votre nom d'utilisateur.", 4);
- }
- }
- echo game2json($user, $pgidNonce == null ? randomGame() : $gid, $nonce, $pgidNonce == null);
-}
-
-
function computeScore($probas, $difficulty, $answer, $userReputation) {
// Calcul du score. Score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2 + bonus
// score = - proba[autres reponses]*coeff2
@@ -638,21 +535,21 @@ function normalizeProbas($row) {
function setGame($user, $pgid, $gid, $answers)
{
$db = getDB();
- if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = $pgid and gid = $gid and login = '".SQLite3::escapeString($user)."' and timestamp = -1;")) {
+ if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = ".longStrVal($pgid)." and gid = ".intval($gid)." and login = '".SQLite3::escapeString($user)."' and timestamp = -1;")) {
return getGameScores($user, $pgid, $gid);
}
$userReputation = computeUserReputation($db->querySingle("SELECT score FROM user WHERE login = '".SQLite3::escapeString($user)."';"));
$db->exec("begin transaction;");
- $db->exec("update played_game set timestamp = ".time()." where pgid = $pgid;");
+ $db->exec("update played_game set timestamp = ".time()." where pgid = ".longStrVal($pgid)." and login = '".SQLite3::escapeString($user)."';");
$r0 = 0;
$trash = -1;
- $r1 = $db->querySingle("SELECT relation_1, relation_2 FROM game WHERE gid = $gid;", true);
+ $r1 = $db->querySingle("SELECT relation_1, relation_2 FROM game WHERE gid = ".intval($gid).";", true);
$r2 = $r1['relation_2'];
$r1 = $r1['relation_1'];
- $res = $db->query("SELECT num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash FROM game_cloud WHERE gid = $gid;");
+ $res = $db->query("SELECT num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash FROM game_cloud WHERE gid = ".intval($gid).";");
$gameScore = 0;
$scores = array();
@@ -677,9 +574,10 @@ function setGame($user, $pgid, $gid, $answers)
$gameScore += $wordScore;
$scores[$num] = $wordScore;
- $db->exec("insert into played_game_cloud(pgid, gid, type, num, relation, weight, score) values($pgid, $gid, 1, $num, $r1, ".$userReputation.", ".$wordScore.");");
- $db->exec("update game_cloud set $probaRx = $probaRx + ".max(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
- $db->exec("update game_cloud set totalWeight = totalWeight + ".max(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
+ $db->exec("insert into played_game_cloud(pgid, login, gid, type, num, relation, weight, score)"
+ ." values(".longStrVal($pgid).", '".SQLite3::escapeString($user)."', ".intval($gid).", 1, $num, $r1, ".$userReputation.", ".$wordScore.");");
+ $db->exec("update game_cloud set $probaRx = $probaRx + ".max(min($userReputation/2,5),0)." where gid = ".intval($gid)." and num = $num;");
+ $db->exec("update game_cloud set totalWeight = totalWeight + ".max(min($userReputation/2,5),0)." where gid = ".intval($gid)." and num = $num;");
}
$db->exec("update user set score = score + ".$gameScore." where login = '$user';");
@@ -694,16 +592,16 @@ function setGame($user, $pgid, $gid, $answers)
function getGameScores($user, $pgid, $gid) {
$db = getDB();
- $timestamp = $db->querySingle("SELECT timestamp FROM played_game WHERE pgid = $pgid and $gid = $gid and login = '$user';");
+ $timestamp = $db->querySingle("SELECT timestamp FROM played_game WHERE pgid = ".longStrVal($pgid)." and $gid = ".intval($gid)." and login = '".SQLite3::escapeString($user)."';");
if ($timestamp == -1) {
throw new Exception("Cette partie n'a jamais été jouée.", 4); // TODO : code d'erreur en doublon avec celui ci-dessous.
} else if ($timestamp == null) {
- throw new Exception("Cette partie n'est associée à votre nom d'utilisateur.", 4);
+ throw new Exception("Cette partie n'est pas associée à votre nom d'utilisateur.", 4);
}
$gameScore = 0;
$scores = array();
- $res = $db->query("SELECT num,score from played_game_cloud where pgid = $pgid and gid = $gid;");
+ $res = $db->query("SELECT num, score from played_game_cloud where pgid = ".longStrVal($pgid)." and gid = ".intval($gid)." and login = '".SQLite3::escapeString($user)."';");
while ($row = $res->fetchArray())
{
$gameScore += $row['score'];
@@ -727,7 +625,7 @@ function get_game_relations()
$relations[] = 7;
$relations[] = 9;
$relations[] = 10;
- $relations[] = 14;
+ $relations[] = 13;
$relations[] = 22;
return $relations;
@@ -749,9 +647,9 @@ function getGameRelationsJSON() {
}
function setGameGetScore($user, $pgid, $gid, $answers) {
- $scores = setGame($user, intval($pgid), intval($gid), $answers);
+ $scores = setGame($user, $pgid, $gid, $answers);
// On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
- $scores['newGame'] = game2json($user, randomGame());
+ $scores['newGame'] = game2json($user);
$scores['minScore'] = -5;
$scores['maxScore'] = 10;
echo json_encode($scores);
diff --git a/code/serveur/php/ressources/my-extensions.js b/code/serveur/php/ressources/my-extensions.js
@@ -84,6 +84,7 @@ function queueize(method) {
$.fn.qAddClass = queueize("addClass");
$.fn.qRemoveClass = queueize("removeClass");
+$.fn.qRemove = queueize("remove");
$.fn.qShow = queueize("show");
$.fn.qHide = queueize("hide");
$.fn.qCss = queueize("css");
@@ -166,16 +167,20 @@ function decodeHash(hash) {
hash = hash.substring(1).split('/');
return {
screen:hash[0] || 'splash',
- pgid:hash[1] || -1,
+ pgid:hash[1] || 0,
answers:(hash[2] ? hash[2].split(',') : [])
};
}
+function appendAnswer(data, answer) {
+ return $.extend({}, data, { answers: data.answers.concat([answer]) });
+}
+
function encodeHash(data) {
var hash = "#";
if (data.screen == '') return hash;
hash += data.screen
- if (data.pgid == -1) return hash;
+ if (data.pgid == 0) return hash;
hash += '/'+data.pgid;
if (data.answers.length == 0) return hash;
hash += '/'+data.answers.join(',');
diff --git a/code/serveur/php/ressources/pticlic.js b/code/serveur/php/ressources/pticlic.js
@@ -1,4 +1,8 @@
// ==== URL persistante
+function trace() {
+// console.log('trace', arguments.callee.caller.toString().substring(0,100));
+}
+
var nullFunction = function(){};
var futureHashChange = null;
var runstate = {
@@ -137,7 +141,7 @@ runstate.gameCache = new Cache(function(k, dfd, cache) {
init(function() {
var game = $('#game.screen');
$('a[href="#game"]').click(function() {
- location.hash = '#game/-' + $.now();
+ location.hash = '#game/' + $.now();
return false;
});
@@ -152,19 +156,16 @@ init(function() {
game.bind('enter', function() {
$("#game .relations").empty();
var game = runstate.game;
+ runstate.relationBox = [];
$.each(game.relations, function(i, relation) {
- $('#templates .relationBox')
+ runstate.relationBox[relation.id] = $('#templates .relationBox')
.clone()
.find(".text").html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>')).end()
.find(".icon").data("image",relation.id).end()
.click(function(e) {
- state.pgid = game.pgid;
- state.answers.push(relation.id);
- location.hash = encodeHash(state);
- $(this).addClass("hot").removeClass("hot", 1000);
-/* try {
- game.nextWord({left:e.pageX, top:e.pageY}, this);
- } catch(e) {alert("Error anonymous 2 click in game.buildUi");alert(e);}*/
+ location.hash = encodeHash(appendAnswer(state, relation.id));
+ window.document.title = "PtiClic "+state.answers.length+' / '+game.cloud.length;
+ $(this).addClass("hot");
})
.appendTo("#game .relations");
});
@@ -173,9 +174,40 @@ init(function() {
});
game.bind('update', function(e) {
- $("#game .mn").text(runstate.game.cloud[state.answers.length].name);
+ var direction = state.answers.length - oldstate.answers.length;
+ var mn = $("#game .mn-caption");
+ var clone = $();
+ if (direction != 0) {
+ clone = (mn)
+ .stop().clearQueue()
+ .clone().removeClass('center')
+ .appendTo("body") // Append to body so we can animate the offset (instead of top/left)
+ .offset(mn.offset());
+ }
+ mn.text(runstate.game.cloud[state.answers.length].name);
jss();
- console.log('update');
+ if (direction != 0) {
+ // window.setTimeout pour éviter que le offset (ci-dessus) ne soit animé, et pour que le temps de rendu de la page ne soit pas inclus dans le temps d'animation.
+ window.setTimeout(function() {
+ (clone)
+ .addClass("transition")
+ .css(runstate.relationBox[state.answers[state.answers.length - 1]].center())
+ .css({fontSize: 0})
+ .delay(700)
+ .qRemove();
+ $('.relationBox.hot').addClass('transition-bg').removeClass('hot').delay(700).qRemoveClass('transition-bg');
+ }, 0);
+ }
+/* var fs = mn.css("fontSize");
+ var mncbCenter = $("#game #mn-caption-box").center();
+
+ (mn)
+ .css("fontSize", 0)
+ .animate({fontSize: fs}, {duration:700, step:function(){
+ try {
+ mn.center(mncbCenter);
+ } catch(e) {alert("Error anonymous 2 in game.animateNext");alert(e);}
+ }}); */
});
});
diff --git a/code/serveur/php/server.php b/code/serveur/php/server.php
@@ -75,7 +75,7 @@ function main()
}
else if($action == 0) { // "Get partie"
// Requête POST : http://serveur/server.php?action=0&user=foo&passwd=bar
- getGame($user, isset($_GET['pgid']) ? $_GET['pgid'] : null);
+ echo game2json($user, isset($_GET['pgid']) ? $_GET['pgid'] : null);
}
else if($action == 1) { // "Set partie"
// Requête POST : http://serveur/server.php?action=1&mode=normal&user=foo&passwd=bar&gid=1234&pgid=12357&0=0&1=-1&2=22&3=13&9=-1
diff --git a/code/serveur/php/showGame.php b/code/serveur/php/showGame.php
@@ -1,153 +0,0 @@
-<?php
- session_start();
-?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
- <head>
- <title>PtiClic sous Android™ - Version Alpha - Accueil</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link rel="stylesheet" href="ressources/simple.css" />
- <link rel="stylesheet" href="ressources/backend.css" />
- </head>
- <body>
- <?php include("ressources/menu.inc"); ?>
- <div class="content">
- <?php include("ressources/showmsg.inc"); ?>
- <h2>PtiClic : Affichage de parties</h2>
- <?php
- require_once("ressources/backend.inc");
- require_once("ressources/relations.inc");
- $gameId = randomGame();
- if (isset($_GET['gid'])) $gameId = intval($_GET['gid']);
- if (isset($_POST['gid'])) $gameId = intval($_POST['gid']);
- $game = game2array("foo", $gameId);
- ?>
- <h3>Informations internes sur le nuage</h3>
- <p>
- Partie numéro <?php echo $gameId; ?> (pgid=<?php echo $game['pgid']; ?>). Pous pouvez obtenir aléatoirement une <a href="showGame.php">autre partie</a>,
- ou avoir un lien vers <a href="showGame.php?gid=<?php echo $gameId; ?>">celle-ci</a>.
- </p>
- <p>
- Vous avez actuellement un score de <?php echo $currentUserScore = getDB()->querySingle("SELECT score FROM user WHERE login='foo';"); ?> points
- et une réputation de <?php echo computeUserReputation($currentUserScore); ?>, ce qui est assez mauvais.
- Vous n'avez aucun espoir de briller grâce à ce jeu. Retournez donc coder.
- </p>
- <?php
- if (isset($_POST['gid'])) {
- $scores = setGame("foo", $game['pgid'], $gameId, $_POST);
- echo '<a name="results"></a>';
- echo '<p>Voilà une bien belle partie ! Vous avez gagné '.$scores['total'].' points au total. Maintenant, retournez coder.</p>';
- }
- ?>
- <ul>
- <li>Poids désigne le poids pour cette relation entre le mot central et le mot en cours (pour cette partie).</li>
- <li>PoidsTotal désigne la somme des poids sur la ligne. C'est un bon indice de la fiabilité des poids pour ce mot : plus PoidsTotal est faible, moins c'est fiable.</li>
- <li>Proba désigne la probabilité que le mot soit associé au mot central avec cette relation.</li>
- <li>Score indique le score que ferait un utilisateur pour ce mot avec cette relation, s'il avait un score de départ de 10, 100, 1000.</li>
- </ul>
- <table class="show-game">
- <thead>
- <tr>
- <th colspan="3" style="color: darkgreen;"><?php echo $game['center']['name'] . " (eid = " . $game['center']['id'] . ")"; ?></th>
- <th rowspan="2">PoidsTotal</th>
- <th colspan="6"><?php echo $stringRelations[$game['cat1']] . " (rid = " . $game['cat1'] . ")"; ?></th>
- <th colspan="6"><?php echo $stringRelations[$game['cat2']] . " (rid = " . $game['cat2'] . ")"; ?></th>
- <th colspan="6"><?php echo $stringRelations[$game['cat3']] . " (rid = " . $game['cat3'] . ")"; ?></th>
- <th colspan="6"><?php echo $stringRelations[$game['cat4']] . " (rid = " . $game['cat4'] . ")"; ?></th>
- <?php
- if (isset($_POST['gid'])) {
- echo '<th rowspan="2">Votre réponse</th>';
- echo '<th rowspan="2">Votre score</th>';
- }
- ?>
- </tr>
- <tr>
- <th>Num.</th>
- <th>Mot</th>
- <th>EID</th>
-
- <th>Poids</th>
- <th>Proba</th>
- <th colspan="4">Score 0, 10, 100, 1000</th>
-
- <th>Poids</th>
- <th>Proba</th>
- <th colspan="4">Score 0, 10, 100, 1000</th>
-
- <th>Poids</th>
- <th>Proba</th>
- <th colspan="4">Score 0, 10, 100, 1000</th>
-
- <th>Poids</th>
- <th>Proba</th>
- <th colspan="4">Score 0, 10, 100, 1000</th>
- </tr>
- </thead>
- <tbody>
- <?php
- foreach ($game['cloud'] as $k => $v) {
- ?>
- <tr>
- <td><?php echo $k . "."; ?></td>
- <th><?php echo $v['name']; ?></th>
- <td><?php echo $v['id']; ?></td>
- <td><?php echo $v['totalWeight']; ?></td>
- <?php
- $columns = array(0 => 'probaR1', 1 => 'probaR2', 2 => 'probaR0', 3 => 'probaTrash');
- foreach ($columns as $answer => $probaRX) {
- echo "<td";
- if (isset($_POST['gid']) && $game['cat'.($answer+1)] == $_POST[$k])
- echo ' style="background-color:#ddd;"';
- echo '>' . $v[$probaRX] . "</td>";
- echo '<td style="color:#'
- . str_pad(dechex(max(0,min(255,0xff - 1.3*255*$v['probas'][$answer]))), 2, "0", STR_PAD_LEFT)
- . str_pad(dechex(max(0,min(255, 1.3*255*$v['probas'][$answer]))), 2, "0", STR_PAD_LEFT)
- . '00;">'
- . (round($v['probas'][$answer]*100)/100) . "</td>";
- echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(0))."</td>";
- echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(10))."</td>";
- echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(100))."</td>";
- echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(1000))."</td>";
- }
- ?>
- <?php
- if (isset($_POST['gid'])) {
- echo '<td>'.$stringRelations[$_POST[$k]]." (rid=".$_POST[$k].")".'</td>';
- echo '<td>'.$scores[$k].'</td>';
- }
- ?>
- </tr>
- <?php
- }
- ?>
- </tbody>
- </table>
-
- <h3>Jouer à la partie</h3>
- <form action="showGame.php#results" method="POST">
- <input type="hidden" name="gid" id="gid" value="<?php echo $gameId; ?>" />
- <p>Mot central : <span style="color: darkgreen;"><?php echo $game['center']['name']; ?></span>.</p>
- <table class="show-game">
- <tbody>
- <?php
- foreach ($game['cloud'] as $k => $v) {
- ?>
- <tr>
- <th><?php echo $v['name']; ?></th>
- <?php for ($answer = 0; $answer < 4; $answer++) { ?>
- <td>
- <input type="radio" name="<?php echo $k; ?>" id="<?php echo $k . '-' . $answer; ?>" value="<?php echo $game['cat'.($answer+1)]; ?>" />
- <label for="<?php echo $k . '-' . $answer; ?>"><?php echo $stringRelations[$game['cat'.($answer+1)]]; ?></label>
- </td>
- <?php } ?>
- </tr>
- <?php
- }
- ?>
- </tbody>
- </table>
- <input type="submit" value="Gamble !" />
- </form>
- </div>
- <?php include("ressources/footer.inc"); ?>
- </body>
-</html>