commit 86ce7a8ad49480f9f0828c61a84fa43680494064
parent 5113c279567f4d09b4eb30be85f95ed11aad7d9a
Author: Bertrand BRUN <bertrand0brun@gmail.com>
Date: Thu, 3 Feb 2011 09:29:29 +0100
Merge branch 'master' of https://github.com/jsmaniac/2011-m1s2-ter
Diffstat:
2 files changed, 105 insertions(+), 79 deletions(-)
diff --git a/code/serveur/dump2sqlite.sh b/code/serveur/dump2sqlite.sh
@@ -7,6 +7,8 @@ echo " La progression est affichée avec pv. Si vous n'avez pas pv, supprimez l
echo " Et c'est parti !" >&2
echo >&2
+# Played_game(type) : 0 => partie de référence, 1 => joueur
+
cat <<EOF
begin transaction;
create table node(eid integer primary key autoincrement, name, type, weight);
@@ -14,9 +16,10 @@ create table relation(rid integer primary key autoincrement, start, end, type, w
create table type_node(name, num);
create table type_relation(name, num, extended_name, info);
create table user(login primary key, mail, hash_passwd);
-create table game(gid integer primary key autoincrement, eid_central_word, relation_1, relation_2, relation_3, relation_4, reference_played_game);
-create table game_cloud(gid, num, difficulty, eid_word);
-create table played_game(gid, type, num, relation, weight);
+create table game(gid integer primary key autoincrement, eid_central_word, relation_1, relation_2, difficulty);
+create table game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash);
+create table played_game(pgid integer primary key autoincrement, gid, login);
+create table played_game_cloud(pgid, gid, type, num, relation, weight, score);
EOF
# tr : pour virer le CRLF qui traîne
diff --git a/code/serveur/php/pticlic.php b/code/serveur/php/pticlic.php
@@ -1,6 +1,7 @@
<?php
// Requête : http://serveur/pticlic.php?action=getparties&nb=2&mode=normal&user=foo&passwd=bar
+$do_initdb = false;
$email_admin = ''; // Adresse e-mail Administrateur.
$SQL_DBNAME = (dirname(__FILE__) . "/db");
@@ -20,7 +21,7 @@ function initdb() {
$db->exec("insert into user(login, mail, hash_passwd) values('foo', 'foo@isp.com', '".md5('bar')."');");
}
-// initdb();
+if ($do_initdb) initdb();
if(!isset($_GET['action']) || !isset($_GET['user']) || !isset($_GET['passwd']))
mDie(2,"La requête est incomplète");
@@ -49,27 +50,28 @@ function cg_build_result_sets($cloudSize, $centerEid, $r1, $r2) {
$typer1r2 = "type in ($r1, $r2)";
$sources = array(
// Voisins 1 saut du bon type (= relations déjà existantes)
- array('w'=>10, 'd'=>1, 's'=>"select end as eid, type = $r1 as r1, type = $r2 as r2 from relation where start = $centerEid and $typer1r2 order by random();"),
+ array('w'=>40, 'd'=>1, 's'=>"select end as eid, type = $r1 as r1, type = $r2 as r2, 0 as r0, 0 as trash from relation where start = $centerEid and $typer1r2 order by random();"),
// Voisins 1 saut via r_associated (0), donc qu'on voudrait spécifier si possible.
- array('w'=>10, 'd'=>2, 's'=>"select end as eid, 0 as r1, 0 as r2 from relation where start = $centerEid and type = 0 order by random();"),
+ array('w'=>40, 'd'=>2, 's'=>"select end as eid, 0.25 as r1, 0.25 as r2, 0.5 as r0, 0 as trash from relation where start = $centerEid and type = 0 order by random();"),
// Voisins 1 saut via les autres relations
- array('w'=>10, 'd'=>3, 's'=>"select end as eid, 0 as r1, 0 as r2 from relation where start = $centerEid and type not in (0, $r1, $r2) order by random();"),
+ // TODO ! certains de ces select pourraient renvoyer des mots de types systèmes (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001), il faut les éliminer.
+ array('w'=>20, 'd'=>3, 's'=>"select end as eid, 0.1 as r1, 0.1 as r2, 0.8 as r0, 0 as trash from relation where start = $centerEid and type not in (0, $r1, $r2) order by random();"),
// Voisins 2 sauts, avec un mix de R1 et R2 pour les liens. Par ex [ A -R1-> B -R2-> C ] ou bien [ A -R2-> B -R2-> C ]
// Version optimisée de : "select end as eid from relation where $typer1r2 and start in oneHopWithType order by random();"
- array('w'=>10, 'd'=>4, 's'=>"select B.end as eid, ((A.type = $r1) + (B.type = $r1)) / 3 as r1, ((A.type = $r2) + (B.type = $r2)) / 3 as r2 from relation as A, relation as B where A.start = $centerEid and A.$typer1r2 and B.start = A.end and B.$typer1r2 order by random();"),
+ array('w'=>30, 'd'=>3, 's'=>"select B.end as eid, ((A.type = $r1) + (B.type = $r1)) / 3 as r1, ((A.type = $r2) + (B.type = $r2)) / 3 as r2, 1/6 as r0, 1/6 as trash from relation as A, relation as B where A.start = $centerEid and A.$typer1r2 and B.start = A.end and B.$typer1r2 order by random();"),
// Voisins 1 saut r1/r2 + 1 saut synonyme
// Version optimisée de : "select end as eid from relation where start in oneHopWithType and type = 5 order by random();"
- array('w'=>10, 'd'=>5, 's'=>"select B.end as eid, (A.type = $r1) * 0.75 as r1, (A.type = $r2) * 0.75 as r2 from relation as A, relation as B where A.start = $centerEid and A.$typer1r2 and B.start = A.end and B.type = 5 order by random();"),
+ array('w'=>20, 'd'=>5, 's'=>"select B.end as eid, (A.type = $r1) * 0.75 as r1, (A.type = $r2) * 0.75 as r2, 0.25 as r0, 0 as trash from relation as A, relation as B where A.start = $centerEid and A.$typer1r2 and B.start = A.end and B.type = 5 order by random();"),
// Version optimisée de : "select end as eid from relation where start in (select end from relation where start = $centerEid and type = 5) and $typer1r2 order by random();"
- array('w'=>10, 'd'=>6, 's'=>"select B.end as eid, (B.type = $r1) * 0.75 as r1, (B.type = $r2) * 0.75 as r2 from relation as A, relation as B where A.start = $centerEid and A.type = 5 and B.start = A.end and B.$typer1r2 order by random();"),
+ array('w'=>20, 'd'=>6, 's'=>"select B.end as eid, (B.type = $r1) * 0.75 as r1, (B.type = $r2) * 0.75 as r2, 0.25 as r0, 0 as trash from relation as A, relation as B where A.start = $centerEid and A.type = 5 and B.start = A.end and B.$typer1r2 order by random();"),
// Voisins 2 sauts (tous)
- array('w'=>10, 'd'=>7, 's'=>"select end as eid, 0.1 as r1, 0.1 as r2 from relation where start in (select end from relation where start = $centerEid) order by random();"),
+ array('w'=>10, 'd'=>7, 's'=>"select end as eid, 0.1 as r1, 0.1 as r2, 0.3 as r0, 0.5 as trash from relation where start in (select end from relation where start = $centerEid) order by random();"),
// Centre pointe vers X, M pointe vers X aussi, on prend M.
// Version optimisée de : "select start as eid from relation where end in (select end from relation where start = $centerEid) and type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) order by random();"
// Ce n'est toujours pas ça… : "select eid from (select B.start as eid from relation as A, relation as B where A.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and A.start = $centerEid and B.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and B.end = A.end limit 1) order by random();"
// Tordu, mais ça marche \o/ . En fait il faut empêcher l'optimiseur de ramener le random avant le limit (et l'optimiseur est malin… :)
- array('w'=>10, 'd'=>8, 's'=>"select x as eid, -0.1 as r1, -0.1 as r2 from (select x from (select X.eid + Y.dumb as x from (select B.start as eid from relation as A, relation as B where A.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and A.start = 74860 and B.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and B.end = A.end limit $cloudSize) as X, (select 0 as dumb) as Y)) order by random();"),
- 'rand' => array('w'=>10, 's'=>false) // random. Le r1 et r2 de random sont juste en-dessous
+ array('w'=>10, 'd'=>8, 's'=>"select x as eid, 0.1 as r1, 0.1 as r2, 0.2 as r0, 0.6 as trash from (select x from (select X.eid + Y.dumb as x from (select B.start as eid from relation as A, relation as B where A.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and A.start = 74860 and B.type not in (4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) and B.end = A.end limit $cloudSize) as X, (select 0 as dumb) as Y)) order by random();"),
+ 'rand' => array('w'=>5, 'd'=>10, 's'=>false) // random. Le r1 et r2 de random sont juste en-dessous
);
$sumWeights = 0;
@@ -88,7 +90,7 @@ function cg_build_result_sets($cloudSize, $centerEid, $r1, $r2) {
} else {
$sources[$k]['resultSet'] = array();
for ($i = 0; $i < 10; $i++) {
- $sources[$k]['resultSet'][] = array('eid'=>random_node(), 'r1'=>-1, 'r2'=>-1);
+ $sources[$k]['resultSet'][] = array('eid'=>random_node(), 'r1'=>0, 'r2'=>0, 'r0'=>0, 'trash'=>1);
$sources[$k]['rsSize']++;
}
}
@@ -97,7 +99,7 @@ function cg_build_result_sets($cloudSize, $centerEid, $r1, $r2) {
}
function cg_choose_relations() {
- $relations = array(5, 7, 9, 10);
+ $relations = array(5, 7, 9, 10, /* Pas d'icônes pour celles-ci. */ 13, 14, 22);
$r1 = rand(0,count($relations)-1);
$r2 = rand(0,count($relations)-2);
if ($r2 >= $r1) $r2++;
@@ -111,20 +113,27 @@ function cg_build_cloud($cloudSize, $sources, $sumWeights) {
$cloud = array();
$nbFailed = 0;
$i = 0;
+ $totalDifficulty = 0;
while ($i < $cloudSize && $nbFailed < 5*$cloudSize) {
// On choisit une source aléatoire en tennant compte des poids.
$rands = rand(1,$sumWeights);
$sumw = 0;
$src = $sources['rand'];
- foreach ($sources as $x) {
+ $srck = null;
+ foreach ($sources as $k => $x) {
$sumw += $x['w'];
if ($rands < $sumw) {
$src = $x;
+ $srck = $k;
break;
}
}
if ($src['rsPos'] >= $src['rsSize']) {
$nbFailed++;
+ if ($srck !== null) {
+ $sumWeights -= $src['w'];
+ unset($sources[$srck]);
+ }
continue;
}
$res = $src['resultSet'][$src['rsPos']++];
@@ -133,22 +142,30 @@ function cg_build_cloud($cloudSize, $sources, $sumWeights) {
continue;
}
// position dans le nuage, difficulté, eid, probaR1, probaR2
- $cloud[$i] = array('pos'=>$i++, 'd'=>$src['d'], 'eid'=>$res['eid'], 'probaR1'=>$res['r1'], 'probaR2'=>$res['r2']);
+ $totalDifficulty += $src['d'];
+ $cloud[$i] = array('pos'=>$i++, 'd'=>$src['d'], 'eid'=>$res['eid'], 'probaR1'=>$res['r1'], 'probaR2'=>$res['r2'], 'probaR0'=>$res['r0'], 'probaTrash'=>$res['trash']);
}
+ $res = $sources['rand']['resultSet'][0];
while ($i < $cloudSize) {
- $cloud[$i] = array('pos'=>$i++, 'd'=>$sources['rand']['d'], 'eid'=>random_node(), 'probaR1'=>$sources['rand']['resultSet'][0]['r1'], 'probaR2'=>$sources['rand']['resultSet'][0]['r2']);
+ $totalDifficulty += $sources['rand']['d'];
+ $cloud[$i] = array('pos'=>$i++, 'd'=>$sources['rand']['d'], 'eid'=>random_node(), 'probaR1'=>$res['r1'], 'probaR2'=>$res['r2'], 'probaR0'=>$res['r0'], 'probaTrash'=>$res['trash']);
}
- return $cloud;
+ return array($cloud, $totalDifficulty);
}
-function cg_insert($centerEid, $cloud, $r1, $r2) {
+function cg_insert($centerEid, $cloud, $r1, $r2, $totalDifficulty) {
+ // Insère dans la base une partie avec le mot central $centerEid, le nuage $cloud et les relations $r1 et $r2
+ global $db;
$db->exec("begin transaction;");
- $db->exec("insert into game(gid, eid_central_word, relation_1, relation_2) values (null, $centerEid, $r1, $r2);");
+ $db->exec("insert into game(gid, eid_central_word, relation_1, relation_2, difficulty) values (null, $centerEid, $r1, $r2, $totalDifficulty);");
$gid = $db->lastInsertRowID();
+ $db->exec("insert into played_game(pgid, gid, login) values (null, $gid, null);");
+ $pgid = $db->lastInsertRowID();
foreach ($cloud as $c) {
- $db->exec("insert into game_cloud(gid, num, difficulty, probaR1, probaR2, eid_word) values($gid, ".$c['pos'].", ".$c['d'].", ".$c['probaR1'].', '.$c['probaR2'].', '.$c['eid'].");");
+ $db->exec("insert into game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash) values($gid, ".$c['pos'].", ".$c['d'].", ".$c['eid'].", 2, ".$c['probaR1'].", ".$c['probaR2'].", ".$c['probaR0'].", ".$c['probaTrash'].");");
+ $db->exec("insert into played_game_cloud(pgid, gid, type, num, relation, weight, score) values($pgid, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
+ $db->exec("insert into played_game_cloud(pgid, gid, type, num, relation, weight, score) values($pgid, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
}
- // TODO : insert into game_played une partie de référence.
$db->exec("commit;");
}
@@ -158,65 +175,71 @@ function create_game($cloudSize) {
$centerEid = random_node();
$r1 = cg_choose_relations(); $r2 = $r1[1]; $r1 = $r1[0];
$sources = cg_build_result_sets($cloudSize, $centerEid, $r1, $r2); $sumWeights = $sources[1]; $sources = $sources[0];
- $cloud = cg_build_cloud($cloudSize, $sources, $sumWeights);
- cg_insert($centerEid, $cloud);
-
- var_dump($cloud);
- exit;}
+ $cloud = cg_build_cloud($cloudSize, $sources, $sumWeights); $totalDifficulty = $cloud[1]; $cloud = $cloud[0];
+ cg_insert($centerEid, $cloud, $r1, $r2, $totalDifficulty);
+}
-create_game(10);
-echo 'ok';
+//create_game(10);
-// // Sinon tout est bon on effectu l'opération correspondant à la commande passée.
-// if($action == 0) // "Get partie"
-// {
-// // Requête sql de création de partie.
-// $req = "...";
-
-// $sql = sqlConnect();
-// $resp = mysql_query($req);
-
-// if(mysql_num_rows($resp) == 0)
-// echo mysql_error();
-// else
-// {
-// $sequence = "...";
-// echo $sequence;
-// }
-
-// mysql_close($sql);
-// }
-// else if($action == 1) // "Set partie"
-// {
-// // Requête sql d'ajout d'informations (et calcul de résultat).
-// $req = "...";
-
-// $sql = sqlConnect();
-// $resp = mysql_query($req);
+function random_game() {
+ global $db;
+ return $db->querySingle("select gid from game where gid = (abs(random()) % (select max(gid) from game))+1 or gid = (select max(gid) from game where gid > 0) order by gid limit 1;");
+}
+
+function game2json($game_id) {
+ global $db;
+ // 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 = ".$game_id.";");
+ $game = $game->fetchArray();
+ echo "{id:".$game['gid'].",cat1:".$game['relation_1'].",cat2:".$game['relation_2'].",cat3:0,cat4:-1,";
+ echo "center:{id:".$game['eid_central_word'].",name:".json_encode("".$game['name_central_word'])."},";
+ echo "cloudsize:10,cloud:["; // TODO ! compter dynamiquement.
-// if(mysql_num_rows($resp) == 0)
-// echo mysql_error();
-// else
-// {
-// $sequence = "...";
-// echo $sequence;
-// }
+ $res = $db->query("select eid_word,(select name from node where eid=eid_word) as name_word from game_cloud where gid = ".$game['gid'].";");
+ while ($x = $res->fetchArray()) {
+ echo "{id:".$x['eid_word'].",name:".$x['name_word']."}\n";
+ }
+ echo "]}";
+}
+
+function main() {
+ // Sinon tout est bon on effectu l'opération correspondant à la commande passée.
+ if($action == 0) { // "Get partie"
+ if(!isset($_GET['nb']) || !isset($_GET['mode']))
+ mDie(2,"La requête est incomplète");
+ $nbGames = intval($_GET['nb']);
-// mysql_close($sql);
-// }
-// else if($action == 2)
-// {
-
-// }
-// else if($action == 3)
-// {
-
-// }
-// else if($action == 4)
-// {
-
-// }
-// else
-// die("Commande inconnue");
+ echo "[";
+ for ($i=0; $i < $nbGames; $i) {
+ game2json(random_game());
+ if ((++$i) < $nbGames) {
+ echo ",";
+ }
+ }
+ echo "]";
+ } else if($action == 1) { // "Set partie"
+ // Requête sql d'ajout d'informations (et calcul de résultat).
+ // TODO : nettoyer, finir
+ $gid = $_GET['gid']; // TODO : vérifier qu'on a bien distribué cette partie à cet utilisateur, et qu'il n'y a pas déjà répondu (répercuter ça sur le random_game).
+ $userReputation = 5; // TODO : un nombre entre 0 et 5 environ. Par ex. log(pointsUtilisateur) est un bon choix.
+ $db->exec("begin transaction;");
+ $db->exec("insert into played_game(pgid, gid, login) values (null, $gid, null);");
+ $pgid = $db->lastInsertRowID();
+ for ($i=0; $i < 10; $i++) {
+ $x = $_GET['$i'];
+ // TODO : calculer le score. Score = proba[réponse de l'utilisateur]*coeff - proba[autres reponses]*coeff
+ // TODO : adapter le score en fonction de la réputation de l'utilisateur (plus quand il est jeune, pour le motiver, par ex. avec un terme constant qu'on ajoute).
+ $score = 1;
+ $db->exec("insert into played_game_cloud(pgid, gid, type, num, relation, weight, score) values($pgid, $gid, 1, ".$c['pos'].", $r1, ".($x*$userReputation).", ".$score.");");
+ // TODO : game_cloud(probaR_x_) += $réputationJoueur * $coeff
+ // TODO : game_cloud(totalWeight) += $réputationJoueur * $coeff (NOTE : même coeff que pour game_cloud(probaR_x_))
+ }
+ $db->exec("commit;");
+ // On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
+ game2json(random_game());
+ } else {
+ die("Commande inconnue");
+ }
+}
?>