n'afficher que les définitions de la case

This commit is contained in:
Adrien MALINGREY 2025-05-01 14:06:44 +02:00
parent 92306e2a2a
commit c8ecb504ef
5 changed files with 266 additions and 226 deletions

View File

@ -20,7 +20,7 @@ class Grille implements Iterator, ArrayAccess {
private $lettres_suivantes; private $lettres_suivantes;
private $positions; private $positions;
private $nb_positions; private $nb_positions;
private $mots_utilises; public $mots_utilises;
public function __construct($hauteur, $largeur, $id = "") public function __construct($hauteur, $largeur, $id = "")
{ {

View File

@ -35,6 +35,9 @@ foreach ($dico as $mot => $definition) {
$mots_de_n_lettres[$n] = []; $mots_de_n_lettres[$n] = [];
} }
$mots_de_n_lettres[$n][] = $mot; $mots_de_n_lettres[$n][] = $mot;
if (!empty($definitions)) {
$dico[$mot] = [$definitions[array_rand($definitions)]];
}
} }
function mots_espaces($longueur) function mots_espaces($longueur)

View File

@ -38,14 +38,14 @@ $largeur = filter_input(INPUT_GET, 'c', FILTER_VALIDATE_INT, [
$grille = new Grille($hauteur, $largeur, $id); $grille = new Grille($hauteur, $largeur, $id);
$grille->current(); $grille->current();
$definitions = [ $definitions = [
"horizontales" => [], "lignes" => [],
"verticales" => [] "colonnes" => []
]; ];
for ($y = 0; $y < $hauteur; $y++) { for ($y = 0; $y < $hauteur; $y++) {
$definitions["horizontales"][$y] = $dico[$grille->get_ligne($y, $largeur)]; $definitions["lignes"][$y] = $dico[$grille->get_ligne($y, $largeur)];
} }
for ($x = 0; $x < $largeur; $x++) { for ($x = 0; $x < $largeur; $x++) {
$definitions["verticales"][$x] = $dico[$grille->get_colonne($x, $hauteur)]; $definitions["colonnes"][$x] = $dico[$grille->get_colonne($x, $hauteur)];
} }
?> ?>
@ -107,10 +107,10 @@ for ($x = 0; $x < $largeur; $x++) {
<?php for ($x = 0; $x < $largeur; $x++): ?> <?php for ($x = 0; $x < $largeur; $x++): ?>
<td class="case <?= $grille[$y][$x] == " " ? "noire" : "blanche" ?>"> <td class="case <?= $grille[$y][$x] == " " ? "noire" : "blanche" ?>">
<?php if ($grille[$y][$x] == " "): ?> <?php if ($grille[$y][$x] == " "): ?>
<input type="text" maxlength="1" size="1" value=" " disabled /> <input id="<?= chr($x + 65) . ($y + 1) ?>" type="text" maxlength="1" size="1" value=" " disabled />
<?php else: ?> <?php else: ?>
<input type="text" maxlength="1" size="1" pattern="[A-Z]" placeholder="<?= $grille[$y][$x] ?>" <input id="<?= chr($x + 65) . ($y + 1) ?>" type="text" maxlength="1" size="1" pattern="[A-Z]" placeholder="<?= $grille[$y][$x] ?>"
title="<?= "➡️ " . strip_tags(implode(" ➡️ ", $definitions["horizontales"][$y])) . "\n⬇ " . strip_tags(implode("\n⬇ ", $definitions["verticales"][$x])) ?>" /> title="<?= "" . strip_tags(implode("\n→ ", $definitions["lignes"][$y])) . "\n↓ " . strip_tags(implode("\n↓ ", $definitions["colonnes"][$x])) ?>" />
<?php endif; ?> <?php endif; ?>
</td> </td>
<?php endfor; ?> <?php endfor; ?>
@ -121,37 +121,37 @@ for ($x = 0; $x < $largeur; $x++) {
<div class="definitions horizontales"> <div class="definitions horizontales">
<h2>Horizontalement</h2> <h2>Horizontalement</h2>
<ol> <ol>
<?php for ($y = 0; $y < $hauteur; $y++): ?> <?php foreach ($definitions["lignes"] as $y => $definitions_ligne): ?>
<li> <li>
<?php if (count($definitions["horizontales"][$y]) == 1): ?> <?php if (count($definitions_ligne) == 1): ?>
<?= $definitions["horizontales"][$y][0] ?> <?= $definitions_ligne[0] ?>
<?php else: ?> <?php else: ?>
<ol> <ol>
<?php foreach ($definitions["horizontales"][$y] as $definition) : ?> <?php foreach ($definitions_ligne as $definition) : ?>
<li><?= $definition ?></li> <li><?= $definition ?></li>
<?php endforeach ?> <?php endforeach ?>
</ol> </ol>
<?php endif ?> <?php endif ?>
</li> </li>
<?php endfor; ?> <?php endforeach; ?>
</ol> </ol>
</div> </div>
<div class="definitions verticales"> <div class="definitions verticales">
<h2>Verticalement</h2> <h2>Verticalement</h2>
<ol type="A"> <ol type="A">
<?php for ($x = 0; $x < $largeur; $x++): ?> <?php foreach ($definitions["colonnes"] as $x => $definitions_colonne): ?>
<li> <li>
<?php if (count($definitions["horizontales"][$x]) == 1): ?> <?php if (count($definitions_colonne) == 1): ?>
<?= $definitions["horizontales"][$x][0] ?> <?= $definitions_colonne[0] ?>
<?php else: ?> <?php else: ?>
<ol> <ol>
<?php foreach ($definitions["horizontales"][$x] as $definition) : ?> <?php foreach ($definitions_colonne as $definition) : ?>
<li><?= $definition ?></li> <li><?= $definition ?></li>
<?php endforeach ?> <?php endforeach ?>
</ol> </ol>
<?php endif ?> <?php endif ?>
</li> </li>
<?php endfor; ?> <?php endforeach; ?>
</ol> </ol>
</div> </div>
<?php else: ?> <?php else: ?>

112
script.js
View File

@ -1,59 +1,79 @@
async function sha256(text) { async function sha256(text) {
const encoder = new TextEncoder(); const encoder = new TextEncoder();
const data = encoder.encode(text); const data = encoder.encode(text);
const hashBuffer = await crypto.subtle.digest('SHA-256', data); const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
} }
const inputs = Array.from(grilleForm.querySelectorAll('input[type="text"]')); const inputs = Array.from(grilleForm.querySelectorAll('input[type="text"]'));
let largeur = Number(colonnes.value); let largeur = Number(colonnes.value);
let nb_cases = inputs.length; let nb_cases = inputs.length;
let index = 0; let index = 0;
inputs.forEach((input) => {
input.index = index++;
input.x = input.index % largeur;
input.y = Math.floor(input.index / largeur);
inputs.forEach(input => { input.onfocus = function (event) {
input.index = index++; for (li of document.querySelectorAll(`.definitions.horizontales > ol > li:nth-child(${input.y+1}), .definitions.verticales > ol > li:nth-child(${input.x+1})`)) {
li.classList.add("selectionee")
}
for (li of document.querySelectorAll(`.definitions.horizontales > ol > li:not(:nth-child(${input.y+1})), .definitions.verticales > ol > li:not(:nth-child(${input.x+1}))`)) {
li.classList.add("non-selectionee")
}
input.select();
};
input.onfocus = function (event) { input.onkeydown = function (event) {
input.select(); next_input = null;
}; switch (event.key) {
case "ArrowUp":
next_input = inputs[(input.index - largeur + nb_cases) % nb_cases];
break;
case "ArrowDown":
next_input = inputs[(input.index + largeur) % nb_cases];
break;
case "ArrowLeft":
next_input = inputs[(input.index - 1 + nb_cases) % nb_cases];
break;
case "ArrowRight":
next_input = inputs[(input.index + 1) % nb_cases];
break;
}
if (next_input) {
next_input.focus();
next_input.select();
event.preventDefault();
}
};
input.onkeydown = function (event) { input.oninput = function (event) {
next_input = null; this.value = this.value.toUpperCase();
switch (event.key) { if (!input.checkValidity()) {
case 'ArrowUp': input.value = "";
next_input = inputs[(input.index - largeur + nb_cases) % nb_cases]; }
break; if (
case 'ArrowDown': inputs.every((input) => input.value.length == 1) &&
next_input = inputs[(input.index + largeur) % nb_cases]; grilleForm.checkValidity()
break; ) {
case 'ArrowLeft': sha256(inputs.map((input) => input.value).join("")).then((hash) => {
next_input = inputs[(input.index - 1 + nb_cases) % nb_cases]; if (hash == solution_hashee.value) {
break; if (confirm("Bravo ! \nUne nouvelle partie ?")) {
case 'ArrowRight': grilleForm.submit();
next_input = inputs[(input.index + 1) % nb_cases]; }
break;
} }
if (next_input) { });
next_input.focus(); }
next_input.select(); };
event.preventDefault();
}
};
input.oninput = function (event) { input.onblur = function (event) {
this.value = this.value.toUpperCase(); for (li of document.querySelectorAll(`.definitions.horizontales > ol > li:nth-child(${input.y+1}), .definitions.verticales > ol > li:nth-child(${input.x+1})`)) {
if (!input.checkValidity()) { li.classList.remove("selectionee")
input.value = ''; }
} for (li of document.querySelectorAll(`.definitions.horizontales > ol > li:not(:nth-child(${input.y+1})), .definitions.verticales > ol > li:not(:nth-child(${input.x+1}))`)) {
if (inputs.every(input => input.value.length == 1) && grilleForm.checkValidity()) { li.classList.remove("non-selectionee")
sha256(inputs.map(input => input.value).join('')).then(hash => { }
if (hash == solution_hashee.value) { };
if (confirm('Bravo ! \nUne nouvelle partie ?')) {
grilleForm.submit();
}
}
});
}
};
}); });

341
style.css
View File

@ -1,283 +1,300 @@
body { body {
margin: 0; margin: 0;
padding: 2rem 1rem; padding: 0;
background-color: white; background-color: white;
font-family: Times, 'Times New Roman', Georgia, serif; font-family: Times, "Times New Roman", Georgia, serif;
} }
form { form {
display: flex; display: flex;
flex-flow: column; padding: 1rem;
min-height: calc(100vh - 4rem); min-height: calc(100vh - 2rem);
flex-flow: column;
justify-content: space-between;
} }
h1 { h1 {
margin: 0; margin: 0;
letter-spacing: 0.2em; letter-spacing: 0.2em;
} }
h1.large.width { h1.large.width {
display: inherit; display: inherit;
padding-top: 1rem;
} }
h1.small.width { h1.small.width {
display: none; display: none;
} }
h1 table { h1 table {
margin: auto; margin: auto;
line-height: 0.8; line-height: 0.8;
} }
h1 td { h1 td {
width: 0.7em; width: 0.7em;
text-align: center; text-align: center;
} }
h1, h1,
h2 { h2 {
font-variant-caps: petite-caps; font-variant-caps: petite-caps;
text-align: center; text-align: center;
} }
.grille-et-definitions { .grille-et-definitions {
display: flex; display: flex;
flex-flow: row; flex-flow: row;
justify-content: space-evenly; justify-content: space-evenly;
flex-wrap: wrap; flex-wrap: wrap;
height: max-content; height: max-content;
flex-grow: 1; gap: 1em;
align-items: center;
} }
.grille table { .grille table {
border-collapse: collapse; border-collapse: collapse;
margin: 0 auto; margin: 0 auto;
height: fit-content; height: fit-content;
} }
.grille th, .grille th,
.grille td { .grille td {
width: 2rem; width: 2rem;
height: 2rem; height: 2rem;
text-align: center; text-align: center;
} }
.grille td { .grille td {
width: 2rem; width: 2rem;
height: 2rem; height: 2rem;
border: 1px solid black; border: 1px solid black;
padding: 2px; padding: 2px;
background-color: white; background-color: white;
} }
.grille tr:nth-of-type(2) td { .grille tr:nth-of-type(2) td {
border-top-width: 3px; border-top-width: 3px;
} }
.grille tr:last-of-type td { .grille tr:last-of-type td {
border-bottom-width: 3px; border-bottom-width: 3px;
} }
.grille td:first-of-type { .grille td:first-of-type {
border-left-width: 3px; border-left-width: 3px;
} }
.grille td:last-child { .grille td:last-child {
border-right-width: 3px; border-right-width: 3px;
} }
.grille .case.noire { .grille .case.noire {
background-color: black; background-color: black;
} }
.grille .case.noire { .grille .case.noire {
background-color: black; background-color: black;
} }
.grille input { .grille input {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: none; border: none;
padding: 0; padding: 0;
text-align: center; text-align: center;
font-size: 1.2em; font-size: 1.2em;
font-family: 'Comic Sans MS', 'Comic Sans', sans; font-family: "Comic Sans MS", "Comic Sans", sans;
color: darkblue; color: darkblue;
background-color: white; background-color: white;
} }
.grille input[disabled] { .grille input[disabled] {
background-color: black; background-color: black;
} }
.grille input::placeholder { .grille input::placeholder {
color: transparent; color: transparent;
} }
.definitions { .definitions {
width: 30%; width: 30%;
} }
.definitions.horizontales { .definitions.horizontales {
order: -1; order: -1;
} }
.definitions ol { .definitions ol {
padding-left: 2em; padding-left: 2em;
} }
.definitions > div > ol > li::marker { .definitions > div > ol > li::marker {
font-weight: bold; font-weight: bold;
} }
.definitions li ol { .definitions li ol {
padding-left: 0em; padding-left: 0em;
list-style: parenthese; list-style: parenthese;
} }
@counter-style parenthese { @counter-style parenthese {
system: extends decimal; system: extends decimal;
suffix: ") "; suffix: ") ";
} }
.definitions li li { .definitions li li {
margin-left: 0.8em; margin-left: 0.8em;
counter-increment: count; counter-increment: count;
} }
.definitions li li::marker { .definitions li li::marker {
font-size: small; font-size: small;
} }
.definitions em { .definitions em {
text-wrap: nowrap; text-wrap: nowrap;
}
.definitions.case ol.horizontales {
list-style-type: "→ ";
}
.definitions.case ol.verticales {
list-style-type: "↓ ";
}
.definitions li {
transition: opacity 0.3s;
}
.definitions li.non-selectionee {
opacity: 30%;
} }
.erreur { .erreur {
text-align: center; text-align: center;
} }
button[type='submit'] { button[type="submit"] {
width: fit-content; width: fit-content;
margin: 0 auto; margin: 0 auto;
} }
button[type='submit'] { button[type="submit"] {
width: 100%; width: 100%;
margin: auto; margin: 1em auto 0 auto;
border: none; border: none;
background: none; background: none;
font-family: inherit; font-family: inherit;
font-size: 1em; font-size: 1em;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5em; gap: 0.5em;
justify-content: center; justify-content: center;
} }
button[type="submit"]:hover { button[type="submit"]:hover {
cursor: pointer; cursor: pointer;
color: #2a6496; color: #2a6496;
text-decoration: underline; text-decoration: underline;
} }
button[type="submit"]:active { button[type="submit"]:active {
color: darkorchid; color: darkorchid;
} }
@media (max-width: 1024px) { @media (max-width: 1024px) {
body { h1.large.width {
padding: 1.5rem 1rem; display: none;
} }
h1.large.width { h1.small.width {
display: none; display: initial;
} }
h1.small.width { h1 table {
display: initial; line-height: 0.7;
} }
h1 table { .grille {
line-height: 0.7; width: 100%;
} margin: auto;
}
form {
min-height: calc(100vh - 2rem); .definitions {
} width: 45%;
}
.grille {
width: 100%; .definitions.horizontales {
margin: auto; order: inherit;
} }
.definitions {
width: 45%;
}
.definitions.horizontales {
order: inherit
}
} }
@media (max-width: 640px) { @media (max-width: 640px) {
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
body {
width: auto;
margin: 0;
padding: 1rem 0;
}
h1.large.width { body {
display: none; width: auto;
} margin: 0;
padding: 1rem 0;
}
h1.small.width { h1.large.width {
display: none; display: none;
} }
.grille td { h1.small.width {
width: 2.5rem; display: none;
height: 2.5rem; }
}
.definitions {
display: flex;
flex-flow: column;
}
.definitions.horizontales, .grille td {
.definitions.verticales { width: 2.5rem;
width: 100%; height: 2.5rem;
} }
h2 {
font-size: 1.2em;
margin: 1em 0 0.5em 0;
}
.definitions.horizontales,
.definitions.verticales {
width: 100%;
}
.definitions > ol {
margin: 0;
}
.definitions li.non-selectionee {
display: none;
}
} }
@media (max-device-width:768px) and (orientation: landscape) { @media (max-device-width: 768px) and (orientation: landscape) {
html { html {
-webkit-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%; -ms-text-size-adjust: 100%;
} }
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
body, body,
button { button {
background-color: #02081a; background-color: #02081a;
color: #c6c6c6; color: #c6c6c6;
} }
.grille td, .grille td,
.grille input { .grille input {
background-color: #edeeee; background-color: #edeeee;
} }
button[type="submit"]:hover { button[type="submit"]:hover {
color: #479fec; color: #479fec;
} }
button[type="submit"]:active { button[type="submit"]:active {
color: orchid; color: orchid;
} }
} }