master #1

Merged
antux18 merged 9 commits from Antux/JeuPistesSarreguemines:master into jeu-pistes-sarreguemines 2024-09-01 15:37:45 +02:00
13 changed files with 95 additions and 72 deletions

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
localhost-key.pem localhost-key.pem
localhost.pem localhost.pem
data/teams.db
data/article.db

View File

@ -1,7 +1,7 @@
# Chasse au trésor Lycée Pange # Jeu de pistes Sarreguemines
**Auteur :** Antoine WAEHREN **Auteur :** Antoine WAEHREN
## Crédits ## Crédits
Ce projet utilise le module QR Scanner de NIMIQ : https://github.com/nimiq/qr-scanner Ce projet utilise le module QR Scanner de NIMIQ : https://github.com/nimiq/qr-scanner

View File

@ -56,17 +56,6 @@
$stmt->bindValue(":puzzle_id", $art_id); $stmt->bindValue(":puzzle_id", $art_id);
$stmt->bindValue(":team_id", $team_id); $stmt->bindValue(":team_id", $team_id);
$stmt->execute(); $stmt->execute();
// On ajoute l'énigme bonus si toutes les autres sont résolues :
$stmt = $database->pdo_teams->prepare("SELECT COUNT(*) FROM solved WHERE team_id == :team_id");
$stmt->bindValue(":team_id", $team_id);
$stmt->execute();
if ($stmt->fetchAll()[0]["COUNT(*)"] == "12") { // Il y a 12 énigmes sans compter la bonus
$stmt = $database->pdo_teams->prepare("UPDATE teams SET bonus = 1 WHERE id = :team_id");
$stmt->bindValue(":team_id", $team_id);
$stmt->execute();
}
} }
$data["valid_qr"] = true; $data["valid_qr"] = true;

View File

@ -5,6 +5,7 @@
$solved = false; $solved = false;
$team_id = -1; $team_id = -1;
$art_id = -1; $art_id = -1;
$art_index = -1; // Index de l'article dans la liste pzorder assignée à l'équipe
$database = new Database(); $database = new Database();
@ -27,18 +28,30 @@
} }
else { else {
// On vérifie si l'énigme bonus n'est pas débloquée : // On cherche l'index de l'article dans la liste pzorder assignée à l'équipe :
if (!$database->checkTeamBonus($team_id)) { $stmt = $database->pdo_teams->prepare("SELECT pzorder FROM teams WHERE id == :id");
// Si c'est celle qui est sélectionnée, on retourne à la liste des énigmes : $stmt->bindValue(":id", $team_id);
if ($art_id == $max_art) { $stmt->execute();
header("Location: puzzles.php?team=" . $team_id); $result = $stmt->fetch();
die(); $order = $result["pzorder"];
}
// On retire l'énigme bonus du total : // Si un ordre d'énigmes n'a pas été défini au préalable pour cette équipe, on en choisit un au hasard :
$max_art--; if (is_null($order)) {
$order = rand(0, sizeof($pzorder));
$stmt = $database->pdo_teams->prepare("UPDATE teams SET pzorder = :order WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->bindValue(":order", $order);
$stmt->execute();
} }
$pzo_arr = $pzorder[$order];
$art_index = array_search($art_id, $pzo_arr);
$prev_art = $pzo_arr[$art_index - 1];
if ($art_index == 0) {
$prev_art = $pzo_arr[$max_art - 1];
}
$next_art = $pzo_arr[($art_index + 1) % $max_art];
// On indique si l'énigme est résolue : // On indique si l'énigme est résolue :
$stmt = $database->pdo_teams->prepare("SELECT * FROM solved WHERE (team_id == :team_id AND puzzle_id == :puzzle_id)"); $stmt = $database->pdo_teams->prepare("SELECT * FROM solved WHERE (team_id == :team_id AND puzzle_id == :puzzle_id)");
$stmt->bindValue(":team_id", $team_id); $stmt->bindValue(":team_id", $team_id);
@ -71,15 +84,18 @@
</header> </header>
<main> <main>
<header> <header>
<h1><?= $tr["page_title"]["article"] . $art_id . " : " . $article["title"] ?></h1> <h1><?= $tr["page_title"]["article"] . $art_id ?></h1>
<h2><?= $article["text"] ?></h2> <h2><?= $article["text"] ?></h2>
<section> <section>
<a href="article.php?team=<?= $team_id ?>&id=<?= $prev_art ?>">
<button><?= $tr["article"]["prev_but"] ?></button>
</a>
<a href="puzzles.php?team=<?= $team_id ?>"> <a href="puzzles.php?team=<?= $team_id ?>">
<button><?= $tr["article"]["back_but"] ?></button> <button><?= $tr["article"]["back_but"] ?></button>
</a> </a>
<!-- <a href="article.php?team=<?= $team_id ?>&id=<?= ($art_id % $max_art) + 1 ?>"> <a href="article.php?team=<?= $team_id ?>&id=<?= $next_art ?>">
<button><?= $tr["article"]["next_but"] ?></button> <button><?= $tr["article"]["next_but"] ?></button>
</a> --> </a>
</section> </section>
<?php if ($solved) : ?> <?php if ($solved) : ?>
<p><?= $tr["article"]["success"] ?></p> <p><?= $tr["article"]["success"] ?></p>
@ -90,7 +106,7 @@
<article> <article>
<?php if ($solved) : ?> <?php if ($solved) : ?>
<p><?= $article["answer"] ?></p> <p><?= $article["answer"] ?></p>
<img src="images/map/puzzles/<?= $article["id"] ?>.png"/> <h1><?= $article["reward"] ?></h1>
<?php else : ?> <?php else : ?>
<button><?= $tr["article"]["qr_but"] ?></button> <button><?= $tr["article"]["qr_but"] ?></button>
<p></p> <!-- Emplacement du message d'erreur JS concernant la caméra. !--> <p></p> <!-- Emplacement du message d'erreur JS concernant la caméra. !-->

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,7 @@
require_once "require/base.php"; require_once "require/base.php";
$puzzles = array(); $puzzles = array();
$order = 0;
$team_id = -1; $team_id = -1;
$database = new Database(); $database = new Database();
@ -31,23 +32,26 @@
false false
); );
// On vérifie si l'équipe a débloqué l'énigme bonus : $stmt = $database->pdo_article->prepare("SELECT * FROM puzzles");
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams WHERE id = :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
// Si c'est le cas, on affiche toutes les énigmes :
if ($stmt->fetchAll()[0][1] == 1) {
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles");
}
// Sinon, on cache la bonus :
else {
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles WHERE id <> 13");
}
$stmt->execute(); $stmt->execute();
$puzzles = $stmt->fetchAll(); $puzzles = $stmt->fetchAll();
// Recherche de l'ordre des énigmes :
$stmt = $database->pdo_teams->prepare("SELECT pzorder FROM teams WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
$result = $stmt->fetch();
$order = $result["pzorder"];
// Si un ordre d'énigmes n'a pas été défini au préalable pour cette équipe, on en choisit un au hasard :
if (is_null($order)) {
$order = rand(0, sizeof($pzorder));
$stmt = $database->pdo_teams->prepare("UPDATE teams SET pzorder = :order WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->bindValue(":order", $order);
$stmt->execute();
}
} }
} }
@ -78,8 +82,12 @@
<article> <article>
<p><?= $tr["puzzles"]["message"]?></p> <p><?= $tr["puzzles"]["message"]?></p>
<ul> <ul>
<?php foreach ($puzzles as $puzzle) : ?> <?php foreach ($pzorder[$order] as $pzid) : ?>
<li><a href="article.php?team=<?= $team_id ?>&id=<?= $puzzle["id"] ?>"><?= $tr["page_title"]["article"] . $puzzle["id"] . " : " . $puzzle["title"] ?></a></li> <?php foreach ($puzzles as $puzzle) : ?>
<?php if ($puzzle["id"] == $pzid) : ?>
<li><a href="article.php?team=<?= $team_id ?>&id=<?= $puzzle["id"] ?>"><?= $tr["page_title"]["article"] . $puzzle["id"] ?></a></li>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
</article> </article>

View File

@ -1,5 +1,6 @@
<?php <?php
require_once "database.php"; require_once "database.php";
require_once "puzzles_order.php";
$rq_path = "require/"; $rq_path = "require/";

View File

@ -17,6 +17,7 @@
"answer" TEXT NOT NULL, "answer" TEXT NOT NULL,
"location" TEXT NOT NULL, "location" TEXT NOT NULL,
"code" TEXT NOT NULL, "code" TEXT NOT NULL,
"reward" TEXT NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT) PRIMARY KEY("id" AUTOINCREMENT)
)'); )');
@ -24,7 +25,7 @@
$this->pdo_teams = new PDO("sqlite:" . dirname(__FILE__) . $data_path . "teams.db"); $this->pdo_teams = new PDO("sqlite:" . dirname(__FILE__) . $data_path . "teams.db");
$this->pdo_teams->query('CREATE TABLE IF NOT EXISTS "teams" ( $this->pdo_teams->query('CREATE TABLE IF NOT EXISTS "teams" (
"id" INTEGER NOT NULL UNIQUE, "id" INTEGER NOT NULL UNIQUE,
"bonus" INTEGER NOT NULL, "pzorder" INTEGER,
PRIMARY KEY("id" AUTOINCREMENT) PRIMARY KEY("id" AUTOINCREMENT)
)'); )');
@ -57,12 +58,6 @@
return $query->fetch()["COUNT(*)"]; return $query->fetch()["COUNT(*)"];
} }
function checkTeamBonus(int $team) {
// $team doit être une équipe existante :
$query = $this->pdo_teams->query("SELECT bonus FROM teams WHERE id = " . $team);
return $query->fetch()[0] == 1;
}
// public function getTeamsNb() { // public function getTeamsNb() {
// $query = $this->pdo_teams->query("SELECT COUNT(*) FROM teams"); // $query = $this->pdo_teams->query("SELECT COUNT(*) FROM teams");
// return $query->fetch()["COUNT(*)"]; // return $query->fetch()["COUNT(*)"];

View File

@ -1,44 +1,45 @@
<?php <?php
$tr = [ $tr = [
"tab_title" => [ "tab_title" => [
"home" => "Home - Lycée Pange Code Hunt", "home" => "Home - Citizen's journey",
"team_confirm" => "Team confirmation - Lycée Pange Code Hunt", "team_confirm" => "Team confirmation - Citizen's journey",
"puzzles" => "Puzzles list - Lycée Pange Code Hunt", "puzzles" => "Puzzles list - Citizen's journey",
"article" => "Puzzle - Lycée Pange Code Hunt" "article" => "Puzzle - Citizen's journey"
], ],
"page_title" => [ "page_title" => [
"home" => "Code Hunt", "home" => "Citizen's journey",
"team_confirm" => "Team confirmation", "team_confirm" => "Team confirmation",
"puzzles" => "Puzzles list for team n°", "puzzles" => "Puzzles list for team n°",
"article" => "Puzzle n°" "article" => "Puzzle n°"
], ],
"home" => [ "home" => [
"subtitle" => "Welcome to the code hunt of Lycée Jean de Pange of Sarreguemines !", "subtitle" => "Welcome to the Citizen's journey!",
"message" => "Enter your team number to begin :", "message" => "Enter your team number to begin:",
"team" => "Team number...", "team" => "Team number...",
"button" => "OK" "button" => "OK"
], ],
"team_confirm" => [ "team_confirm" => [
"subtitle" => "Please make sure you selected the right team.", "subtitle" => "Please make sure you selected the right team.",
"message" => "Your name must appear on the following list : ", "message" => "Your name must appear on the following list: ",
"button" => "Yes, this is my team !" "button" => "Yes, this is my team !"
], ],
"article" => [ "article" => [
"message" => "This puzzle describes a specific place. Head to that place, then scan the QR code you'll find there.", "message" => "This puzzle describes a specific place. Head to that place, then scan the QR code you'll find there.",
"success" => "Well done ! Your team solved this puzzle !", "success" => "Well done ! Your team solved this puzzle !",
"back_but" => "Puzzle list", "back_but" => "Puzzle list",
"next_but" => "Next puzzle", "prev_but" => "🡰 Prev.",
"next_but" => "Next 🡲",
"qr_but" => "Scan QR code", "qr_but" => "Scan QR code",
"cam_sel" => "Selected camera :", "cam_sel" => "Selected camera:",
"f_cam" => "Front camera", "f_cam" => "Front camera",
"r_cam" => "Rear camera" "r_cam" => "Rear camera"
], ],
"puzzles" => [ "puzzles" => [
"message" => "Select a puzzle in the list below :", "message" => "Select a puzzle in the list below:",
"map_desc" => "Here is a map showing the location of the puzzles you already solved :" "map_desc" => "Here is a map showing the location of the puzzles you already solved:"
], ],
"nav" => [ "nav" => [
"title" => "Code Hunt Pange", "title" => "Citizen's journey",
"home" => "Home" "home" => "Home"
], ],
"footer" => [ "footer" => [

View File

@ -1,19 +1,19 @@
<?php <?php
$tr = [ $tr = [
"tab_title" => [ "tab_title" => [
"home" => "Accueil - Chasse au code Lycée Pange", "home" => "Accueil - Parcours citoyen",
"team_confirm" => "Confirmation du choix d'équipe - Chasse au code Lycée Pange", "team_confirm" => "Confirmation du choix d'équipe - Parcours citoyen",
"puzzles" => "Liste des énigmes - Chasse au code Lycée Pange", "puzzles" => "Liste des énigmes - Parcours citoyen",
"article" => "Énigme - Chasse au code Lycée Pange" "article" => "Énigme - Parcours citoyen"
], ],
"page_title" => [ "page_title" => [
"home" => "Chasse au code", "home" => "Parcours citoyen",
"team_confirm" => "Confirmation du choix d'équipe", "team_confirm" => "Confirmation du choix d'équipe",
"puzzles" => "Liste des puzzles pour l'équipe n°", "puzzles" => "Liste des puzzles pour l'équipe n°",
"article" => "Énigme n°" "article" => "Énigme n°"
], ],
"home" => [ "home" => [
"subtitle" => "Bienvenue à la chasse au code du Lycée Jean de Pange de Sarreguemines !", "subtitle" => "Bienvenue dans le Parcours citoyen !",
"message" => "Pour commencer, veuillez entrer le numéro de votre équipe :", "message" => "Pour commencer, veuillez entrer le numéro de votre équipe :",
"team" => "Numéro d'équipe...", "team" => "Numéro d'équipe...",
"button" => "Valider" "button" => "Valider"
@ -27,7 +27,8 @@
"message" => "Cette énigme décrit un endroit précis. Dirigez-vous vers cet endroit, puis scannez le QR code que vous-y trouverez.", "message" => "Cette énigme décrit un endroit précis. Dirigez-vous vers cet endroit, puis scannez le QR code que vous-y trouverez.",
"success" => "Bien joué ! Votre équipe a résolu cette énigme !", "success" => "Bien joué ! Votre équipe a résolu cette énigme !",
"back_but" => "Liste des énigmes", "back_but" => "Liste des énigmes",
"next_but" => "Énigme suivante", "prev_but" => "🡰 Préc.",
"next_but" => "Suiv. 🡲",
"qr_but" => "Scanner le QR code", "qr_but" => "Scanner le QR code",
"cam_sel" => "Caméra sélectionnée :", "cam_sel" => "Caméra sélectionnée :",
"f_cam" => "Caméra avant", "f_cam" => "Caméra avant",
@ -38,11 +39,11 @@
"map_desc" => "Voici la carte des emplacements des énigmes que vous avez résolues :" "map_desc" => "Voici la carte des emplacements des énigmes que vous avez résolues :"
], ],
"nav" => [ "nav" => [
"title" => "Chasse au code Pange", "title" => "Parcours citoyen",
"home" => "Accueil" "home" => "Accueil"
], ],
"footer" => [ "footer" => [
"text" => "Lycée Jean de Pange Sarreguemines<br><a href='https://forge.chapril.org/antux18/ChasseTresorPange'>Code source</a>" "text" => "Lycée Jean de Pange Sarreguemines<br><a href='https://forge.chapril.org/Antux/JeuPistesSarreguemines'>Code source</a>"
] ]
]; ];
?> ?>

View File

@ -0,0 +1,9 @@
<?php
$pzorder = [
[7,4,3,2,5,8,9,6,10,1],
[10,6,8,5,2,7,4,3,9,1],
[5,2,7,4,3,6,8,10,9,1],
[3,6,8,10,9,4,7,5,2,1],
[9,6,10,4,7,8,5,3,2,1]
]
?>

View File

@ -149,6 +149,7 @@ main header section {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center;
gap: 15px; gap: 15px;
} }