Add challenge feedback API

This commit is contained in:
2026-07-21 22:29:22 +02:00
parent 5a388d3d60
commit f4fea7324a
7 changed files with 500 additions and 6 deletions
+186 -1
View File
@@ -381,6 +381,47 @@
return lignes;
};
Recette.prototype.analyser = function () {
var actions = this.notions.fonctions.slice();
var etapesAPlates = aplatirEtapes(this.etapes);
var derniereAction =
etapesAPlates.length > 0
? actionDeTexte(etapesAPlates[etapesAPlates.length - 1].texte)
: "";
var erreurs = [];
if (this.etapes.length === 0) {
erreurs.push("Ta recette est vide : ajoute au moins une etape.");
}
if (this.etapes.length > 0 && derniereAction !== "servir") {
erreurs.push("Ta recette ne se termine pas par servir.");
}
etapesAPlates.forEach((etape, index) => {
if (
actionDeTexte(etape.texte) === "servir" &&
index !== etapesAPlates.length - 1
) {
erreurs.push("Tu as servi avant la fin de la recette.");
}
});
return {
nom: this.nom,
ingredients: this.notions.variables.slice(),
variables: this.notions.variables.slice(),
materiels: this.notions.constantes.slice(),
constantes: this.notions.constantes.slice(),
actions: actions,
nombreEtapes: etapesAPlates.length,
utiliseBoucle: this.notions.boucles,
utiliseCondition: this.notions.conditions,
termineParServir: derniereAction === "servir",
erreurs: erreurs,
};
};
Recette.prototype._lignesNotions = function () {
var lignes = [
"",
@@ -446,6 +487,148 @@
return html;
};
function aplatirEtapes(etapes) {
var resultat = [];
etapes.forEach((etape) => {
resultat.push(etape);
if (etape.enfants && etape.enfants.length > 0) {
resultat = resultat.concat(aplatirEtapes(etape.enfants));
}
});
return resultat;
}
function actionDeTexte(texteEtape) {
var index;
var valeur = texte(texteEtape).toLowerCase();
var actions = [
"prendre",
"utiliser",
"ajouter",
"retirer",
"couper",
"melanger",
"verser",
"chauffer",
"cuire",
"attendre",
"repeter",
"si",
"servir",
];
for (index = 0; index < actions.length; index += 1) {
if (valeur.indexOf(actions[index]) === 0) {
return actions[index];
}
}
return "";
}
function defi(nom, regles) {
if (!nom && nom !== 0) {
throw new Error("CookieCode : un defi doit avoir un nom.");
}
return {
type: "defi",
nom: texte(nom),
regles: regles || {},
};
}
function verifier(recetteAVerifier, defiAVerifier) {
var rapport = recetteAVerifier.analyser();
var regles = defiAVerifier?.regles ? defiAVerifier.regles : {};
var messages = [];
var reussi = true;
function valider(condition, succes, echec) {
if (condition) {
messages.push("✅ " + succes);
} else {
reussi = false;
messages.push("❌ " + echec);
}
}
if (regles.ingredientsMinimum !== undefined) {
valider(
rapport.ingredients.length >= regles.ingredientsMinimum,
"Tu as utilise " + rapport.ingredients.length + " ingredient(s).",
"Il faut au moins " + regles.ingredientsMinimum + " ingredient(s).",
);
}
if (regles.materielsMinimum !== undefined) {
valider(
rapport.materiels.length >= regles.materielsMinimum,
"Tu as utilise " + rapport.materiels.length + " materiel(s).",
"Il faut au moins " + regles.materielsMinimum + " materiel(s).",
);
}
(regles.actionsObligatoires || []).forEach((action) => {
valider(
rapport.actions.indexOf(action) !== -1,
"Action trouvee : " + action + ".",
"Action manquante : " + action + ".",
);
});
if (regles.boucleObligatoire) {
valider(
rapport.utiliseBoucle,
"Tu as utilise une boucle avec repeter.",
"Il manque une boucle : essaie avec .repeter().",
);
}
if (regles.conditionObligatoire) {
valider(
rapport.utiliseCondition,
"Tu as utilise une condition avec si.",
"Il manque une condition : essaie avec .si().",
);
}
if (regles.terminerParServir) {
valider(
rapport.termineParServir,
"Ta recette se termine par servir.",
"Ta recette doit se terminer par .servir().",
);
}
if (regles.interdireErreurs) {
valider(
rapport.erreurs.length === 0,
"Aucune erreur logique detectee.",
rapport.erreurs.join(" ") || "Une erreur logique a ete detectee.",
);
}
if (messages.length === 0) {
messages.push("️ Aucun critere de defi a verifier.");
}
return {
reussi: reussi,
nom: defiAVerifier ? defiAVerifier.nom : "Defi",
messages: messages,
rapport: rapport,
toText: function () {
return [
"Defi : " + this.nom,
this.reussi ? "Resultat : reussi" : "Resultat : a ameliorer",
]
.concat(this.messages)
.join("\n");
},
};
}
function etapesHTML(etapes) {
var html = "<ol>";
etapes.forEach((etape) => {
@@ -470,7 +653,9 @@
materiel: materiel,
constante: constante,
preparation: preparation,
version: "0.1.0",
defi: defi,
verifier: verifier,
version: "0.2.0",
};
return CookieCode;