www

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

pticlic.php (20708B)


      1 <?php
      2 
      3 require_once("relations.php");
      4 require_once("db.php");
      5 require_once("ressources/errors.inc");
      6 
      7 /* Les prototypes des fonctions :
      8 * ===============================>
      9 *   checkLogin($user, $passwd);
     10 *   randomCenterNode();
     11 *   randomCloudNode();
     12 *   cgBuildResultSets($cloudSize, $centerEid, $r1, $r2);
     13 *   cgChooseRelations();
     14 *   cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights);
     15 *   cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty);
     16 *   randomGameCore();
     17 *   randomGame();
     18 *   formatWord($word);
     19 *   game2json($user, $gameId);
     20 *   game2array($user, $gameId);
     21 *   createGame($nbParties, $mode);
     22 *   createGameCore($cloudSize);
     23 *   getGame($user, $nbGames, $mode);
     24 *   computeScore($probas, $difficulty, $answer, $userReputation);
     25 *   computeUserReputation($score);
     26 *   normalizeProbas($row);
     27 *   setGame($user, $pgid, $gid, $answers);
     28 *   get_game_relations();
     29 	getGameRelationsJSON();
     30 *   setGameGetScore($user, $pgid, $gid, $answers);
     31 *   insertNode($node);
     32 *   getNodeEid($node);
     33 */
     34 
     35 
     36 /**  Vérifie la validité du couple nom d'utilisateur / mot de passe.
     37 * @param user : Le nom d'utilisateur.
     38 * @param passwd : Le mot de passe.
     39 * @return boolean : true si OK sinon false.
     40 */
     41 function checkLogin($user, $passwd) {
     42 	$db = getDB();
     43 	$hashPasswd = md5($passwd);
     44 	$loginIsOk = ($hashPasswd == $db->querySingle(sqlGetPassword($user)));
     45 	return $loginIsOk;
     46 }
     47 
     48 /** Selectionne aléatoirement l'eid d'un mot central.
     49 * @return eid : Identifiant d'un mot central, NULL en cas d'erreur.
     50 */
     51 function randomCenterNode()
     52 {
     53 	$db = getDB();
     54 	return $db->querySingle(sqlGetEIDCenterNode());
     55 }
     56 
     57 /** Selectionne aléatoirement un noeud d'un nuage.
     58 * @return eid : L'identifiant du noeud.
     59 */
     60 function randomCloudNode()
     61 {
     62 	$db = getDB();
     63 	return $db->querySingle(sqlGetEIRCloudNode());
     64 }
     65 
     66 /**
     67 * @param cloudSize : Taille du nuage.
     68 * @param centerEid : Identifiant du mot central.
     69 * @param r1 Type de la relation 1.
     70 * @param r2 Type de la relation 2.
     71 */
     72 function cgBuildResultSets($cloudSize, $centerEid, $r1, $r2)
     73 {
     74 	$db = getDB();
     75 	// 'w' => weight (poids), 'd' => difficulté, 's' => select
     76 	// Le select doit ranvoyer trois colonnes :
     77 	//   eid => l'eid du mot à mettre dans le nuage,
     78 	//   r1 => la probabilité pour que le mot soit dans r1, entre -1 et 1 (négatif = ne devrait pas y être, positif = devrait y être à coup sûr, 0 = on sait pas).
     79 	
     80 	$sources = array(
     81 		array('w'=>40, 'd'=>1, 's'=>sql1JumpGoodType($r1, $r2, $centerEid)),
     82 		array('w'=>40, 'd'=>2, 's'=>sql1JumpViaRAssociated0($centerEid)),
     83 		array('w'=>20, 'd'=>3.1, 's'=>sql1JumpViaOtherRelation($centerEid, $r1, $r2, $banned_types)),
     84 		array('w'=>30, 'd'=>3.2, 's'=>sql2JumpWithMixR1R2ForLinks($r1, $r2, $centerEid)),
     85 		array('w'=>20, 'd'=>5, 's'=>sql1JumpR1DivR2Plus1JumpSynonymOneHopWithType($r1, $r2, $centerEid)),
     86 		array('w'=>20, 'd'=>6, 's'=>sql1JumpR1DivR2Plus1JumpSynonym($r1, $r2, $centerEid)),
     87 		array('w'=>10, 'd'=>8, 's'=>sql2JumpAll($centerEid, $cloudSize)),
     88 		array('w'=>10, 'd'=>8, 's'=>sqlXPointsToMMPointsToXTakeM($cloudSize)),
     89 		'rand' => array('w'=>5, 'd'=>10, 's'=>false) // random. Le r1 et r2 de random sont juste en-dessous
     90 	);
     91 
     92 	$sumWeights = 0;
     93 	
     94 	foreach ($sources as $k => $x)
     95 	{
     96 		$sumWeights += $x['w'];
     97 		$sources[$k]['rsPos'] = 0;
     98 		$sources[$k]['rsSize'] = 0;
     99 		
    100 		if ($x['s'] !== false)
    101 		{
    102 			$sources[$k]['resultSet'] = array();
    103 			$res = $db->query($x['s']);
    104 			$i = 0;
    105 			
    106 			while ($i < 10 && $sources[$k]['resultSet'][] = $res->fetchArray())
    107 			{
    108 				$i++;
    109 				$sources[$k]['rsSize']++;
    110 			}
    111 		} 
    112 		else
    113 		{
    114 			$sources[$k]['resultSet'] = array();
    115 			
    116 			for ($i = 0; $i < 10; $i++)
    117 			{
    118 				$sources[$k]['resultSet'][] = array('eid'=>randomCloudNode(), 'r1'=>0, 'r2'=>0, 'r0'=>0, 'trash'=>1);
    119 				$sources[$k]['rsSize']++;
    120 			}
    121 		}
    122 	}
    123 
    124 	return array($sources, $sumWeights);
    125 }
    126 
    127 
    128 /** Sélectionne aléatoirement deux relations.
    129 * @return array : Tableau avec la relation 1 et la relation 2.
    130 */
    131 function cgChooseRelations()
    132 {
    133 	$relations = array(5, 7, 9, 10);// /* Pas d'icônes pour celles-ci. */ 13, 14, 22);
    134 	$r1 = rand(0,count($relations)-1);
    135 	$r2 = rand(0,count($relations)-2);
    136 
    137 	if ($r2 >= $r1)
    138 		$r2++;
    139 
    140 	$r1 = $relations[$r1];
    141 	$r2 = $relations[$r2];
    142 
    143 	return array($r1, $r2);
    144 }
    145 
    146 /** Génération d'un nuage pour un mot central.
    147 * @param cloudSize : Taille du nuage.
    148 * @param sources Les sources.
    149 * @param sumWeights La somme des poids.
    150 * @return array : Tableau avec comme premier élément le nuage et comme second élément le total de difficulté.
    151 */
    152 function cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights)
    153 {
    154 	$db = getDB();
    155 	// On boucle tant qu'il n'y a pas eu au moins 2 sources épuisées
    156 	$cloud = array();
    157 	$nbFailed = 0;
    158 	$i = 0;
    159 	$totalDifficulty = 0;
    160 	
    161 	while ($i < $cloudSize && $nbFailed < 10*$cloudSize)
    162 	{
    163 		// On choisit une source aléatoire en tennant compte des poids.
    164 		$rands = rand(1,$sumWeights);
    165 		$sumw = 0;
    166 		if (!isset($sources['rand'])) {
    167 			break;
    168 		}
    169 		$src = $sources['rand'];
    170 		$srck = 'rand';
    171 
    172 		// Sélection d'une source aléatoire
    173 		foreach ($sources as $k => $x)
    174 		{
    175 			$sumw += $x['w'];
    176 			
    177 			if ($rands < $sumw)
    178 			{
    179 				$src = $x;
    180 				$srck = $k;
    181 				break;
    182 			}
    183 		}
    184 		
    185 		// Vérification si on est à la fin du ResultSet de cette source.
    186 		if ($src['rsPos'] >= $src['rsSize'])
    187 		{
    188 			$nbFailed++;
    189 
    190 			$sumWeights -= $src['w'];
    191 			unset($sources[$srck]);
    192 
    193 			continue;
    194 		}
    195 		
    196 		// On récupère un résultat de cette source.
    197 		$res = $src['resultSet'][$src['rsPos']];
    198 		$sources[$srck]['rsPos']++;
    199 
    200 		// On vérifie si le mot n'a pas déjà été sélectionné.
    201 		$rejected = false;
    202 		// Ne pas mettre le mot central dans le nuage.
    203 		if ($res['eid'] == $centerEid) { continue; }
    204 		$nodeName = $db->querySingle(sqlGetNameFromNode($res));
    205 		if (substr($nodeName, 0, 2) == "::") { continue; }
    206 		foreach ($cloud as $c) {
    207 			if ($c['eid'] == $res['eid']) {
    208 				$nbFailed++;
    209 				$rejected = true;
    210 				break;
    211 			}
    212 		}
    213 		if ($rejected) { continue; }
    214 
    215 		// position dans le nuage, difficulté, eid, probaR1, probaR2
    216 		$totalDifficulty += $src['d'];
    217 		$cloud[$i] = array('pos'=>$i++, 'd'=>$src['d'], 'eid'=>$res['eid'], 'probaR1'=>$res['r1'], 'probaR2'=>$res['r2'], 'probaR0'=>$res['r0'], 'probaTrash'=>$res['trash']);
    218 	}
    219 
    220 	$res = $sources['rand']['resultSet'][0];
    221 	
    222 	while ($i < $cloudSize)
    223 	{
    224 		$totalDifficulty += $sources['rand']['d'];
    225 		$cloud[$i] = array('pos'=>$i++, 'd'=>$sources['rand']['d'], 'eid'=>randomCloudNode(), 'probaR1'=>$res['r1'], 'probaR2'=>$res['r2'], 'probaR0'=>$res['r0'], 'probaTrash'=>$res['trash']);
    226 	}
    227 
    228 	return array($cloud, $totalDifficulty);
    229 }
    230 
    231 
    232 /** Insère la partie dans la base de données.
    233 * @param centerEid : Identifiant du mot central.
    234 * @param cloud : Le nuage.
    235 * @param r1 : Le type de la relation 1.
    236 * @param r2 : Le type de la relation 2.
    237 * @param totalDifficulty : La difficulté totale.
    238 */
    239 function cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty)
    240 {
    241 	$db = getDB();
    242 	// Insère dans la base une partie avec le mot central $centerEid, le nuage $cloud et les relations $r1 et $r2
    243 	$db->exec("begin transaction;");
    244 	$db->exec("INSERT INTO game(gid, eid_central_word, relation_1, relation_2, difficulty)
    245 		   VALUES (null, $centerEid, $r1, $r2, $totalDifficulty);");
    246 	$gid = $db->lastInsertRowID();
    247 	
    248 	$t = time();
    249 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
    250 		   VALUES (null, $gid, null, $t);");
    251 	$pgid1 = $db->lastInsertRowID();
    252 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
    253 		   VALUES (null, $gid, null, $t);");
    254 	$pgid2 = $db->lastInsertRowID();
    255 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
    256 		   VALUES (null, $gid, null, $t);");
    257 	$pgid0 = $db->lastInsertRowID();
    258 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
    259 		   VALUES (null, $gid, null, $t);");
    260 	$pgidT = $db->lastInsertRowID();
    261 
    262 	// TODO : R0 et Trash + corrections
    263 	foreach ($cloud as $c)
    264 	{
    265 		$totalWeight = $c['probaR1'] + $c['probaR2'] + $c['probaR0'] + $c['probaTrash'];
    266 		$db->exec("INSERT INTO game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash)
    267 			   VALUES ($gid, ".$c['pos'].", ".$c['d'].", ".$c['eid'].", $totalWeight, ".$c['probaR1'].", ".$c['probaR2'].", ".$c['probaR0'].", ".$c['probaTrash'].");");
    268 		
    269 		$db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
    270 			   VALUES ($pgid1, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
    271 
    272 		$db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
    273 			   VALUES ($pgid2, $gid, 0, ".$c['pos'].", $r2, ".$c['probaR2'].", 0);");
    274 
    275 		$db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
    276 			   VALUES ($pgid0, $gid, 0, ".$c['pos'].", 0, ".$c['probaR0'].", 0);");
    277 
    278 		$db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
    279 			   VALUES ($pgidT, $gid, 0, ".$c['pos'].", -1, ".$c['probaTrash'].", 0);");
    280 	}
    281 
    282 	$db->exec("commit;");
    283 }
    284 
    285 /** Retourne un identifiant de partie aléatoire de la liste de parties jouables
    286 * @return gid : Identifiant de partie.
    287 */
    288 function randomGameCore() {
    289 	$db = getDB();
    290 	return $db->querySingle(sqlGetGidFromGame());
    291 }
    292 
    293 /** Sélection aléatoire d'une partie de la base de données parmis les parties à jouer.
    294 * @return gid : Identifiant de la partie selectionnée.
    295 */
    296 function randomGame()
    297 {
    298 	$gid = randomGameCore();
    299 
    300 	if ($gid === null) {
    301 		// TODO : séparer ces créations de parties dans une fonction qui détecte le mode toussa.
    302 		for ($i = 0; $i < 100; $i++)
    303 			createGameCore(10);
    304 
    305 		$gid = randomGameCore();
    306 
    307 		if ($gid === null)
    308 			errGetGame();
    309 	}
    310 	return $gid;
    311 }
    312 
    313 /** Formatage des mots lorsqu'il y a des généralisations/spécifications par le symbole ">".
    314 * @param word : Le mot que l'on veut reformater.
    315 * @return word : le mot formaté.
    316 */
    317 function formatWord($word) {
    318 	$db = getDB();
    319 	$res = "";
    320 	$stack = array();
    321 
    322 	while (($pos = strpos($word, ">")) !== false) {
    323 		$res .= substr($word,0,$pos) . " (";
    324 		$eid = intval(substr($word,$pos+1));
    325 		if ($eid == 0) { errFollowingPointer($word);  }
    326 		if (in_array($eid, $stack)) { errLoopDetected($word);  }
    327 		if (count($stack) > 10) { errTooMuchRecursion($word);  }
    328 		$stack[] = $eid;
    329 		$word = $db->querySingle(sqlGetNameFromNodeWithEid($eid));
    330 	}
    331 
    332 	$res .= $word;
    333 
    334 	for ($depth = count($stack); $depth > 0; $depth--)
    335 		$res .= ')';
    336 
    337 	return $res;
    338 }
    339 
    340 /** Formate une partie en JSON en l'imprimant.
    341 * @param user : l'utilisateur.
    342 * @param gameId : L'identifiant d'une partie.
    343 */
    344 function game2json($user, $gameId)
    345 {
    346 	$db = getDB();
    347 	// TODO : factoriser avec game2array() .
    348 	// TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
    349 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp) VALUES (null, ".$gameId.", '$user', -1);");
    350 	$pgid = $db->lastInsertRowID();
    351 	
    352 	$game = $db->query(sqlGetGamesForId($gameId));
    353 	$game = $game->fetchArray();
    354 	
    355 	$retstr = "";
    356 	$retstr .= '{"gid":'.$gameId.',"pgid":'.$pgid.',"cat1":'.$game['relation_1'].',"cat2":'.$game['relation_2'].',"cat3":0,"cat4":-1,';
    357 	$retstr .= '"center":{"id":'.$game['eid_central_word'].',"name":'.json_encode(''.formatWord($game['name_central_word'])).'},';
    358 	$retstr .= '"cloudsize":10,"cloud":['; // TODO ! compter dynamiquement.
    359 	
    360 	$res = $db->query(sqlGetWordEidAndName($gameId));
    361 	$notfirst = false;
    362 	
    363 	while ($x = $res->fetchArray())
    364 	{
    365 		if ($notfirst) 
    366 			$retstr .= ",";
    367 		else
    368 			$notfirst=true;
    369 
    370 		$retstr .= '{"id":'.$x['eid_word'].',"name":'.json_encode("".formatWord($x['name_word'])).'}';
    371 	}
    372 
    373 	$retstr .= "]}";
    374 	return $retstr;
    375 }
    376 
    377 /** Récupère une partie sous forme de tableau.
    378 * @param db : descripteur de la bdd (obtenu avec getDB()).
    379 * @param user : Login de l'utilisateur demandant la partie.
    380 * @param gameId : L'identifiant d'une partie.
    381 */
    382 function game2array($user, $gameId)
    383 {
    384 	$db = getDB();
    385 	// TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
    386 	$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp) VALUES (null, ".$gameId.", '$user', -1);");
    387 	$pgid = $db->lastInsertRowID();
    388 	
    389 	// TODO Yoann : faire des tests d'erreur pour ces select ?
    390 	$game = $db->query(sqlGetGamesForId($gameId));
    391 	$game = $game->fetchArray();
    392 
    393 	$ret = array();
    394 	$ret['gid'] = $gameId;
    395 	$ret['pgid'] = $pgid;
    396 	$ret['cat1'] = $game['relation_1'];
    397 	$ret['cat2'] = $game['relation_2'];
    398 	$ret['cat3'] = 0;
    399 	$ret['cat4'] = -1;
    400 	$ret['center'] = array('id' => $game['eid_central_word'], 'name' => formatWord($game['name_central_word']));
    401 	$ret['cloud'] = array(); // TODO ! compter dynamiquement.
    402 	
    403 	$res = $db->query(sqlGetInformationAboutGame($gameId));
    404 	
    405 	while ($x = $res->fetchArray())
    406 	{
    407 		$ret['cloud'][$x['num']] = array(
    408 			'id' => $x['eid_word'],
    409 			'name' => formatWord($x['name_word']),
    410 			'difficulty' => $x['difficulty'],
    411 			'totalWeight' => $x['totalWeight'],
    412 			'probaR1' => $x['probaR1'],
    413 			'probaR2' => $x['probaR2'],
    414 			'probaR0' => $x['probaR0'],
    415 			'probaTrash' => $x['probaTrash'],
    416 			'probas' => normalizeProbas($x)
    417 		);
    418 	}
    419 	
    420 	$ret['cloudsize'] = count($ret['cloud']);
    421 	return $ret;
    422 }
    423 
    424 
    425 /** Création d'un lot de parties suivant un mode donnée.
    426 * @param nbParties : le nombre de parties à créer.
    427 * @param mode : Le mode de jeu pour les parties à créer.
    428 */
    429 function createGame($nbParties, $mode)
    430 {
    431 	for ($i = 0; $i < $nbParties; $i++)
    432 		createGameCore(10);
    433 }
    434 
    435 /** Génère une partie (mode normal pour l'instant) pour une certaine taille de nuage.
    436 * @param cloudSize : Taille du nuage.
    437 *
    438 * Est appelée par randomGame(), donc il faudra adapter quand on aura plusieurs modes, par exemple en ayant une fonction intermédiaire qui puisse être appelée par createGame et randomGame.
    439 */
    440 function createGameCore($cloudSize)
    441 {
    442 	// select random node
    443 	$centerEid = randomCenterNode();
    444 
    445 	$r1 = cgChooseRelations(); $r2 = $r1[1]; $r1 = $r1[0];
    446 	$sources = cgBuildResultSets($cloudSize, $centerEid, $r1, $r2); $sumWeights = $sources[1]; $sources = $sources[0];
    447 	$cloud = cgBuildCloud($centerEid, $cloudSize, $sources, $sumWeights); $totalDifficulty = $cloud[1]; $cloud = $cloud[0];
    448 	cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty);
    449 }
    450 
    451 /** Récupération d'une partie.
    452 * @param user : L'identifiant de l'utilisateur.
    453 * @param nbGames : Le nombre de parties à récupérer.
    454 * @param mode : Le mode de jeu des parties à récupérer.
    455 */
    456 function getGame($user, $nbGames, $mode)
    457 {
    458 	echo "[";
    459 
    460 	for ($i=0; $i < $nbGames; $i)
    461 	{
    462 		echo game2json($user, randomGame());
    463 
    464 		if ((++$i) < $nbGames)
    465 			echo ",";
    466 	}
    467 	
    468 	echo "]";
    469 }
    470 
    471 
    472 function computeScore($probas, $difficulty, $answer, $userReputation) {
    473 	// Calcul du score. Score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2 + bonus
    474 	// score = - proba[autres reponses]*coeff2
    475 	// On aura donc -5 <= score <= 0
    476 	$score = -5 * (($probas[0] + $probas[1] + $probas[2] + $probas[3]) - $probas[$answer]);
    477 	
    478 	// score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2
    479 	// On aura donc -5 <= score <= 10
    480 	$score += 10 * $probas[$answer];
    481 	
    482 	// On est indulgent si la réponse est 3 (poubelle) :
    483 	if ($answer == 3 && $score < 0) {
    484 		$score = $score / 2;
    485 	}
    486 	
    487 	// Adapter le score en fonction de la réputation de l'utilisateur (quand il est jeune, augmenter le score pour le motiver).
    488 	// On aura donc -5 <= score <= 15
    489 	if ($score > 3) {
    490 		$score += max(0, min(5, 5 - $userReputation));
    491 	}
    492 	
    493 	return round($score);
    494 }
    495 
    496 /** Calcul de la réputation de l'utilisateur selon son score.
    497 * @param score : Le score du joueur.
    498 */
    499 function computeUserReputation($score) {
    500 	return max(round(log($score/10)*100)/100, 0);
    501 }
    502 
    503 /** Formatage des probalitées dans un tableau.
    504 * @param row : le vecteur de probabilités.
    505 * @return array : Le vecteur de probabilités normalisé.
    506 */
    507 function normalizeProbas($row) {
    508 	return array($row['probaR1']/$row['totalWeight'], $row['probaR2']/$row['totalWeight'], $row['probaR0']/$row['totalWeight'], $row['probaTrash']/$row['totalWeight']);
    509 }
    510 
    511 /** Insertion des données d'une partie joué par un utilisateur.
    512 * @param user : L'identifiant de l'utilisateur ayant joué à la partie.
    513 * @param pgid : L'identifiant de la partie jouée.
    514 * @param gid : L'identifiant du jeu auquel la partie appartient.
    515 * @return score : Le score réalisé par le joueur.
    516 */
    517 function setGame($user, $pgid, $gid, $answers)
    518 {
    519 	$db = getDB();
    520 	if ('ok' !== $db->querySingle(sqlGameIsOK($pgid, $gid, $user))) {
    521 		return getGameScores($user, $pgid, $gid);
    522 	}
    523 	
    524 	$userReputation = computeUserReputation($db->querySingle(sqlGetScoreForUser($user)));
    525 	
    526 	$db->exec("begin transaction;");
    527 	$db->exec("update played_game set timestamp = ".time()." where pgid = $pgid;");
    528 
    529 	$r0 = 0;
    530 	$trash = -1;
    531 	$r1 = $db->querySingle("SELECT relation_1, relation_2 FROM game WHERE gid = $gid;", true);
    532 	$r2 = $r1['relation_2'];
    533 	$r1 = $r1['relation_1'];
    534 	$res = $db->query("SELECT num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash FROM game_cloud WHERE gid = $gid;");
    535 	$gameScore = 0;
    536 	$scores = array();
    537 	$nbScores = 0;
    538 	
    539 	while ($row = $res->fetchArray())
    540 	{
    541 		$num = intval($row['num']);
    542 		$nbScores++;
    543 		if (!isset($answers[$num])) {
    544 			errSetPartiNoRelation($num);
    545 		}
    546 		$relanswer = intval($answers[$num]);
    547 
    548 		switch ($relanswer) 
    549 		{
    550 			case $r1:    $answer = 0; $probaRx = "probaR1"; break;
    551 			case $r2:    $answer = 1; $probaRx = "probaR2"; break;
    552 			case $r0:    $answer = 2; $probaRx = "probaR0"; break;
    553 			case $trash: $answer = 3; $probaRx = "probaTrash"; break;
    554 			default:     errAnswerInvalidForWord($r1, $r2, $r0, $trash);
    555 		}
    556 			
    557 		$wordScore = computeScore(normalizeProbas($row), $row['difficulty'], $answer, $userReputation);
    558 		$gameScore += $wordScore;
    559 		$scores[$num] = $wordScore;
    560 		
    561 		$db->exec("insert into played_game_cloud(pgid, gid, type, num, relation, weight, score) values($pgid, $gid, 1, $num, $r1, ".$userReputation.", ".$wordScore.");");
    562 		$db->exec("update game_cloud set $probaRx = $probaRx + ".max(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
    563 		$db->exec("update game_cloud set totalWeight = totalWeight + ".max(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
    564 	}
    565 	$db->exec("update user set score = score + ".$gameScore." where login = '$user';");
    566 
    567 	$db->exec("commit;");
    568 	$scores['total'] = $gameScore;
    569 	$scores['nb'] = $nbScores;
    570 	$scores['alreadyPlayed'] = 'false';
    571 	return $scores;
    572 }
    573 
    574 function getGameScores($user, $pgid, $gid) {
    575 	$db = getDB();
    576 	$timestamp = $db->querySingle(sqlGetPlayedGameTime($pgid, $gid, $user));
    577 	if ($timestamp == -1) {
    578 		errGameNeverPlayed();
    579 	} else if ($timestamp == null) {
    580 		errGameNotAssociatedWithUser();
    581 	}
    582 	
    583 	$gameScore = 0;
    584 	$scores = array();
    585 	$nbScores = 0;
    586 	$res = $db->query(sqlGetNumAndScoreFromGame($pgid, $gid));
    587 	while ($row = $res->fetchArray())
    588 	{
    589 		$nbScores++;
    590 		$gameScore += $row['score'];
    591 		$scores[$row['num']] = $row['score'];
    592 	}
    593 	$scores['total'] = $gameScore;
    594 	$scores['nb'] = $nbScores;
    595 	$scores['alreadyPlayed'] = 'true';
    596 	return $scores;
    597 }
    598 
    599 /** Fourni l'ensembles des relations pouvant apparaître dans le jeu.
    600 * @return array : un tableau de realtions.
    601 */
    602 function get_game_relations()
    603 {
    604 		$reqlations = array();
    605 
    606 		$relations[] = 5;
    607 		$relations[] = 7;
    608 		$relations[] = 9;
    609 		$relations[] = 10;
    610 		$relations[] = 14;
    611 		$relations[] = 22;
    612 
    613 		return $relations;
    614 }
    615 
    616 function getGameRelationsJSON() {
    617 	$json = "{";
    618 	global $stringRelations;
    619 	
    620 	foreach($stringRelations as $id=>$description)
    621 		if($id == -1)
    622 			$json .= '"'.$id.'":"'.$description.'"';
    623 		else
    624 			$json .= ',"'.$id.'":"'.$description.'"';
    625 			
    626 	$json .= '}';
    627 	
    628 	return $json;
    629 }
    630 
    631 function setGameGetScore($user, $pgid, $gid, $answers) {
    632 	$scores = setGame($user, intval($pgid), intval($gid), $answers);
    633 	// On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
    634 	echo '{"scoreTotal":'.$scores['total'];
    635 	echo ',"alreadyPlayed":'.$scores['alreadyPlayed'];
    636 	echo ',"scores":[';
    637 	for ($i = 0; $i < $scores['nb']; $i++) {
    638 		if ($i != 0) echo ',';
    639 		echo $scores[$i];
    640 	}
    641 	echo "],\"newGame\":";
    642 	echo json_encode("".game2json($user, randomGame()));
    643 	echo "}";
    644 }
    645 
    646 /** Insère dans la base de données le noeud si il n'existe pas encore.
    647 * @param node : le noeud à ajouter.
    648 */
    649 function insertNode($node) {
    650 	$db = getDB();
    651 	
    652 	if($db->querySingle(sqlGetEidFromNode($node)) == null) {
    653 		$db->exec("INSERT INTO node(name,type,weight) VALUES('".SQLite3::escapeString($node)."',1,50);");
    654 		return true;
    655 	}
    656 
    657 	return false;
    658 }
    659 
    660 
    661 /** retourne l'eid d'un mot.
    662 * @param node : le mot dont on veut obtenir l'eid.
    663 */
    664 
    665 function getNodeEid($node) {
    666 	$db = getDB();
    667 
    668 	return $db->querySingle(sqlGetEidFromNode($node));
    669 }
    670 
    671 function wordExist($node) {
    672 	$db = getDB();
    673 
    674 	return $db->querySingle("SELECT eid FROM node WHERE name='".SQLite3::escapeString($node)."';") ? true : false;
    675 }
    676 ?>