Suite et fin de l'afficheur de parties. Maintenant on peut même jouer pour déboguer.

This commit is contained in:
Georges Dupéron 2011-03-04 23:21:37 +01:00
parent 5cd02c47d8
commit 7508266b82
6 changed files with 100 additions and 22 deletions

View File

@ -1,3 +1,4 @@
db.old db.old
log.txt log.txt
mails.txt mails.txt
unstable

View File

@ -46,10 +46,10 @@ function cgBuildResultSets($cloudSize, $centerEid, $r1, $r2)
// Voisins 1 saut via r_associated (0), donc qu'on voudrait spécifier si possible. // Voisins 1 saut via r_associated (0), donc qu'on voudrait spécifier si possible.
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();"), 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 // Voisins 1 saut via les autres relations
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, 4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) order by random();"), array('w'=>20, 'd'=>3.1, '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, 4, 12, 36, 18, 29, 45, 46, 47, 48, 1000, 1001) 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 ] // 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();" // Version optimisée de : "select end as eid from relation where $typer1r2 and start in oneHopWithType 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();"), array('w'=>30, 'd'=>3.2, '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 // 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()"; // Version optimisée de : "select end as eid from relation where start in oneHopWithType and 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();"), 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();"),
@ -236,8 +236,9 @@ function cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty)
// TODO : R0 et Trash + corrections // TODO : R0 et Trash + corrections
foreach ($cloud as $c) 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) $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'].");"); 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) $db->exec("INSERT INTO played_game_cloud(pgid, gid, type, num, relation, weight, score)
VALUES ($pgid1, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);"); VALUES ($pgid1, $gid, 0, ".$c['pos'].", $r1, ".$c['probaR1'].", 0);");
@ -427,18 +428,21 @@ function computeScore($probas, $difficulty, $answer, $userReputation) {
// Calcul du score. Score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2 // Calcul du score. Score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2
// score = - proba[autres reponses]*coeff2 // score = - proba[autres reponses]*coeff2
$score = -0.7 * (($probas[0] + $probas[1] + $probas[2] + $probas[3]) - $probas[$answer]); $score = -0.7 * (($probas[0] + $probas[1] + $probas[2] + $probas[3]) - $probas[$answer]);
// ici, -0.7 <= score <= 0 // ici, -0.7 <= score <= 0
// score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2 // score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2
$score += ($difficulty/5) * $probas[$answer]; $score += ($difficulty/5) * $probas[$answer];
// ici, -0.7 <= score <= 2 // ici, -0.7 <= score <= 2
// Adapter le score en fonction de la réputation de l'utilisateur (quand il est jeune, augmenter le score pour le motiver). // Adapter le score en fonction de la réputation de l'utilisateur (quand il est jeune, augmenter le score pour le motiver).
$score += min(2 - max(0, ($userReputation / 4) - 1), 2); $score += min(2 - max(0, ($userReputation / 4) - 1), 2);
// ici, -0.7 <= score <= 4 // ici, -0.7 <= score <= 4
return round($score * 100) / 100; return round($score * 100) / 100;
} }
function computeUserReputation($score) { function computeUserReputation($score) {
return ($score > 0) ? log($score) : 0; return max(round(log($score)*100)/100, 0);
} }
function normalizeProbas($row) { function normalizeProbas($row) {
@ -447,7 +451,7 @@ function normalizeProbas($row) {
/** Insertion des données d'une partie. /** Insertion des données d'une partie.
*/ */
function setGame($user, $pgid, $gid, $num, $answers) function setGame($user, $pgid, $gid, $answers)
{ {
$db = getDB(); $db = getDB();
if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = $pgid and $gid = $gid and login = '$user' and timestamp = -1;")) { if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = $pgid and $gid = $gid and login = '$user' and timestamp = -1;")) {
@ -466,6 +470,7 @@ function setGame($user, $pgid, $gid, $num, $answers)
$r1 = $r1['relation_1']; $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 = $gid;");
$gameScore = 0; $gameScore = 0;
$scores = array();
while ($row = $res->fetchArray()) while ($row = $res->fetchArray())
{ {
@ -481,23 +486,22 @@ function setGame($user, $pgid, $gid, $num, $answers)
case $r2: $answer = 1; $probaRx = "probaR2"; break; case $r2: $answer = 1; $probaRx = "probaR2"; break;
case $r0: $answer = 2; $probaRx = "probaR0"; break; case $r0: $answer = 2; $probaRx = "probaR0"; break;
case $trash: $answer = 3; $probaRx = "probaTrash"; break; case $trash: $answer = 3; $probaRx = "probaTrash"; break;
default: throw new Exception("Réponse invalide pour le mot $num.", 5); default: throw new Exception("Réponse ($relanswer) invalide pour le mot $num. Les réponses possibles sont : $r1, $r2, $r0, $trash", 5);
} }
$wordScore = computeScore(normalizeProbas($row), $row['difficulty'], $answer, $userReputation); $wordScore = computeScore(normalizeProbas($row), $row['difficulty'], $answer, $userReputation);
$gameScore += $wordScore; $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("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($userReputation,1)." where gid = $gid;"); $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($userReputation,1)." where gid = $gid;"); $db->exec("update game_cloud set totalWeight = totalWeight + ".max(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
} }
$db->exec("update user set score = score + ".$gameScore." where login = '$user';"); $db->exec("update user set score = score + ".$gameScore." where login = '$user';");
$db->exec("commit;"); $db->exec("commit;");
// On renvoie une nouvelle partie pour garder le client toujours bien alimenté. $scores['total'] = $gameScore;
echo "{\"score\":".$gameScore.",\"newGame\":"; return $scores;
game2json($user, randomGame());
echo "}";
} }
?> ?>

View File

@ -1,5 +1,10 @@
.show-game { .show-game {
border-collapse: collapse; border-collapse: collapse;
margin-left: 4em;
}
form * {
margin-left: 0 !important;
} }
.show-game td, .show-game td,

View File

@ -68,7 +68,13 @@ function main()
if (!isset($_GET['pgid']) || !isset($_GET['gid'])) { if (!isset($_GET['pgid']) || !isset($_GET['gid'])) {
throw new Exception("La requête est incomplète", 2); throw new Exception("La requête est incomplète", 2);
} }
setGame($user, intval($_GET['pgid']), intval($_GET['gid']), $_GET); // TODO : il faudrait filtrer les paramètres qui correspondent à une réponse au lieu d'envoyer $_GET en entier, mais on ne connaît pas leur nom à l'avance. // TODO : il faudrait filtrer les paramètres qui correspondent à une réponse
// au lieu d'envoyer $_GET en entier, mais on ne connaît pas leur nom à l'avance.
$scores = setGame($user, intval($_GET['pgid']), intval($_GET['gid']), $_GET);
// On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
echo "{\"score\":".$scores['total'].",\"newGame\":";
game2json($user, randomGame());
echo "}";
} else { } else {
throw new Exception("Commande inconnue", 2); throw new Exception("Commande inconnue", 2);
} }

View File

@ -16,12 +16,28 @@
<?php <?php
require_once("pticlic.php"); require_once("pticlic.php");
require_once("relations.php"); require_once("relations.php");
$game = game2array("foo", (isset($_GET['gid']) ? $_GET['gid'] : randomGame())); $gameId = randomGame();
if (isset($_GET['gid'])) $gameId = intval($_GET['gid']);
if (isset($_POST['gid'])) $gameId = intval($_POST['gid']);
$game = game2array("foo", $gameId);
?> ?>
<h3><?php echo $game['center']['name'] . " (eid = " . $game['center']['id'] . ")"; ?></h3> <h3>Informations internes sur le nuage</h3>
<p> <p>
<?php $scoreAvantPartie = 10; ?>Score de l'utilisateur avant la partie : <?php echo $scoreAvantPartie; ?>. 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>
<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> <ul>
<li>Poids désigne le poids pour cette relation entre le mot central et le mot en cours (pour cette partie).</li> <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>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>
@ -31,12 +47,18 @@
<table class="show-game"> <table class="show-game">
<thead> <thead>
<tr> <tr>
<th colspan="3">Mot</th> <th colspan="3" style="color: darkgreen;"><?php echo $game['center']['name'] . " (eid = " . $game['center']['id'] . ")"; ?></th>
<th rowspan="2">PoidsTotal</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['cat1']] . " (rid = " . $game['cat1'] . ")"; ?></th>
<th colspan="6"><?php echo $stringRelations[$game['cat2']] . " (rid = " . $game['cat2'] . ")"; ?></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['cat3']] . " (rid = " . $game['cat3'] . ")"; ?></th>
<th colspan="6"><?php echo $stringRelations[$game['cat4']] . " (rid = " . $game['cat4'] . ")"; ?></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>
<tr> <tr>
<th>Num.</th> <th>Num.</th>
@ -72,24 +94,59 @@
<?php <?php
$columns = array(0 => 'probaR1', 1 => 'probaR2', 2 => 'probaR0', 3 => 'probaTrash'); $columns = array(0 => 'probaR1', 1 => 'probaR2', 2 => 'probaR0', 3 => 'probaTrash');
foreach ($columns as $answer => $probaRX) { foreach ($columns as $answer => $probaRX) {
echo "<td>" . $v[$probaRX] . "</td>"; 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:#' echo '<td style="color:#'
. str_pad(dechex(max(0,min(255,0xff - 2*255*$v['probas'][$answer]))), 2, "0", STR_PAD_LEFT) . 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, 2*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;">' . '00;">'
. $v['probas'][$answer] . "</td>"; . (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(0))."</td>";
echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(10))."</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(100))."</td>";
echo "<td>" . computeScore($v['probas'], $v['difficulty'], $answer, computeUserReputation(1000))."</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> </tr>
<?php <?php
} }
?> ?>
</tbody> </tbody>
</table> </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> </div>
<?php include("ressources/footer.inc"); ?> <?php include("ressources/footer.inc"); ?>
</body> </body>

View File

@ -1,3 +1,8 @@
BUG : dans les parties qu'on génère, la somme des poids doit toujours être 2, or il y en a certaines où c'est 0 !?!
- Une classe Constante pour toutes les constantes ("symboles" pour les paramètres, ...). - Une classe Constante pour toutes les constantes ("symboles" pour les paramètres, ...).
- Boutons pour les différents modes de jeu directement sur la "page de garde". - Boutons pour les différents modes de jeu directement sur la "page de garde".
- Icônes : http://developer.android.com/guide/practices/ui_guidelines/icon_design.html - Icônes : http://developer.android.com/guide/practices/ui_guidelines/icon_design.html