www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Dcode/serveur/dump2mysql.sh | 48------------------------------------------------
Mcode/serveur/dump2sqlite.sh | 6++++--
Mcode/serveur/php/jeu.php | 9++++++---
Mcode/serveur/php/ressources/backend.inc | 294++++++++++++++++++++++++++-----------------------------------------------------
Mcode/serveur/php/ressources/my-extensions.js | 9+++++++--
Mcode/serveur/php/ressources/pticlic.js | 54+++++++++++++++++++++++++++++++++++++++++++-----------
Mcode/serveur/php/server.php | 2+-
Dcode/serveur/php/showGame.php | 153-------------------------------------------------------------------------------
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>