Intégration de la page de scores.

This commit is contained in:
Georges Dupéron 2011-04-24 15:05:10 +02:00
parent 12dda39f49
commit c6f25c0a9c
8 changed files with 147 additions and 176 deletions

View File

@ -1,31 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>PtiClic pre-alpha 0.2</title>
<meta charset="utf-8" />
<style>
body {
background-color: black;
}
#screen {
background-color : #FFFFE0;
}
</style>
<script src="jquery-1.5.1.min.js"></script>
<script src="jquery-ui-1.8.11.custom.min.js"></script>
<script src="score.js"></script>
<script src="my-extensions.js"></script>
</head>
<body>
<div id="screen">
<h1>Score total : <span class="scoreTotal"></span></h1>
<div class="scores"></div>
<div id="templates" style="display: none;">
<div class="scoreLine">
<span class="word"></span> (<span class="score"></span>)
</div>
</div>
</div>
</body>
</html>

View File

@ -1,41 +0,0 @@
function jss() {
var w, h;
w = $(window).width();
h = $(window).height();
var mch = h/8, mnh = h*0.075;
$("body, html")
.css({
padding: 0,
margin: 0,
overflow: "hidden",
textAlign: "left"
});
$("#screen")
.wh(w, h)
.north($("body").north()); // TODO : par rapport à la fenêtre entière.
}
$(function () {
var url = "score.json";
$.getJSON(url, function(data) {
console.log(data);
$.each(data.scores, function(i,e) {
var percentScore = (e.score - data.minScore) / (data.maxScore - data.minScore);
$("#templates .scoreLine")
.clone()
.find(".word").text(e.name).end()
.find(".score")
.text(e.score)
.css("color","rgb("+(255 - 255*percentScore).clip(0,255)+","+(191*percentScore).clip(0,255,true)+",0)")
.end()
.appendTo(".scores");
jss();
});
}).error(function(x){
alert("Erreur fatale. Merci de nous envoyer ce message :\n"+x.status+"\n"+x.statusText+"\n"+x.responseText.substring(0,20)+"…");
});
jss();
});

View File

@ -1 +0,0 @@
{"minScore":-5,"maxScore":10,"scores":[{"id":84632,"name":"camion","score":3},{"id":61939,"name":"transbahutage","score":10},{"id":104263,"name":"trimbaler","score":4},{"id":44654,"name":"transporter","score":-2},{"id":38285,"name":"d\u00e9m\u00e9nageur","score":5},{"id":43404,"name":"porter","score":5},{"id":63192,"name":"transports","score":-1},{"id":130473,"name":"enthousiasmer","score":0},{"id":90461,"name":"se trimbaler","score":6},{"id":134609,"name":"baguenauder","score":9}]}

View File

@ -1 +0,0 @@
[{"gid":22,"pgid":512,"relations":[{"id":10,"name":"%mc fait partie de %mn"},{"id":9,"name":"%mn est une partie de %mc"},{"id":0,"name":"%mc est en rapport avec %mn"},{"id":-1,"name":"%mn n'est pas lié à %mc"}],"center":{"id":28282,"name":"transbahuter"},"cloudsize":10,"cloud":[{"id":84632,"name":"camion"},{"id":61939,"name":"transbahutage"},{"id":104263,"name":"trimbaler"},{"id":44654,"name":"transporter"},{"id":38285,"name":"d\u00e9m\u00e9nageur"},{"id":43404,"name":"porter"},{"id":63192,"name":"transports"},{"id":130473,"name":"enthousiasmer"},{"id":90461,"name":"se trimbaler"},{"id":134609,"name":"baguenauder"}]}]

View File

@ -56,12 +56,6 @@ body {
<div id="mc-caption" class="mc"></div>
<div id="mn-caption" class="mn"></div>
<div class="relations"></div>
<div id="templates" style="display: none;">
<div class="relationBox">
<div class="relation"><img class="icon" alt="" src="ressources/img/rel/default.png" /><span class="text"></span></div>
<div class="clearboth"></div>
</div>
</div>
</div>
<div class="screen" id="frontpage">
<div id="title-block"></div>
@ -96,5 +90,18 @@ body {
<span class="text">A Propos</span>
</div>
</div>
<div class="screen" id="score">
<h1>Score total : <span class="scoreTotal"></span></h1>
<div class="scores"></div>
</div>
<div id="templates" style="display: none;">
<div class="relationBox">
<div class="relation"><img class="icon" alt="" src="ressources/img/rel/default.png" /><span class="text"></span></div>
<div class="clearboth"></div>
</div>
<div class="scoreLine">
<span class="word"></span> (<span class="score"></span>)
</div>
</div>
</body>
</html>

View File

@ -572,7 +572,7 @@ function computeScore($probas, $difficulty, $answer, $userReputation) {
* @param score : Le score du joueur.
*/
function computeUserReputation($score) {
return max(round(log($score/10)*100)/100, 0);
return max(round(log(max($score/10,1))*100)/100, 0);
}
/** Formatage des probalitées dans un tableau.
@ -596,7 +596,7 @@ function setGame($user, $pgid, $gid, $answers)
return getGameScores($user, $pgid, $gid);
}
$userReputation = computeUserReputation($db->querySingle("SELECT score FROM user WHERE login='".$user."';"));
$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;");
@ -609,12 +609,10 @@ function setGame($user, $pgid, $gid, $answers)
$res = $db->query("SELECT num, difficulty, totalWeight, probaR1, probaR2, probaR0, probaTrash FROM game_cloud WHERE gid = $gid;");
$gameScore = 0;
$scores = array();
$nbScores = 0;
while ($row = $res->fetchArray())
{
$num = intval($row['num']);
$nbScores++;
if (!isset($answers[$num])) {
throw new Exception("Cette requête \"Set partie\" ne donne pas de réponse (une relation) pour le mot numéro $num de la partie.", 5);
}
@ -640,10 +638,12 @@ function setGame($user, $pgid, $gid, $answers)
$db->exec("update user set score = score + ".$gameScore." where login = '$user';");
$db->exec("commit;");
$scores['total'] = $gameScore;
$scores['nb'] = $nbScores;
$scores['alreadyPlayed'] = 'false';
return $scores;
return array(
'scoreTotal' => $gameScore,
'alreadyPlayed' => false,
'scores' => $scores
);
}
function getGameScores($user, $pgid, $gid) {
@ -657,18 +657,17 @@ function getGameScores($user, $pgid, $gid) {
$gameScore = 0;
$scores = array();
$nbScores = 0;
$res = $db->query("SELECT num,score from played_game_cloud where pgid = $pgid and gid = $gid;");
while ($row = $res->fetchArray())
{
$nbScores++;
$gameScore += $row['score'];
$scores[$row['num']] = $row['score'];
}
$scores['total'] = $gameScore;
$scores['nb'] = $nbScores;
$scores['alreadyPlayed'] = 'true';
return $scores;
return array(
'scoreTotal' => $gameScore,
'alreadyPlayed' => true,
'scores' => $scores
);
}
/** Fourni l'ensembles des relations pouvant apparaître dans le jeu.
@ -706,16 +705,10 @@ function getGameRelationsJSON() {
function setGameGetScore($user, $pgid, $gid, $answers) {
$scores = setGame($user, intval($pgid), intval($gid), $answers);
// On renvoie une nouvelle partie pour garder le client toujours bien alimenté.
echo '{"scoreTotal":'.$scores['total'];
echo ',"alreadyPlayed":'.$scores['alreadyPlayed'];
echo ',"scores":[';
for ($i = 0; $i < $scores['nb']; $i++) {
if ($i != 0) echo ',';
echo $scores[$i];
}
echo "],\"newGame\":";
echo json_encode("".game2json($user, randomGame()));
echo "}";
$scores['newGame'] = game2json($user, randomGame());
$scores['minScore'] = -5;
$scores['maxScore'] = 10;
echo json_encode($scores);
}
/** Insère dans la base de données le noeud si il n'existe pas encore.

View File

@ -1,4 +1,4 @@
var state = "frontpage"
var state = "frontpage";
// ==== JavaScript Style général
function jss() {
@ -22,7 +22,7 @@ function jss() {
$("#"+state).show();
jss[state](w, h, iconSize);
};
}
// ==== JavaScript Style pour la frontpage
jss.frontpage = function(w, h, iconSize) {
@ -47,7 +47,7 @@ jss.frontpage = function(w, h, iconSize) {
.southEast({left:w*0.45,top:h*0.9});
$fp(".frontpage-button.prefs")
.southWest({left:w*0.55,top:h*0.9});
}
};
// ==== JavaScript Style pour le jeu
jss.game = function(w, h, iconSize) {
@ -93,7 +93,10 @@ jss.game = function(w, h, iconSize) {
$g(".relations")
.south(g.south());
}
};
jss.score = function(w, h, iconSize) {
};
// ==== Code métier général
$(function() {
@ -102,85 +105,129 @@ $(function() {
frontpage();
});
function ajaxError(x) {
alert("Erreur fatale. Merci de nous envoyer ce message : "+x.status+" - "+x.statusText+"\n"+x.responseText.substring(0,20)+((x.responseText == '') ? '': '…'));
}
// ==== Code métier pour la frontpage
function frontpage() {
state="frontpage";
$(".frontpage-button.game").click(function(){
game();
$("#frontpage .frontpage-button.game").click(function(){
getGame();
});
}
// ==== Code métier pour le jeu
function game() {
function getGame() {
state="game";
$.getJSON("getGame.php?callback=?", {
user:"foo",
passwd:"bar",
}, function(game) {
var currentWordNb = 0;
var answers = [];
var updateText = function() {
$(".mn").text(game.cloud[currentWordNb].name);
$(".mc").text(game.center.name);
jss();
}
var nextWord = function(click, button) {
answers[currentWordNb++] = $(button).data("rid");
if (currentWordNb < game.cloud.length) {
animateNext(click, button);
} else {
$(".relations").empty();
$('#mn-caption').stop().clearQueue();
alert("Partie terminée !");
}
}
function animateNext(click, button) {
var duration = 700;
var mn = $("#mn-caption");
$(button).addClass("hot").removeClass("hot", duration);
(mn)
.stop() // Attention : stop() et clearQueue() ont aussi un effet
.clearQueue() // sur la 2e utilisation de mn (ci-dessous).
.clone()
.removeClass("mn") // Pour que le texte animé ne soit pas modifié.
.appendTo("body") // Append to body so we can animate the offset (instead of top/left).
.offset(mn.offset())
.animate({left:click.left, top:click.top, fontSize: 0}, duration)
.queue(function() { $(this).remove(); });
}, uiGame).error(ajaxError);
jss();
}
updateText();
var fs = mn.css("fontSize");
var mncbCenter = $("#mn-caption-block").center();
(mn)
.css("fontSize", 0)
.animate({fontSize: fs}, {duration:duration, step:function(){mn.center(mncbCenter);}});
function uiGame(game) {
var currentWordNb = 0;
game.answers = [];
var updateText = function() {
$("#game .mn").text(game.cloud[currentWordNb].name);
$("#game .mc").text(game.center.name);
jss();
}
var nextWord = function(click, button) {
game.answers[currentWordNb++] = $(button).data("rid");
if (currentWordNb < game.cloud.length) {
animateNext(click, button);
} else {
$("#game .relations").empty();
$('#game #mn-caption').stop().clearQueue();
getScore(game);
}
}
function animateNext(click, button) {
var duration = 700;
$.each(game.relations, function(i, relation) {
$('#templates .relationBox')
.clone()
.data("rid", relation.id)
.find(".text")
.html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>'))
.end()
.find(".icon")
.attr("src", "ressources/img/rel/"+relation.id+".png")
.end()
.click(function(e) {
nextWord({left:e.pageX, top:e.pageY}, this);
})
.appendTo(".relations");
});
var mn = $("#game #mn-caption");
$(button).addClass("hot").removeClass("hot", duration);
(mn)
.stop() // Attention : stop() et clearQueue() ont aussi un effet
.clearQueue() // sur la 2e utilisation de mn (ci-dessous).
.clone()
.removeClass("mn") // Pour que le texte animé ne soit pas modifié.
.appendTo("body") // Append to body so we can animate the offset (instead of top/left).
.offset(mn.offset())
.animate({left:click.left, top:click.top, fontSize: 0}, duration)
.queue(function() { $(this).remove(); });
updateText();
}).error(function(x){
alert("Erreur fatale. Merci de nous envoyer ce message : "+x.status+" - "+x.statusText+"\n"+x.responseText.substring(0,20)+((x.responseText == '') ? '': '…'));
var fs = mn.css("fontSize");
var mncbCenter = $("#game #mn-caption-block").center();
(mn)
.css("fontSize", 0)
.animate({fontSize: fs}, {duration:duration, step:function(){mn.center(mncbCenter);}});
}
$.each(game.relations, function(i, relation) {
$('#templates .relationBox')
.clone()
.data("rid", relation.id)
.find(".text")
.html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>'))
.end()
.find(".icon")
.attr("src", "ressources/img/rel/"+relation.id+".png")
.end()
.click(function(e) {
nextWord({left:e.pageX, top:e.pageY}, this);
})
.appendTo("#game .relations");
});
updateText();
}
// ==== Code métier pour les scores
function getScore(game) {
state="score";
$.getJSON("server.php?callback=?", {
user: "foo",
passwd: "bar",
action: 1,
pgid: game.pgid,
gid: game.gid,
answers: game.answers
}, function(data) {
for (var i = 0; i < data.scores.length; i++) {
game.cloud[i].score = data.scores[i];
}
delete data.score;
uiScore($.extend(game, data));
}).error(ajaxError);
jss();
}
function uiScore(game) {
$.each(game.cloud, function(i,e) {
var percentScore = (e.score - game.minScore) / (game.maxScore - game.minScore);
u = $("#templates .scoreLine");
ee = e;
$("#templates .scoreLine")
.clone()
.find(".word")
.text(e.name)
.end()
.find(".score")
.text(e.score)
.css("color","rgb("+(255 - 255*percentScore).clip(0,255)+","+(191*percentScore).clip(0,255,true)+",0)")
.end()
.appendTo("#score .scores");
jss();
});
}

View File

@ -64,12 +64,10 @@ function main()
}
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
if (!isset($_GET['pgid']) || !isset($_GET['gid'])) {
if (!isset($_GET['pgid']) || !isset($_GET['gid']) || !isset($_GET['answers'])) {
throw new Exception("La requête est incomplète", 2);
}
// 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.
setGameGetScore($user, $_GET['pgid'], $_GET['gid'], $_GET);
setGameGetScore($user, $_GET['pgid'], $_GET['gid'], $_GET['answers']);
} else if($action == 4) { // CheckWord
if (!isset($_GET['word']))
errRequestIncomplete();