commit 7508266b8262a683fe4f0e5649a42f8bad32419c
parent 5cd02c47d8766f0b10ac6de50b35eaae9c9f2853
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Fri, 4 Mar 2011 23:21:37 +0100
Suite et fin de l'afficheur de parties. Maintenant on peut même jouer pour déboguer.
Diffstat:
6 files changed, 100 insertions(+), 23 deletions(-)
diff --git a/code/serveur/php/.gitignore b/code/serveur/php/.gitignore
@@ -1,3 +1,4 @@
db.old
log.txt
mails.txt
+unstable
diff --git a/code/serveur/php/pticlic.php b/code/serveur/php/pticlic.php
@@ -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.
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'=>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 ]
// 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
// 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();"),
@@ -236,8 +236,9 @@ function cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty)
// 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'].", 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)
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
// score = - proba[autres reponses]*coeff2
$score = -0.7 * (($probas[0] + $probas[1] + $probas[2] + $probas[3]) - $probas[$answer]);
+
// ici, -0.7 <= score <= 0
// score = proba[réponse de l'utilisateur]*coeff1 - proba[autres reponses]*coeff2
$score += ($difficulty/5) * $probas[$answer];
+
// 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).
$score += min(2 - max(0, ($userReputation / 4) - 1), 2);
+
// ici, -0.7 <= score <= 4
return round($score * 100) / 100;
}
function computeUserReputation($score) {
- return ($score > 0) ? log($score) : 0;
+ return max(round(log($score)*100)/100, 0);
}
function normalizeProbas($row) {
@@ -447,7 +451,7 @@ function normalizeProbas($row) {
/** Insertion des données d'une partie.
*/
-function setGame($user, $pgid, $gid, $num, $answers)
+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 = '$user' and timestamp = -1;")) {
@@ -466,6 +470,7 @@ function setGame($user, $pgid, $gid, $num, $answers)
$r1 = $r1['relation_1'];
$res = $db->query("SELECT num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash FROM game_cloud WHERE gid = $gid;");
$gameScore = 0;
+ $scores = array();
while ($row = $res->fetchArray())
{
@@ -481,23 +486,22 @@ function setGame($user, $pgid, $gid, $num, $answers)
case $r2: $answer = 1; $probaRx = "probaR2"; break;
case $r0: $answer = 2; $probaRx = "probaR0"; 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);
$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($userReputation,1)." where gid = $gid;");
- $db->exec("update game_cloud set totalWeight = totalWeight + ".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(min($userReputation/2,5),0)." where gid = $gid and num = $num;");
}
$db->exec("update user set score = score + ".$gameScore." where login = '$user';");
$db->exec("commit;");
- // On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
- echo "{\"score\":".$gameScore.",\"newGame\":";
- game2json($user, randomGame());
- echo "}";
+ $scores['total'] = $gameScore;
+ return $scores;
}
?>
\ No newline at end of file
diff --git a/code/serveur/php/ressources/backend.css b/code/serveur/php/ressources/backend.css
@@ -1,5 +1,10 @@
.show-game {
border-collapse: collapse;
+ margin-left: 4em;
+}
+
+form * {
+ margin-left: 0 !important;
}
.show-game td,
@@ -11,4 +16,4 @@
.show-game caption {
text-align: left;
-}
-\ No newline at end of file
+}
diff --git a/code/serveur/php/server.php b/code/serveur/php/server.php
@@ -68,7 +68,13 @@ function main()
if (!isset($_GET['pgid']) || !isset($_GET['gid'])) {
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 {
throw new Exception("Commande inconnue", 2);
}
diff --git a/code/serveur/php/showGame.php b/code/serveur/php/showGame.php
@@ -16,12 +16,28 @@
<?php
require_once("pticlic.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>
- <?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>
+ 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>
@@ -31,12 +47,18 @@
<table class="show-game">
<thead>
<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 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>
@@ -72,24 +94,59 @@
<?php
$columns = array(0 => 'probaR1', 1 => 'probaR2', 2 => 'probaR0', 3 => 'probaTrash');
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:#'
- . 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, 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, 1.3*255*$v['probas'][$answer]))), 2, "0", STR_PAD_LEFT)
. '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(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>
diff --git a/organisation/notes b/organisation/notes
@@ -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, ...).
- 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