Browse Source

Travail sur les formulaires CVT.

--------------------------------
Report de [64877] adapté à SPIP 3.0
+ Reports de [64912] (retrait des globales QCM/QRM et Trous)
+ Amélioration des traitements de #TEXTE/jeux grâce à l'utilisation préférentielle d'une nouvelle balise raccourci : #TEXTE_JEU. Grâce à cette balise, le traitement pre_propre (pré-décodage des jeux) qui doit agir sur le texte brut du jeu est effectué au plus tôt, avant le reste des traitements repris de la balise #TEXTE. Les arguments de cette balise sont ajoutes à la config interne du jeu (dans une boucle (JEUX), #TEXTE_JEU{key1, value1, key2, value2,...} ajoute au jeu la section suivante : [config]id_jeu=#ID_JEU, key1=value1, key2=value2, etc.)

L'idée est donc d'obtenir la correction des jeux en AJAX, grâce à l'API CVT de SPIP.
Ce système n'est pas pleinement utilisé car l'enregistrement des scores en base se fait au moment du calcul de la correction du jeu, bien avant l'action 'Traiter'.
L'action 'Vérifier' est aujourd'hui toujours validée, car les jeux ne gèrent pas (encore?) de champ bloquant.
TODO : Le reset d'un jeu n'est pas encore ajaxé.

Voici donc les 3 façons pour gérer/afficher un jeu :
  - les jeux inline entre balises <jeux/> et sans score
  - les jeux créés en base (avec score), appelés grâce au modèle <jeuXX>
  - les jeux créés en base (avec score), corrigés en AJAX grâce au raccourci <formulaire|jeu|XX>
svn/root/tags/v3.4.6
patfr@ifrance.com 11 years ago
parent
commit
2b6a29d519
  1. 4
      .gitattributes
  2. 15
      _REGLES_DE_COMMIT.txt
  3. 0
      _TODO.txt
  4. 2
      base/jeux_tables.php
  5. 15
      formulaires/editer_jeu.php
  6. 16
      formulaires/jeu.html
  7. 65
      formulaires/jeu.php
  8. 6
      formulaires/jeux_gerer_resultats.php
  9. 443
      jeux/mots_croises.php
  10. 139
      jeux/qcm.php
  11. 410
      jeux/sudoku.php
  12. 64
      jeux/trous.php
  13. 49
      jeux_fonctions.php
  14. 52
      jeux_pipelines.php
  15. 53
      jeux_utils.php
  16. 4
      modeles/jeu.html

4
.gitattributes vendored

@ -1,6 +1,6 @@
* text=auto !eol
/_REGLES_DE_COMMIT.txt -text
/afaire.txt -text
/_TODO.txt -text
base/jeux_ajouter_resultat.php -text
base/jeux_tables.php -text
fonds/bouton_corriger.html -text
@ -11,6 +11,8 @@ fonds/jeu_score.html -text
formulaires/configurer_jeux.html -text
formulaires/editer_jeu.html -text
formulaires/editer_jeu.php -text
formulaires/jeu.html -text
formulaires/jeu.php -text
formulaires/jeux_gerer_resultats.html -text
formulaires/jeux_gerer_resultats.php -text
/gpl_fr.txt -text

15
_REGLES_DE_COMMIT.txt

@ -6,14 +6,16 @@ Auteurs : Patrice Vanneufville
Voici les règles à suivre avant de commiter des modifications sur
cette branche.
A. Observer le planning de travail. Pour le modifier, proposez-nous vos idées !
A. Observer le planning de travail.
===================================
Pour le modifier, proposez-nous vos idées !
Planning de modification, sans ordre :
1. Prévoir Plusieurs jeux dans une page (en cours...)
1. Prévoir Plusieurs jeux dans une page (a priori OK)
2. Meilleures CSS
3. AJAX/jQuery
4. Traductions et ajouts de langues
3. AJAX/jQuery/CVT (en cours)
4. Traductions (OK avec Salvatore et SPIP v3)
5. Statistiques des performances et des timings
6. Sauvegarde des jeux en cours (utilisateurs identifiés)
7. Notification par mail
@ -22,12 +24,14 @@ A. Observer le planning de travail. Pour le modifier, proposez-nous vos id
10. D'autres jeux, encore et encore !
B. Obligation de commenter les commits
======================================
Si vous envoyez des modifications, il faut toujours les commenter
de façon "descriptive" et "complète" avec l'option -m ou -F du
commit SVN.
C. Modification du code
========================
Cette version peut évoluer. Si vous avez envie de vous
retrousser les manches, n'hésitez pas.
@ -55,7 +59,8 @@ C. Modification du code
l'utilisateur, les dépendances qu'elle apporte.
D. Clarté du code.
D. Clarté du code
=================
Il n'y a actuellement pas de règles précises d'écriture correcte du
code. Il faut juste garder du code indenté (i.e. indenter chaque

0
afaire.txt → _TODO.txt

2
base/jeux_tables.php

@ -77,6 +77,8 @@ function jeux_declarer_tables_interfaces($tables){
$table_des_traitements['TITRE_PUBLIC'] = $table_des_traitements['TITRE'];
if (!isset($table_des_traitements['TITRE_PRIVE']))
$table_des_traitements['TITRE_PRIVE'] = $table_des_traitements['TITRE'];
if (!isset($table_des_traitements['TEXTE_JEU']))
$table_des_traitements['TEXTE_JEU'] = $table_des_traitements['TEXTE'];
return $tables;
}
?>

15
formulaires/editer_jeu.php

@ -1,9 +1,14 @@
<?php
/**
* Plugin Spip-jeus
* (c) 2012 Maïeul Rouquette d&#039;après Artego
* Licence GNU/GPL
*/
#---------------------------------------------------#
# Plugin : Jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Gestion des scores : Maieul Rouquette, 2007 #
# Portage SPIP3 : Maieul Rouquette d'apres Artego #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GNU/GPL (c) 2012 #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
if (!defined('_ECRIRE_INC_VERSION')) return;

16
formulaires/jeu.html

@ -0,0 +1,16 @@
<BOUCLE_jeu(JEUX){id_jeu}>
<div class="ajax">
<!--<div class='formulaire_spip formulaire_editer formulaire_#FORM formulaire_jeu-#ENV{id_jeu}'>-->
<div class='formulaire_jeu-#ENV{id_jeu}'>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV**{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
<form method='post' action='#ENV{action}'>
<input type='hidden' name='id_jeu' value='#ENV{id_jeu}' />
<input type='hidden' name='jeu_cvt' value='oui' />
#ACTION_FORMULAIRE{#ENV{action}}
#TEXTE_JEU{jeu_cvt,oui,index_jeux,#ENV{index_jeux}}
<!-- <p class="boutons"><input type='submit' class='submit' value='<:bouton_enregistrer:>' /></p>-->
</form>
</div>
</div>
</BOUCLE_jeu>

65
formulaires/jeu.php

@ -0,0 +1,65 @@
<?php
#---------------------------------------------------#
# Plugin : Jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Gestion des scores : Maieul Rouquette, 2007 #
# Formulaires CVT : Patrice Vanneufville, 2012 #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GNU/GPL (c) 2012 #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
if (!defined('_ECRIRE_INC_VERSION')) return;
/**
* Charger : declarer les champs postes et y integrer les valeurs par defaut ou precedemment postees
*
* @param int $id_jeu
* @return array
*/
function formulaires_jeu_charger_dist($id_jeu = 0){
// si index_jeu = 0, premier affichage et pas de correction
$indexJeux = intval(_request('index_jeux'));
return array(
// si id_jeu = 0, pas de formulaire possible
'id_jeu' => $id_jeu,
// index aleatoire du premier jeu de la page
'debut_index_jeux' => intval(_request('debut_index_jeux')),
// index aleatoire du jeu courant
'index_jeux' => $indexJeux,
// champ 0/1 indiquant s'il faut corriger ou non
'correction'.$indexJeux => intval(_request('correction_'.$indexJeux)),
// l'ensemble des reponses postees
'reponses'.$indexJeux => _request('reponses'.$indexJeux),
);
}
/**
* Verifier : corriger les champs postes
*
* @param int $id_jeu
* @return array
*/
function formulaires_jeu_verifier_dist($id_jeu = 0){
// pas de gestion d'erreur bloquante pour l'instant
return array(
// erreurs a notifier
);
}
/**
* Traiter : stocker les resultats en base
*
* @param int $id_jeu
* @return array
*/
function formulaires_jeu_traiter_dist($id_jeu = 0){
// les resultats sont deja enregistres par la correction du jeu
return array(
// 'message_ok' => _L('config_info_enregistree'),
);
}
?>

6
formulaires/jeux_gerer_resultats.php

@ -27,21 +27,21 @@ function formulaires_jeux_gerer_resultats_saisies($param=array()){
return $saisies;
}
function formulaires_jeux_gerer_resultats_charger($param=array(),$return=''){
function formulaires_jeux_gerer_resultats_charger_dist($param=array(),$return=''){
if (!autoriser('gerer','resultats')){
return false;
}
$param['saisies'] = formulaires_jeux_gerer_resultats_saisies($param);
return $param;
}
function formulaires_jeux_gerer_resultats_verifier($param=array(),$return=''){
function formulaires_jeux_gerer_resultats_verifier_dist($param=array(),$return=''){
$erreurs = array();
if (!_request('confirmer') and _request('faire')){
$erreurs['non_confirme']=true;
}
return $erreurs;
}
function formulaires_jeux_gerer_resultats_traiter($param=array(),$return=''){
function formulaires_jeux_gerer_resultats_traiter_dist($param=array(),$return=''){
$faire = _request('faire');
$id_auteur = $param['id_auteur'];
$id_jeu = $param['id_jeu'];

443
jeux/mots_croises.php

@ -1,243 +1,242 @@
<?php
if (!defined("_ECRIRE_INC_VERSION")) return;
#---------------------------------------------------#
# Plugin : jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GPL #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
/*
Insere une grille de mots croises dans vos articles !
------------------------------------------------------
Idee originale de Ma•eul ROUQUETTE
------------------------------------------------------
separateurs obligatoires : [horizontal], [vertical], [solution]
separateurs optionnels : [titre], [texte], [config]
parametres de configurations par defaut :
solution=oui // Afficher la solution ?
fondnoir=noir // couleur des cases noires
compact=non // Definitions en format compact ?
if (!defined("_ECRIRE_INC_VERSION")) return;
#---------------------------------------------------#
# Plugin : jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GPL #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
/*
Insere une grille de mots croises dans vos articles !
------------------------------------------------------
Idee originale de Ma•eul ROUQUETTE
------------------------------------------------------
separateurs obligatoires : [horizontal], [vertical], [solution]
separateurs optionnels : [titre], [texte], [config]
parametres de configurations par defaut :
solution=oui // Afficher la solution ?
fondnoir=noir // couleur des cases noires
compact=non // Definitions en format compact ?
type=0 // types de grilles : 0 ou 1
vertical=chiffres // on met des chiffres en vertical
horizontal=lettres // on met des lettres en horizontal
Exemple de syntaxe dans l'article :
-----------------------------------
<jeux>
[horizontal]
Definition 1
Definition 2. Definition 3
Definition 4. Definition 5
[vertical]
Definition 1
Definition 2
Definition 3
[solution]
aaa
b*g
a*d
</jeux>
*/
// retourne la lettre correspondant au chiffre
function lettre_grille($chiffre) {
$alphabet = _T('jeux:alphabet');
return $alphabet[$chiffre-1];
}
// affiche la grille de mot croises, avec la solution au cas ou
function affichage_grille_mc($tableau_grille, $indexJeux, $form, $solution=false){
$jeux_couleurs = _request('jeux_couleurs');
// les variables de la grille
$hauteur = sizeof($tableau_grille);
$largeur = sizeof($tableau_grille[0]);
$grille = '';
horizontal=lettres // on met des lettres en horizontal
Exemple de syntaxe dans l'article :
-----------------------------------
<jeux>
[horizontal]
Definition 1
Definition 2. Definition 3
Definition 4. Definition 5
[vertical]
Definition 1
Definition 2
Definition 3
[solution]
aaa
b*g
a*d
</jeux>
*/
// retourne la lettre correspondant au chiffre
function lettre_grille($chiffre) {
$alphabet = _T('jeux:alphabet');
return $alphabet[$chiffre-1];
}
// affiche la grille de mot croises, avec la solution au cas ou
function affichage_grille_mc($tableau_grille, $indexJeux, $form, $solution=false){
$jeux_couleurs = _request('jeux_couleurs');
// les variables de la grille
$hauteur = sizeof($tableau_grille);
$largeur = sizeof($tableau_grille[0]);
$grille = '';
$type_vertical = jeux_config('vertical');
$type_horizontal = jeux_config('horizontal');
// entetes : formulaire + grille
$grille .= (!$solution)
? ($form?jeux_form_debut('motscroises', $indexJeux, 'jeux_grille jeux_left', 'post', self()):'')
: '<div class="jeux_solution">'._T('jeux:solution').' : </div>' ;
$grille .= '<table class="jeux_grille" cellspacing="0" border="0" summary="'
. _T('motscroises:table_summary', array('hauteur'=>$hauteur,'largeur'=>$largeur))
. "\">\n\t<tr>\n\t\t<td class=\"jeux_coin\"></td>\n";
// les cellules d'entetes verticales
// entetes : formulaire + grille
$grille .= (!$solution)
? ($form?jeux_form_debut('motscroises', $indexJeux, 'jeux_grille jeux_left', 'post', self()):'')
: '<div class="jeux_solution">'._T('jeux:solution').' : </div>' ;
$grille .= '<table class="jeux_grille" cellspacing="0" border="0" summary="'
. _T('motscroises:table_summary', array('hauteur'=>$hauteur,'largeur'=>$largeur))
. "\">\n\t<tr>\n\t\t<td class=\"jeux_coin\"></td>\n";
// les cellules d'entetes verticales
for($i = 1; $i<=$largeur; $i++){
$entete_colonne = $type_vertical == 'lettres' ? lettre_grille($i) : $i ;
$grille .= "\t\t<th scope=\"col\">$entete_colonne</th>\n";
}
$grille .= "\t</tr>\n";
// debut affichage des lignes
foreach($tableau_grille as $ligne =>$contenu_ligne){
}
$grille .= "\t</tr>\n";
// debut affichage des lignes
foreach($tableau_grille as $ligne =>$contenu_ligne){
$ligne++;
$entete_ligne = $type_horizontal=='chiffres'?$ligne:lettre_grille($ligne);
$grille .= "\t<tr>\n\t<th scope=\"row\">".$entete_ligne."</th>\n"; // numeros de ligne
foreach ($contenu_ligne as $colonne =>$cellule){
$entete_ligne = $type_horizontal=='chiffres'?$ligne:lettre_grille($ligne);
$grille .= "\t<tr>\n\t<th scope=\"row\">".$entete_ligne."</th>\n"; // numeros de ligne
foreach ($contenu_ligne as $colonne =>$cellule){
$colonne++;
$entete_colonne = $type_vertical == 'lettres' ? lettre_grille($colonne) : $colonne;
$class = $ligne==$hauteur?($colonne==$largeur?' class="jeux_bas jeux_droite"':' class="jeux_bas"'):($colonne==$largeur?' class="jeux_droite"':'');
$classnoir = ' class="jeux_noir' . ($ligne==$hauteur?($colonne==$largeur?' jeux_bas jeux_droite':' jeux_bas'):($colonne==$largeur?' jeux_droite':'')) . '"';
// s'il s'agit d'un noir
if ($cellule == "*") {
$noires = $jeux_couleurs[jeux_config('fondnoir')];
$noires = "rgb($noires[0], $noires[1], $noires[2])";
$grille .= "\t\t<td$classnoir style=\"background-color:$noires; color:$noires;\">*</td>\n";
}
else if ($solution)
$grille .= "\t\t<td$class>$cellule</td>\n" ;
else {
$name = 'GR'.$indexJeux.'x'.$colonne.'x'.$ligne;
$valeur = _request($name);
$grille .= "\t\t<td$class><label for=\"$name\">"
. _T('jeux:ligne_n', array('n'=>$entete_ligne)).';'
. _T('jeux:colonne_n', array('n'=>$entete_colonne)).'</label>'
. '<input type="text" maxlength="1" '
. ((isset($valeur) and $valeur!='')? 'value="'.$valeur:'')
.'" name="'.$name.'" id="'.$name.'" />'
. "</td>\n" ;
}
} // foreach
$grille = $grille."\t</tr>\n";}
// fin affichage des lignes
$grille.="</table>\n";
if (!$solution) $grille .=
(jeux_config('solution')?"<p><input id=\"affiche_solution_$indexJeux\" name=\"affiche_solution_{$indexJeux}[]\" type=\"checkbox\" class=\"jeux_cocher\" value=\"1\" /><label for=\"affiche_solution_$indexJeux\" >"._T('jeux:afficher_solution')."</label></p>\n":'')
.'<p><input type="submit" value="'._T('jeux:verifier')."\" name=\"bouton_envoi_$indexJeux\" /></p>"
.($form?jeux_form_fin():'');
return $grille;
}
// dechiffre le code source de la grille
function calcul_tableau_grille($texte){
$texte = preg_replace(",\s?[\r\n]+\s?,", "\n", trim($texte));
$tableau = preg_split("/\n/", $texte);
foreach ($tableau as $i=>$valeur) $tableau[$i] = preg_split('//', trim($valeur), -1, PREG_SPLIT_NO_EMPTY);
return $tableau;
}
// compare les variables Post avec les valeurs de la solution...
function comparaison_grille($tableau_grille, $indexJeux) {
$erreurs=0; $vides=0; $total=0;
foreach($tableau_grille as $ligne =>$contenu_ligne) {
foreach ($contenu_ligne as $colonne =>$cellule) {
//compare les valeurs du tableau PHP avec les variables POST
if ($cellule!='*') {
$input = trim(_request('GR'.$indexJeux.'x'.($colonne+1).'x'.($ligne+1)));
$total++; // nombre de case total
if ($input=='') $vides++;
elseif (strtoupper($input)!=strtoupper($cellule)) $erreurs++;
}
}
}
return array($erreurs, $vides,$total);
}
// renvoie le nombre d'erreurs et de cases vides
function calcul_erreurs_grille($solution, $indexJeux) {
if (_request("bouton_envoi_$indexJeux") == '') return '';
else {
list($nbr_erreurs, $nbr_vides,$total) = comparaison_grille($solution, $indexJeux);
// on insere le resultat dans la base de donnee
if ($_POST['id_jeu']){
include_spip('base/jeux_ajouter_resultat');
jeux_ajouter_resultat($_POST['id_jeu'], $total-$nbr_erreurs-$nbr_vides, $total, "erreurs=$nbr_erreurs, vides=$nbr_vides");
}
// on retourne ce qu'on affiche
return '<div class="jeux_erreur">'
. (($nbr_erreurs==0)?_T('jeux:aucune_erreur'):(
($nbr_erreurs==1)?_T('jeux:une_erreur'):_T("jeux:n_erreurs", array('n'=>$nbr_erreurs))
))
. (($nbr_vides==0)?(($nbr_erreurs==0)?'. '._T('jeux:bravo'):''):(
($nbr_vides==1)?' - '._T('jeux:une_vide'):' - '._T("jeux:n_vides", array('n'=>$nbr_vides))
))
. '</div><br />';
}
}
// retourne une liste compactee alphabetique ou numerique
function jeux_listes_compacte($texte, $alpha) {
$tableau = preg_split("/[\r\n]+/", trim($texte));
$tableau2 = array(); $i=0; $a=_T('jeux:alphabet');
foreach ($tableau as $i=>$valeur) if (($valeur=trim($valeur))!='') {
$c=$alpha?$a[$i]:$i+1;
if ($valeur[strlen($valeur)-1]!='.') $valeur.='.';
if ($valeur!='-.') $tableau2[] = "<strong>$c.</strong>&nbsp;$valeur";
}
return implode(' ', $tableau2);
}
// definitions des mots croises
function affichage_definitions($horizontal, $vertical) {
if (jeux_config('compact')) return
'<p><strong>'._T('motscroises:horizontalement').'&nbsp;</strong>'
.jeux_listes_compacte($horizontal, jeux_config('horizontal')=='lettres')
.'<br /><strong>'._T('motscroises:verticalement').'&nbsp;</strong>'
.jeux_listes_compacte($vertical, jeux_config('vertical')=='lettres').'</p>';
$entete_colonne = $type_vertical == 'lettres' ? lettre_grille($colonne) : $colonne;
$class = $ligne==$hauteur?($colonne==$largeur?' class="jeux_bas jeux_droite"':' class="jeux_bas"'):($colonne==$largeur?' class="jeux_droite"':'');
$classnoir = ' class="jeux_noir' . ($ligne==$hauteur?($colonne==$largeur?' jeux_bas jeux_droite':' jeux_bas'):($colonne==$largeur?' jeux_droite':'')) . '"';
// s'il s'agit d'un noir
if ($cellule == "*") {
$noires = $jeux_couleurs[jeux_config('fondnoir')];
$noires = "rgb($noires[0], $noires[1], $noires[2])";
$grille .= "\t\t<td$classnoir style=\"background-color:$noires; color:$noires;\">*</td>\n";
}
else if ($solution)
$grille .= "\t\t<td$class>$cellule</td>\n" ;
else {
list($id, $name) = jeux_idname($indexJeux, $colonne, 'C', $ligne, 'L');
$value = jeux_form_reponse($indexJeux, $colonne, 'C', $ligne, 'L');
$value = strlen($value)?' value="'.$value.'"':'';
$grille .= "\t\t<td$class><label for=\"$name\">"
. _T('jeux:ligne_n', array('n'=>$entete_ligne)).';'
. _T('jeux:colonne_n', array('n'=>$entete_colonne)).'</label>'
. "<input type='text' maxlength='1'$value name='$name' id='$id' /></td>\n" ;
}
} // foreach
$grille = $grille."\t</tr>\n";}
// fin affichage des lignes
$grille.="</table>\n";
if (!$solution) {
list($id, $name) = jeux_idname($indexJeux, 'SOL');
$grille .=
(jeux_config('solution')?"<p><input id='$id' name='$name' type='checkbox' class='jeux_cocher' value='1' /><label for='$id' >"._T('jeux:afficher_solution')."</label></p>\n":'')
.'<p><input type="submit" value="'._T('jeux:verifier')."\" name='submit' /></p>"
.($form?jeux_form_fin():'');
}
return $grille;
}
// dechiffre le code source de la grille
function calcul_tableau_grille($texte){
$texte = preg_replace(",\s?[\r\n]+\s?,", "\n", trim($texte));
$tableau = preg_split("/\n/", $texte);
foreach ($tableau as $i=>$valeur) $tableau[$i] = preg_split('//', trim($valeur), -1, PREG_SPLIT_NO_EMPTY);
return $tableau;
}
// compare les variables Post avec les valeurs de la solution...
function comparaison_grille($tableau_grille, $indexJeux) {
$erreurs=0; $vides=0; $total=0;
foreach($tableau_grille as $ligne =>$contenu_ligne) {
foreach ($contenu_ligne as $colonne =>$cellule) {
//compare les valeurs du tableau PHP avec les variables POST
if ($cellule!='*') {
$input = jeux_form_reponse($indexJeux, $colonne+1, 'C', $ligne+1, 'L');
$total++; // nombre de case total
if ($input=='') $vides++;
elseif (strtoupper($input)!=strtoupper($cellule)) $erreurs++;
}
}
}
return array($erreurs, $vides,$total);
}
// renvoie le nombre d'erreurs et de cases vides
function calcul_erreurs_grille($solution, $indexJeux) {
if (!jeux_form_correction($indexJeux)) return '';
list($nbr_erreurs, $nbr_vides,$total) = comparaison_grille($solution, $indexJeux);
$id_jeu = _request('id_jeu');
// on insere le resultat dans la base de donnee
if ($id_jeu){
include_spip('base/jeux_ajouter_resultat');
jeux_ajouter_resultat($id_jeu, $total-$nbr_erreurs-$nbr_vides, $total, "erreurs=$nbr_erreurs, vides=$nbr_vides");
}
// on retourne ce qu'on affiche
return '<div class="jeux_erreur">'
. (($nbr_erreurs==0)?_T('jeux:aucune_erreur'):(
($nbr_erreurs==1)?_T('jeux:une_erreur'):_T("jeux:n_erreurs", array('n'=>$nbr_erreurs))
))
. (($nbr_vides==0)?(($nbr_erreurs==0)?'. '._T('jeux:bravo'):''):(
($nbr_vides==1)?' - '._T('jeux:une_vide'):' - '._T("jeux:n_vides", array('n'=>$nbr_vides))
))
. '</div><br />';
}
// retourne une liste compactee alphabetique ou numerique
function jeux_listes_compacte($texte, $alpha) {
$tableau = preg_split("/[\r\n]+/", trim($texte));
$tableau2 = array(); $i=0; $a=_T('jeux:alphabet');
foreach ($tableau as $i=>$valeur) if (($valeur=trim($valeur))!='') {
$c=$alpha?$a[$i]:$i+1;
if ($valeur[strlen($valeur)-1]!='.') $valeur.='.';
if ($valeur!='-.') $tableau2[] = "<strong>$c.</strong>&nbsp;$valeur";
}
return implode(' ', $tableau2);
}
// definitions des mots croises
function affichage_definitions($horizontal, $vertical) {
if (jeux_config('compact')) return
'<p><strong>'._T('motscroises:horizontalement').'&nbsp;</strong>'
.jeux_listes_compacte($horizontal, jeux_config('horizontal')=='lettres')
.'<br /><strong>'._T('motscroises:verticalement').'&nbsp;</strong>'
.jeux_listes_compacte($vertical, jeux_config('vertical')=='lettres').'</p>';
else
$liste_horizontal = jeux_config('horizontal')=='chiffres'?'<div class="spip jeux_horizontal jeux_liste_chiffres">':'<div class="spip jeux_horizontal jeux_liste_lettres">';
$liste_horizontal .= '<h4 class="spip jeux_grille">'
$liste_horizontal .= '<h4 class="spip jeux_grille">'
._T('motscroises:horizontalement')."</h4>\n".jeux_listes($horizontal).'</div>';
$liste_vertical = jeux_config('vertical')=='lettres'?'<div class="spip jeux_vertical jeux_liste_lettres">':'<div class="spip jeux_vertical jeux_liste_chiffres">';
$liste_vertical .= '<h4 class="spip jeux_grille">'
$liste_vertical .= '<h4 class="spip jeux_grille">'
._T('motscroises:verticalement')."</h4>\n".jeux_listes($vertical).'</div>';
return $liste_horizontal.$liste_vertical;
}
// configuration par defaut : jeu_{mon_jeu}_init()
function jeux_mots_croises_init() {
return "
solution=oui // Afficher la solution ?
fondnoir=noir // couleur des cases noires
compact=non // Definitions en format compact ?
return $liste_horizontal.$liste_vertical;
}
// configuration par defaut : jeu_{mon_jeu}_init()
function jeux_mots_croises_init() {
return "
solution=oui // Afficher la solution ?
fondnoir=noir // couleur des cases noires
compact=non // Definitions en format compact ?
type=0 // types de grilles : 0 ou 1
vertical=chiffres // on met des chiffres en vertical
horizontal=lettres // on met des lettres en horizontal
";
}
// decode une grille de mots croises
// traitement du jeu : jeu_{mon_jeu}()
horizontal=lettres // on met des lettres en horizontal
";
}
// decode une grille de mots croises
// traitement du jeu : jeu_{mon_jeu}()
function jeux_mots_croises($texte, $indexJeux, $form=true) {
$horizontal = $vertical = $solution = $html = false;
$titre = _T('motscroises:titre');
// parcourir tous les #SEPARATEURS
$tableau = jeux_split_texte('mots_croises', $texte);
$horizontal = $vertical = $solution = $html = false;
$titre = _T('motscroises:titre');
// parcourir tous les #SEPARATEURS
$tableau = jeux_split_texte('mots_croises', $texte);
foreach($tableau as $i => $valeur) if ($i & 1) {
if ($valeur==_JEUX_TITRE) $titre = $tableau[$i+1];
elseif ($valeur==_JEUX_HORIZONTAL) $horizontal = $tableau[$i+1];
elseif ($valeur==_JEUX_VERTICAL) $vertical = $tableau[$i+1];
elseif ($valeur==_JEUX_SOLUTION) $solution = calcul_tableau_grille($tableau[$i+1]);
elseif ($valeur==_JEUX_TEXTE) $html .= $tableau[$i+1];
}
$affiche_solution = _request('affiche_solution_'.$indexJeux);
return '<div class="mots_croises">'
. calcul_erreurs_grille($solution, $indexJeux)
. affichage_grille_mc($solution, $indexJeux, $form)
. affichage_definitions($horizontal, $vertical)
// solution
. (($affiche_solution[0] == 1)? affichage_grille_mc($solution, $indexJeux, $form, true) : '')
. '</div><br class="jeux_nettoyeur"/>';
}
?>
if ($valeur==_JEUX_TITRE) $titre = $tableau[$i+1];
elseif ($valeur==_JEUX_HORIZONTAL) $horizontal = $tableau[$i+1];
elseif ($valeur==_JEUX_VERTICAL) $vertical = $tableau[$i+1];
elseif ($valeur==_JEUX_SOLUTION) $solution = calcul_tableau_grille($tableau[$i+1]);
elseif ($valeur==_JEUX_TEXTE) $html .= $tableau[$i+1];
}
return '<div class="mots_croises">'
. calcul_erreurs_grille($solution, $indexJeux)
. affichage_grille_mc($solution, $indexJeux, $form)
. affichage_definitions($horizontal, $vertical)
// solution
. (jeux_form_reponse($indexJeux, 'SOL') ? affichage_grille_mc($solution, $indexJeux, $form, true) : '')
. '</div><br class="jeux_nettoyeur"/>';
}
?>

139
jeux/qcm.php

@ -61,7 +61,6 @@ La gestion des points et des precisions est toujours possible :
*/
// configuration par defaut : jeu_{mon_jeu}_init()
function jeux_qcm_init() {
return "
@ -78,12 +77,11 @@ function jeux_qcm_init() {
}
// cette fonction remplit le tableau $qcms sur la question $indexQCM
function qcm_analyse_le_qcm($qcm, $indexQCM, $isQRM) {
global $qcms;
function qcm_analyse_le_qcm(&$qcms, $qcm, $indexQCM, $isQRM) {
$qcms[$indexQCM]['qrm'] = $isQRM;
$qcms['qrm'] |= $isQRM;
$lignes = preg_split('/[\r\n]+/', $qcm);
foreach ($lignes as $ligne) {
foreach($lignes as $ligne) {
$li = trim($ligne);
switch($li[0]){
case 'Q' : // extraire la question
@ -93,7 +91,7 @@ function qcm_analyse_le_qcm($qcm, $indexQCM, $isQRM) {
break;
case 'P' : // extraire une proposition
// Pour les precisions de la proposition...
list($reponse, $precision)=explode("|", $li, 2);
list($reponse, $precision) = explode("|", $li, 2);
// extraire le numero de la proposition et son contenu
preg_match(',^P(\d*)(.*)$,', $reponse, $regs);
$indexProposition = intval($regs[1]);
@ -152,23 +150,13 @@ function qcm_les_points($phrase, $points, $veto=false) {
return $phrase;
}
function qcm_un_trou($nomVarSelect, $indexQCM) {
global $qcms;
if (($sizeInput = intval(jeux_config('trou')))==0)
foreach($qcms[$indexQCM]['propositions'] as $mot) $sizeInput = max($sizeInput, strlen($mot));
$temp = $_POST[$nomVarSelect] = trim($_POST[$nomVarSelect]);
$prop = jeux_minuscules($temp);
return " &nbsp; &nbsp; &nbsp;<input name=\"$nomVarSelect\" class=\"jeux_input qcm_input\" size=\"$sizeInput\" type=\"text\" /> ";
}
function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoints) {
global $qcms, $qcm_score, $qcm_score_detaille;
function qcm_affiche_la_question(&$qcms, $indexJeux, $indexQCM, $gestionPoints) {
$indexQCM_1 = $indexQCM + 1;
if (!$qcms[$indexQCM]['nbpropositions'] || !$qcms[$indexQCM]['maxScore'])
return "<div class=\"jeux_question\">".definir_puce()._T('jeux:erreur_syntaxe').'</div>';
return '<div class="jeux_question">'.definir_puce()._T('jeux:erreur_syntaxe').'</div>';
// Initialisation du code a retourner
$nomVarSelect = "var{$indexJeux}_Q{$indexQCM}";
list($idInput, $nameInput) = jeux_idname($indexJeux, $indexQCM, 'Q');
$question = trim(str_replace('&nbsp;', ' ', $qcms[$indexQCM]['question']));
$trou = $qcms[$indexQCM]['nbpropositions']==1;
$qrm = $qcms[$indexQCM]['qrm'];
@ -180,41 +168,37 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
$question = qcm_les_points($question, $pointsQ);
} else $pointsQ = 1;
$codeHTML = "<div class=\"qcm_element \"><div class=\"jeux_question\">".definir_puce().$question.'</div>';
if (!$corriger){
// affichage sans correction :
$codeHTML.="\n<div class=\"qcm_proposition\">";
$codeHTML = "<div class='qcm_element'><div class='jeux_question'>".definir_puce().$question.'</div>';
if (!jeux_form_correction($indexJeux)){
// affichage du jeu sans correction
$codeHTML .= "\n<div class='qcm_proposition'>";
if ($trou) {
$codeHTML.=qcm_un_trou($nomVarSelect, $indexQCM);
if (($sizeInput = intval(jeux_config('trou')))==0)
foreach($qcms[$indexQCM]['propositions'] as $mot) $sizeInput = max($sizeInput, strlen($mot));
$prop = jeux_minuscules($temp);
$codeHTML .= " &nbsp; &nbsp; &nbsp;<input name='$nameInput' id='$idInput' class='jeux_input qcm_input' size='$sizeInput' type='text' /> ";
} elseif ($qrm) {
// cases a cocher
foreach($qcms[$indexQCM]['propositions'] as $i=>$valeur)
$codeHTML.='<input type="checkbox" class="jeux_cocher qcm_cocher" name="'.$nomVarSelect
. '[]" value="'.$i.'" id="'.$nomVarSelect.$i.'" /><label for="'.$nomVarSelect.$i.'">&nbsp;'
. $valeur.'</label>'
. ($i % $nbcol?' &nbsp; ':'<br />');
$codeHTML .= "<input type='checkbox' class='jeux_cocher qcm_cocher' name='{$nameInput}[]' value='$i' id='{$idInput}-$i' /><label for='{$idInput}-$i'>&nbsp;" . $valeur.'</label>' . ($i % $nbcol?' &nbsp; ':'<br />');
// S'il y a trop de choix, utiliser une liste a la place des boutons radio
} elseif ($qcms[$indexQCM]['nbpropositions']>jeux_config('max_radios')) {
$codeHTML.='<select name="'.$nomVarSelect.'" class="qcm_select"><option value="">'._T('jeux:votre_choix').'</option>';
foreach($qcms[$indexQCM]['propositions'] as $i=>$valeur) $codeHTML.="<option value=\"$i\">$valeur</option>";
$codeHTML.='</select>';
$codeHTML .= "<select name='$nameInput' id='$idInput' class='qcm_select'><option value=''>"._T('jeux:votre_choix').'</option>';
foreach($qcms[$indexQCM]['propositions'] as $i=>$valeur) $codeHTML.="<option value='$i'>$valeur</option>";
$codeHTML .= '</select>';
} else {
// boutons radio
foreach($qcms[$indexQCM]['propositions'] as $i=>$valeur)
$codeHTML.='<input type="radio" class="jeux_radio qcm_radio" name="'.$nomVarSelect
. '" value="'.$i.'" id="'.$nomVarSelect.$i.'" /><label for="'.$nomVarSelect.$i.'">&nbsp;'
. $valeur.'</label>'
. ($i % $nbcol?' &nbsp; ':'<br />');
$codeHTML .= "<input type='radio' class='jeux_radio qcm_radio' name='$nameInput' value='$i' id='{$idInput}-$i' /><label for='{$idInput}-$i'>&nbsp;$valeur</label>" . ($i % $nbcol?' &nbsp; ':'<br />');
}
$codeHTML.="</div><br /></div>";
} // fin du cas sans correction
$codeHTML .= '</div><br /></div>';
// Sinon afficher la correction
else {
$reponse = $_POST[$nomVarSelect];
if (!is_array($reponse)) $reponse=trim($reponse);
} else {
// affichage du jeu avec correction
$reponse = jeux_form_reponse($indexJeux, $indexQCM, 'Q');
$bonneReponse = false; $qrm_score = 0;
if ($reponse) {
if($reponse) {
// chaque question est-elle corrigee ?
$affiche_correction = jeux_config('corrections');
// les points de la reponse donnee...
@ -226,24 +210,24 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
if(($p=$qcms[$indexQCM]['points'][$trou?0:$reponse])!==false) $pointsR += $p;
}
$intro=$trou?_T('jeux:votre_reponse'):_T('jeux:votre_choix');
$intro = $trou?_T('jeux:votre_reponse'):_T('jeux:votre_choix');
// question a reponse simple
if (!$qrm) {
// ici : une question a reponse simple
// la reponse donnee & precision des points eventuels de la mauvaise reponse...
$codeHTML.='<div class="qcm_reponse">'
.($pointsR===$pointsQ?$intro:qcm_les_points($intro, $pointsR, !$affiche_correction))
.($trou?$reponse:$qcms[$indexQCM]['propositions'][$reponse])
.'</div>';
$codeHTML .= '<div class="qcm_reponse">'
. ($pointsR===$pointsQ?$intro:qcm_les_points($intro, $pointsR, !$affiche_correction))
. ($trou?$reponse:$qcms[$indexQCM]['propositions'][$reponse])
. '</div>';
// bonne reponse
$bonneReponse = ($trou && jeux_in_liste($reponse, $qcms[$indexQCM]['propositions']))
|| ($qcms[$indexQCM]['bonnesreponses'][$reponse]==1);
// si ce n'est pas un trou, donner les points de la reponse quoiqu'il arrive
if (!$trou || $bonneReponse) $qcm_score += $pointsR;
if (!$trou || $bonneReponse) $qcms['score_du_qcm'] += $pointsR;
// renseigner le resultat detaille
$qcm_score_detaille[] = $trou?"T$indexQCM_1:$reponse:".($bonneReponse?$pointsR:'0')
$qcms['score_detaille'][] = $trou?"T$indexQCM_1:$reponse:".($bonneReponse?$pointsR:'0')
:"Q$indexQCM_1:R$reponse:$pointsR";
if($affiche_correction) {
@ -254,9 +238,8 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
$prec = $qcms[$indexQCM]['precisions'][$trou?0:$reponse];
if (strlen($prec)) $codeHTML.="<div class=\"qcm_precision\">$prec</div>";
}
// question a reponses multiples
} else foreach($reponse as $r) {
// ici : une question a reponses multiples
// la reponse donnee & precision des points de la mauvaise reponse...
$codeHTML.='<div class="qcm_reponse">'
.qcm_les_points($intro, $qcms[$indexQCM]['points'][$r], !$affiche_correction)
@ -267,8 +250,8 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
$bonneReponse = $qcms[$indexQCM]['bonnesreponses'][$r]==1;
// donner les points de la reponse quoiqu'il arrive
$qcm_score += $qcms[$indexQCM]['points'][$r];
$qcm_score_detaille[] = "Q$indexQCM_1:R$r:".intval($qcms[$indexQCM]['points'][$r]);
$qcms['score_du_qcm'] += $qcms[$indexQCM]['points'][$r];
$qcms['score_detaille'][] = "Q$indexQCM_1:R$r:".intval($qcms[$indexQCM]['points'][$r]);
$qrm_score += $qcms[$indexQCM]['points'][$r];
if($affiche_correction) {
@ -279,12 +262,12 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
$prec = $qcms[$indexQCM]['precisions'][$r];
if (strlen($prec)) $codeHTML.="<div class=\"qcm_precision\">$prec</div>";
}
}
} // foreach($reponse)
// pas de reponse postee...
} else {
$codeHTML.='<div class="qcm_correction_null">'._T('jeux:reponseNulle').'</div>';
$qcm_score_detaille[] = "Q$indexQCM_1:R?:0";
$qcms['score_detaille'][] = "Q$indexQCM_1:R?:0";
}
// afficher les bonnes reponses si la configuration l'autorise
@ -324,15 +307,14 @@ function qcm_affiche_la_question($indexJeux, $indexQCM, $corriger, $gestionPoint
return $codeHTML;
}
function qcm_inserer_les_qcm(&$chaine, $indexJeux, $gestionPoints) {
global $qcms;
function qcm_inserer_les_qcm(&$qcms, $indexJeux, &$chaine, $gestionPoints) {
if (preg_match(',<ATTENTE_QCM>(\d+)</ATTENTE_QCM>,', $chaine, $regs)) {
$indexQCM = intval($regs[1]);
list($texteAvant, $texteApres) = explode($regs[0], $chaine, 2);
$chaine = $texteAvant.jeux_rem('QCM-DEBUT', $indexQCM)
. qcm_affiche_la_question($indexJeux, $indexQCM, isset($_POST["var_correction_".$indexJeux]), $gestionPoints)
. qcm_affiche_la_question($qcms, $indexJeux, $indexQCM, $gestionPoints)
. jeux_rem('QCM-FIN', $indexQCM)
. qcm_inserer_les_qcm($texteApres, $indexJeux, $gestionPoints);
. qcm_inserer_les_qcm($qcms, $indexJeux, $texteApres, $gestionPoints);
}
return $chaine;
}
@ -340,15 +322,17 @@ function qcm_inserer_les_qcm(&$chaine, $indexJeux, $gestionPoints) {
// traitement du jeu : jeu_{mon_jeu}()
function jeux_qcm($texte, $indexJeux, $form=true) {
// initialisation
global $qcms, $qcm_score, $qcm_score_detaille;
$qcms = array(); $indexQCM = $qcm_score = 0;
$qcm_score_detaille = array();
$qcms['pointsTrouves'] = $qcms['nbQuestions'] = $qcms['totalScore'] = $qcms['totalPropositions'] = 0;
$qcms_[$indexJeux] = array(
'pointsTrouves' =>0, 'nbQuestions' =>0,
'totalScore' => 0, 'totalPropositions' => 0,
'score_du_qcm' => 0, 'score_detaille' => array()
);
$qcms = &$qcms_[$indexJeux];
$indexQCM = 0;
$titre = $horizontal = $vertical = $solution = $html = $categ_score = false;
$id_jeu = _request('id_jeu');
// parcourir tous les #SEPARATEURS
// parcourir tous les #SEPARATEURS, remplir $tableau et mettre a jour $indexJeux si ajax
$tableau = jeux_split_texte('qcm', $texte);
foreach($tableau as $i => $valeur) if ($i & 1) {
if ($valeur==_JEUX_TITRE) $titre = $tableau[$i+1];
@ -356,7 +340,7 @@ function jeux_qcm($texte, $indexJeux, $form=true) {
// remplacement des qcm par : <ATTENTE_QCM>ii</ATTENTE_QCM>
$html .= "<ATTENTE_QCM>$indexQCM</ATTENTE_QCM>";
// analyser le QCM
qcm_analyse_le_qcm($tableau[$i+1], $indexQCM, $valeur==_JEUX_QRM);
qcm_analyse_le_qcm($qcms, $tableau[$i+1], $indexQCM, $valeur==_JEUX_QRM);
$qcms['totalPropositions'] += count($qcms[$indexQCM]['propositions']);
$qcms['totalScore'] += $qcms[$indexQCM]['maxScore'];
$indexQCM++;
@ -369,27 +353,26 @@ function jeux_qcm($texte, $indexJeux, $form=true) {
$gestionPoints = $qcms['qrm'] || $qcms['pointsTrouves'];
// reinserer les qcms mis en forme
$texte = qcm_inserer_les_qcm($html, $indexJeux, $gestionPoints);
$texte = qcm_inserer_les_qcm($qcms, $indexJeux, $html, $gestionPoints);
// calcul des extremes
$tete = '<div class="jeux_cadre qcm">'.($titre?'<div class="jeux_titre qcm_titre">'.$titre.'<hr /></div>':'');
$pied = '';
if (!isset($_POST["var_correction_".$indexJeux])) {
if (jeux_form_correction($indexJeux)) {
// mode correction
$pied = jeux_afficher_score($qcms['score_du_qcm'], $qcms['totalScore'], $id_jeu, join(', ', $qcms['score_detaille']), $categ_score);
if($form) $pied .= jeux_bouton(jeux_config('bouton_refaire'), $id_jeu, $indexJeux);
} else {
// mode formulaire
if($form) {
$pied = '<br />'.jeux_bouton(jeux_config('bouton_corriger'), $id_jeu).jeux_form_fin();
$pied = '<br />' . jeux_bouton(jeux_config('bouton_corriger'), $id_jeu) . jeux_form_fin();
$tete .= jeux_form_debut('qcm', $indexJeux, '', 'post', self());
}
} else {
$pied = jeux_afficher_score($qcm_score, $qcms['totalScore'], $id_jeu, join(', ', $qcm_score_detaille), $categ_score);
if($form) $pied .= jeux_bouton(jeux_config('bouton_refaire'), $id_jeu, $indexJeux);
}
// ajout du javascript s'il faut afficher une par une
if (jeux_config('une_par_une'))
$js = '<script type="text/javascript">qcm_affichage_une_par_une();</script>';
else
$js = '';
$js = jeux_config('une_par_une')?'<script type="text/javascript">qcm_affichage_une_par_une();</script>':'';
unset($qcms, $qcm_score, $qcm_score_detaille);
unset($qcms_[$indexJeux]);
return $tete.$texte.$pied.'</div>'.$js;
}

410
jeux/sudoku.php

@ -1,206 +1,206 @@
<?php
if (!defined("_ECRIRE_INC_VERSION")) return;
#---------------------------------------------------#
# Plugin : jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GPL #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
/*
Insere une grille de mots croises dans vos articles !
-----------------------------------------------------
separateurs obligatoires : [sudoku], [solution]
separateurs optionnels : [titre], [texte], [config]
parametres de configurations par defaut :
solution=oui // Afficher la solution ?
regle=non // Afficher la regle du jeu ?
Tailles de sudoku acceptees : 4x4, 6x6, 9x9
Exemple de syntaxe dans l'article :
-----------------------------------
<jeux>
[sudoku]
-2
--5--4
3--5
----3
--1--6
6--1
[solution]
423615
165324
314562
256431
531246
642153
</jeux>
*/
// affiche la grille de sudoku, en format solution au cas ou...
function affichage_sudoku($tableau_sudoku, $indexJeux, $form=true, $solution=false){
// les variables de la grille
$largeur = $hauteur = sizeof($tableau_sudoku);
switch ($largeur) {
case 4 : $interh = $interv = '24'; $li = $lj = 2; break;
case 6 : $interh = '36'; $interv = '246'; $lj = 3; $li = 2; break;
case 9 : $interh = $interv = '369'; $li = $lj = 3; break;
default : return '<div class="jeux_erreur">'._T('jeux:erreur_taille_grille').' : </div>' ;
}
$grille='';
// entetes : formulaire + grille
$grille .= (!$solution)
? ($form?jeux_form_debut('sudoku', $indexJeux, 'jeux_grille', 'post', self()):'')
: '<div class="jeux_solution">'._T('jeux:solution').' : </div>' ;
$grille .= '<table class="jeux_grille sudoku" cellspacing="0" border="0" summary="'
. _T('sudoku:table_summary',Array('hauteur'=>$hauteur,'largeur'=>$largeur)) . "\">\n";
// debut affichage des lignes
foreach($tableau_sudoku as $ligne => $contenu_ligne){
$ligne++;
$grille .= "\t<tr>\n\t";
foreach ($contenu_ligne as $colonne =>$cellule){
$colonne++;
$class = preg_match(",[$interh],", $colonne)?(preg_match(",[$interv],", $ligne)?' class="jeux_bas jeux_droite"':' class="jeux_droite"'):(preg_match(",[$interv],", $ligne)?' class="jeux_bas"':'');
// : ($ligne==$hauteur?($colonne==$largeur?' class="jeux_bas jeux_droite"':' class="jeux_bas"'):($colonne==$largeur?' class="jeux_droite"':''))
// );
// s'il s'agit pas d'un espace
if ($cellule != '-')
$grille .= "\t\t<td$class><strong>$cellule</strong></td>\n";
else if ($solution)
$grille .= "\t\t<td$class>$cellule</td>\n" ;
else {
$name = 'GR'.$indexJeux.'x'.$colonne.'x'.$ligne;
$grille .= "\t\t<td$class><label for=\"$name\">"
._T('jeux:ligne_n',Array('n'=>$ligne)).';'
._T('jeux:colonne_n',Array('n'=>$colonne)).'</label>'
. '<input type="text" maxlength="1" '
. ((isset($_POST[$name]) and $_POST[$name]!='')? 'value="'.$_POST[$name]:'')
.'" name="'.$name.'" id="'.$name.'" />'
. "</td>\n" ;
}
} // foreach
$grille = $grille."\t</tr>\n";}
// fin affichage des lignes
$grille.="</table>\n";
if (!$solution) $grille .=
(jeux_config('regle')?'<div class="jeux_regle">'.definir_puce()._T('sudoku:regle',Array('hauteur'=>$li,'largeur'=>$lj, 'max'=>$largeur)).'</div>' : '')
.(jeux_config('solution')?"<p><input id=\"affiche_solution_$indexJeux\" name=\"affiche_solution_{$indexJeux}[]\" type=\"checkbox\" class=\"jeux_cocher\" value=\"1\" /><label for=\"affiche_solution_$indexJeux\" >"._T('jeux:afficher_solution')."</label></p>\n":'')
.'<p><input type="submit" value="'._T('jeux:verifier_validite')."\" name=\"bouton_envoi_$indexJeux\" /></p>"
.($form?jeux_form_fin():'');
return $grille;
}
// dechiffre le code source de la grille
function calcul_tableau_sudoku($texte){
$texte = preg_replace(",\s*[\r\n]+\s*,", "\n", trim($texte));
// arggh les raccourcis SPIP... TODO : voir pkoi (1.93)
$texte = str_replace('&mdash;', '--', $texte);
$tableau = preg_split("/\n/", $texte);
$hauteur = count($tableau);
foreach ($tableau as $i=>$valeur) {
if (strlen($valeur)) $valeur .= str_repeat('-', $hauteur-strlen($valeur));
$tableau[$i] = preg_split('//', trim($valeur), -1, PREG_SPLIT_NO_EMPTY);
}
return $tableau;
}
// valide si la lsite est composee de chiffres tous differents
function sudoku_valide_liste($liste) {
// echo"<br>", join(', ',$liste);
$chiffres = "123456789";
foreach($liste as $cell) if ($cell!='-') {
if ($chiffres[$cell]=='*') return false; else $chiffres[$cell]='*';
}
// echo ":ok";
return true;
}
// valide si la grille de sudoku est valide
function sudoku_valide_grille($tableau_sudoku) {
$taille = sizeof($tableau_sudoku);
foreach($tableau_sudoku as $ligne) if (!sudoku_valide_liste($ligne)) return false;
for ($i=0; $i<$taille; $i++) {
$colonne=false;
foreach($tableau_sudoku as $ligne) $colonne[] = $ligne[$i];
if (!sudoku_valide_liste($colonne)) return false;
}
switch ($taille) {
case 4 : $ii = 2; $li = 2; $ij = 2; $lj = 2; break;
case 6 : $ii = 3; $li = 2; $ij = 2; $lj = 3; break;
case 9 : $ii = 3; $li = 3; $ij = 3; $lj = 3; break;
}
for ($i=0; $i<$ii; $i++) for ($j=0; $j<$ij; $j++) {
$zone=false;
for ($x=0; $x<$li; $x++) for ($y=0; $y<$lj; $y++) $zone[] = $tableau_sudoku[$i*$li+$x][$j*$lj+$y];
if (!sudoku_valide_liste($zone)) return false;
}
return true;
}
// retourne les erreurs et les cases vides eventuelles
function sudoku_validite($tableau_sudoku, $solution, $indexJeux) {
$vides=0;
foreach($tableau_sudoku as $ligne => $contenu_ligne) {
foreach ($contenu_ligne as $colonne => $cellule) {
$input = trim(_request('GR'.$indexJeux.'x'.($colonne+1).'x'.($ligne+1)));
if ($input=='' && $cellule=='-') $vides++;
if ($input!='' && $cellule=='-') $tableau_sudoku[$ligne][$colonne] = $input;
}
}
return array(sudoku_valide_grille($tableau_sudoku), $vides);
}
// renvoie la validite et le nombre de cases vides
function calcul_erreurs_sudoku($tableau_sudoku, $solution, $indexJeux) {
if (_request("bouton_envoi_$indexJeux") == '') return '';
else {
list($valide, $nbr_vides) = sudoku_validite($tableau_sudoku, $solution, $indexJeux);
return '<div class="jeux_erreur">'
. _T('jeux:grille_'.($valide?'':'in').'valide')
. (($nbr_vides==0)?(($nbr_erreurs==0)?'. '._T('jeux:bravo'):''):(
($nbr_vides==1)?' - '._T('jeux:une_vide'):' - '._T("jeux:n_vides", Array('n'=>$nbr_vides))
))
. '</div><br />';
}
}
// configuration par defaut : jeu_{mon_jeu}_init()
function jeux_sudoku_init() {
return "
solution=oui // Afficher la solution ?
regle=non // Afficher la regle ?
";
}
// decode une grille de sudoku
function jeux_sudoku($texte, $indexJeux, $form=true) {
$sudoku = $solution = $titre = $html = false;
// parcourir tous les #SEPARATEURS
$tableau = jeux_split_texte('sudoku', $texte);
foreach($tableau as $i => $valeur) if ($i & 1) {
if ($valeur==_JEUX_TITRE) $titre = $tableau[$i+1];
elseif ($valeur==_JEUX_SUDOKU) $sudoku = calcul_tableau_sudoku($tableau[$i+1]);
elseif ($valeur==_JEUX_SOLUTION) $solution = calcul_tableau_sudoku($tableau[$i+1]);
elseif ($valeur==_JEUX_TEXTE) $html .= $tableau[$i+1];
}
return ($titre?"<div class=\"jeux_titre sudoku_titre\">$titre</div>":'')
. calcul_erreurs_sudoku($sudoku, $solution, $indexJeux)
. affichage_sudoku($sudoku, $indexJeux, $form)
// solution
. (($_POST['affiche_solution_'.$indexJeux][0] == 1)? affichage_sudoku($solution, $indexJeux, $form, true) : '');
}
?>
if (!defined("_ECRIRE_INC_VERSION")) return;
#---------------------------------------------------#
# Plugin : jeux #
# Auteur : Patrice Vanneufville, 2006 #
# Contact : patrice¡.!vanneufville¡@!laposte¡.!net #
# Licence : GPL #
#--------------------------------------------------------------------------#
# Documentation : http://www.spip-contrib.net/Des-jeux-dans-vos-articles #
#--------------------------------------------------------------------------#
/*
Insere une grille de mots croises dans vos articles !
-----------------------------------------------------
separateurs obligatoires : [sudoku], [solution]
separateurs optionnels : [titre], [texte], [config]
parametres de configurations par defaut :
solution=oui // Afficher la solution ?
regle=non // Afficher la regle du jeu ?
Tailles de sudoku acceptees : 4x4, 6x6, 9x9
Exemple de syntaxe dans l'article :
-----------------------------------
<jeux>
[sudoku]
-2
--5--4
3--5
----3
--1--6
6--1
[solution]
423615
165324
314562
256431
531246
642153
</jeux>
*/
// affiche la grille de sudoku, en format solution au cas ou...
function affichage_sudoku($tableau_sudoku, $indexJeux, $form=true, $solution=false){
// les variables de la grille
$largeur = $hauteur = sizeof($tableau_sudoku);
switch ($largeur) {
case 4 : $interh = $interv = '24'; $li = $lj = 2; break;
case 6 : $interh = '36'; $interv = '246'; $lj = 3; $li = 2; break;
case 9 : $interh = $interv = '369'; $li = $lj = 3; break;
default : return '<div class="jeux_erreur">'._T('jeux:erreur_taille_grille').' : </div>' ;
}
$grille='';
// entetes : formulaire + grille
$grille .= (!$solution)
? ($form?jeux_form_debut('sudoku', $indexJeux, 'jeux_grille', 'post', self()):'')
: '<div class="jeux_solution">'._T('jeux:solution').' : </div>' ;
$grille .= '<table class="jeux_grille sudoku" cellspacing="0" border="0" summary="'
. _T('sudoku:table_summary',Array('hauteur'=>$hauteur,'largeur'=>$largeur)) . "\">\n";
// debut affichage des lignes
foreach($tableau_sudoku as $ligne => $contenu_ligne){
$ligne++;
$grille .= "\t<tr>\n\t";
foreach ($contenu_ligne as $colonne =>$cellule){
$colonne++;
$class = preg_match(",[$interh],", $colonne)?(preg_match(",[$interv],", $ligne)?' class="jeux_bas jeux_droite"':' class="jeux_droite"'):(preg_match(",[$interv],", $ligne)?' class="jeux_bas"':'');
// : ($ligne==$hauteur?($colonne==$largeur?' class="jeux_bas jeux_droite"':' class="jeux_bas"'):($colonne==$largeur?' class="jeux_droite"':''))
// );
// s'il s'agit pas d'un espace
if ($cellule != '-')
$grille .= "\t\t<td$class><strong>$cellule</strong></td>\n";
else if ($solution)
$grille .= "\t\t<td$class>$cellule</td>\n" ;
else {
list($id, $name) = jeux_idname($indexJeux, $colonne, 'C', $ligne, 'L');
$value = jeux_form_reponse($indexJeux, $colonne, 'C', $ligne, 'L');
$value = strlen($value)?' value="'.$value.'"':'';
$grille .= "\t\t<td$class><label for=\"$name\">"
._T('jeux:ligne_n',Array('n'=>$ligne)).';'
._T('jeux:colonne_n',Array('n'=>$colonne)).'</label>'
. "<input type='text' maxlength='1'$value name='$name' id='$id' /></td>\n" ;
}
} // foreach
$grille = $grille."\t</tr>\n";}
// fin affichage des lignes
$grille.="</table>\n";
if (!$solution){
list($id, $name) = jeux_idname($indexJeux, 'SOL');
$grille .=
(jeux_config('regle')?'<div class="jeux_regle">'.definir_puce()._T('sudoku:regle',Array('hauteur'=>$li,'largeur'=>$lj, 'max'=>$largeur)).'</div>' : '')
.(jeux_config('solution')?"<p><input id='$id' name='$name' type='checkbox' class='jeux_cocher' value='1' /><label for='$id' >"
._T('jeux:afficher_solution')."</label></p>\n":'')
.'<p><input type="submit" value="'._T('jeux:verifier_validite')."\" name='submit' /></p>"
.($form?jeux_form_fin():'');
}
return $grille;
}
// dechiffre le code source de la grille
function calcul_tableau_sudoku($texte){
$texte = preg_replace(",\s*[\r\n]+\s*,", "\n", trim($texte));
// arggh les raccourcis SPIP... TODO : voir pkoi (1.93)
$texte = str_replace('&mdash;', '--', $texte);
$tableau = preg_split("/\n/", $texte);
$hauteur = count($tableau);
foreach ($tableau as $i=>$valeur) {
if (strlen($valeur)) $valeur .= str_repeat('-', $hauteur-strlen($valeur));
$tableau[$i] = preg_split('//', trim($valeur), -1, PREG_SPLIT_NO_EMPTY);
}
return $tableau;
}
// valide si la lsite est composee de chiffres tous differents
function sudoku_valide_liste($liste) {
// echo"<br>", join(', ',$liste);
$chiffres = "123456789";
foreach($liste as $cell) if ($cell!='-') {
if ($chiffres[$cell]=='*') return false; else $chiffres[$cell]='*';
}
// echo ":ok";
return true;
}
// valide si la grille de sudoku est valide
function sudoku_valide_grille($tableau_sudoku) {
$taille = sizeof($tableau_sudoku);
foreach($tableau_sudoku as $ligne) if (!sudoku_valide_liste($ligne)) return false;
for ($i=0; $i<$taille; $i++) {
$colonne=false;
foreach($tableau_sudoku as $ligne) $colonne[] = $ligne[$i];
if (!sudoku_valide_liste($colonne)) return false;
}
switch ($taille) {
case 4 : $ii = 2; $li = 2; $ij = 2; $lj = 2; break;
case 6 : $ii = 3; $li = 2; $ij = 2; $lj = 3; break;
case 9 : $ii = 3; $li = 3; $ij = 3; $lj = 3; break;
}
for ($i=0; $i<$ii; $i++) for ($j=0; $j<$ij; $j++) {
$zone=false;
for ($x=0; $x<$li; $x++) for ($y=0; $y<$lj; $y++) $zone[] = $tableau_sudoku[$i*$li+$x][$j*$lj+$y];
if (!sudoku_valide_liste($zone)) return false;
}
return true;
}
// retourne les erreurs et les cases vides eventuelles
function sudoku_validite($tableau_sudoku, $solution, $indexJeux) {
$vides=0;
foreach($tableau_sudoku as $ligne => $contenu_ligne) {
foreach ($contenu_ligne as $colonne => $cellule) {
$input = jeux_form_reponse($indexJeux, $colonne+1, 'C', $ligne+1, 'L');
if ($input=='' && $cellule=='-') $vides++;
if ($input!='' && $cellule=='-') $tableau_sudoku[$ligne][$colonne] = $input;
}
}
return array(sudoku_valide_grille($tableau_sudoku), $vides);
}
// renvoie la validite et le nombre de cases vides
function calcul_erreurs_sudoku($tableau_sudoku, $solution, $indexJeux) {
if (!jeux_form_correction($indexJeux)) return '';
list($valide, $nbr_vides) = sudoku_validite($tableau_sudoku, $solution, $indexJeux);
return '<div class="jeux_erreur">'
. _T('jeux:grille_'.($valide?'':'in').'valide')
. (($nbr_vides==0)?(($nbr_erreurs==0)?'. '._T('jeux:bravo'):''):(
($nbr_vides==1)?' - '._T('jeux:une_vide'):' - '._T("jeux:n_vides", Array('n'=>$nbr_vides))
))
. '</div><br />';
}
// configuration par defaut : jeu_{mon_jeu}_init()
function jeux_sudoku_init() {
return "
solution=oui // Afficher la solution ?
regle=non // Afficher la regle ?
";
}
// decode une grille de sudoku
function jeux_sudoku($texte, $indexJeux, $form=true) {
$sudoku = $solution = $titre = $html = false;
// parcourir tous les #SEPARATEURS
$tableau = jeux_split_texte('sudoku', $texte);
foreach($tableau as $i => $valeur) if ($i & 1) {
if ($valeur==_JEUX_TITRE) $titre = $tableau[$i+1];
elseif ($valeur==_JEUX_SUDOKU) $sudoku = calcul_tableau_sudoku($tableau[$i+1]);
elseif ($valeur==_JEUX_SOLUTION) $solution = calcul_tableau_sudoku($tableau[$i+1]);
elseif ($valeur==_JEUX_TEXTE) $html .= $tableau[$i+1];
}
return ($titre?"<div class=\"jeux_titre sudoku_titre\">$titre</div>":'')
. calcul_erreurs_sudoku($sudoku, $solution, $indexJeux)
. affichage_sudoku($sudoku, $indexJeux, $form)
// solution
. (jeux_form_reponse($indexJeux, 'SOL') ? affichage_sudoku($solution, $indexJeux, $form, true) : '');
}
?>

64
jeux/trous.php

@ -76,17 +76,15 @@ function jeux_trous_init() {
";
}
function trous_inserer_le_trou($indexJeux, $indexTrou, $size, $corriger) {
global $propositionsTROUS, $scoreTROUS, $score_detailTROUS;
function trous_inserer_le_trou(&$trous, $indexJeux, $indexTrou, $size) {
// Initialisation du code a retourner
$nomVarSelect = "var{$indexJeux}_T{$indexTrou}";
$mots = $propositionsTROUS[$indexTrou];
$prop = trim($_POST[$nomVarSelect]);
$oups = $disab = $color = '';
$mots = $trous['propositions'][$indexTrou];
$prop = $oups = $disab = $color = '';
// en cas de correction
if($corriger) {
if(jeux_form_correction($indexJeux)) {
$prop = jeux_form_reponse($indexJeux, $indexTrou, 'T');
$ok = strlen($prop) && jeux_in_liste($prop, $mots);
if($ok) ++$scoreTROUS;
if($ok) ++$trous['score'];
if(jeux_config('couleurs')) $color = $ok?' juste':' faux';
if(!$ok && jeux_config('solution')) {
if(!strlen($prop)) {
@ -99,24 +97,24 @@ function trous_inserer_le_trou($indexJeux, $indexTrou, $size, $corriger) {
}
//$solution = ' <span class="juste">('.trous_liste_reponses($mots).')</span> ';
// on renseigne le resultat detaille
$score_detailTROUS[] = 'T'.($indexTrou+1).":$prop:".($ok?'1':'0');
$trous['score_detaille'][] = 'T'.($indexTrou+1).":$prop:".($ok?'1':'0');
$disab = " disabled='disabled'";
}
$codeHTML = "<input name='$nomVarSelect' class='jeux_input trous$color' size='$size' type='text'$disab' value=\"$prop\" />";
// if($corriger) $codeHTML .= '(T'.($indexTrou+1).":$prop/".$GLOBALS['meta']['charset']."[".join('|',$mots)."]:".($ok?'1':'0').'pt)';
list($idInput, $nameInput) = jeux_idname($indexJeux, $indexTrou, 'T');
$codeHTML = "<input id='sidInput' name='$nameInput' class='jeux_input trous$color' size='$size' type='text'$disab' value=\"$prop\" />";
// if(jeux_form_correction($indexJeux)) $codeHTML .= '(T'.($indexTrou+1).":$prop/".$GLOBALS['meta']['charset']."[".join('|',$mots)."]:".($ok?'1':'0').'pt)';
return $oups . $codeHTML;
}
function trous_inserer_les_trous($chaine, $indexJeux) {
global $propositionsTROUS;
function trous_inserer_les_trous(&$trous, $chaine, $indexJeux) {
if (preg_match(',<ATTENTE_TROU>([0-9]+)</ATTENTE_TROU>,', $chaine, $regs)) {
$indexTROU = intval($regs[1]);
list($texteAvant, $texteApres) = explode($regs[0], $chaine, 2);
$texteApres = trous_inserer_les_trous($texteApres, $indexJeux);
$texteApres = trous_inserer_les_trous($trous, $texteApres, $indexJeux);
if (($sizeInput = intval(jeux_config('taille')))==0)
foreach($propositionsTROUS as $trou) foreach($trou as $mot) $sizeInput = max($sizeInput, strlen($mot));
foreach($trous['propositions'] as $trou) foreach($trou as $mot) $sizeInput = max($sizeInput, strlen($mot));
$chaine = $texteAvant.jeux_rem('TROU-DEBUT', $indexTROU, '', 'span')
. trous_inserer_le_trou($indexJeux, $indexTROU, $sizeInput, isset($_POST["var_correction_".$indexJeux]))
. trous_inserer_le_trou($trous, $indexJeux, $indexTROU, $sizeInput)
. jeux_rem('TROU-FIN', $indexTROU, '', 'span')
. $texteApres;
}
@ -125,9 +123,8 @@ function trous_inserer_les_trous($chaine, $indexJeux) {
// renvoyer l'ensemble des solutions dans le desordre...
// si plusieurs solutions sont possibles, seule la premiere est retenue
function trous_afficher_indices($indexJeux) {
global $propositionsTROUS;
foreach ($propositionsTROUS as $prop)
function trous_afficher_indices(&$trous) {
foreach ($trous['propositions'] as $prop)
$indices[] = preg_match(',(.*)/M$,', $prop[0], $reg)?$reg[1]:$prop[0];
shuffle($indices);
return '<div class="jeux_indices"><html>'.str_replace(array("'",'&#8217;'),"&#039;",charset2unicode(join(' -&nbsp;', $indices))).'</html></div>';
@ -145,11 +142,12 @@ function trous_liste_reponses($mots) {
// traitement du jeu : jeu_{mon_jeu}()
function jeux_trous($texte, $indexJeux, $form=true) {
global $propositionsTROUS, $scoreTROUS, $score_detailTROUS;
$titre = $html = false;
$indexTrou = $scoreTROUS = 0;
$score_detailTROUS = array();
$trous_[$indexJeux] = array(
'propositions'=> array(),
'score' => 0, 'score_detaille' => array()
);
$trous = &$trous_[$indexJeux];
$titre = $html = false; $indexTrou = 0;
// parcourir tous les #SEPARATEURS
$tableau = jeux_split_texte('trous', $texte);
foreach($tableau as $i => $valeur) if ($i & 1) {
@ -159,24 +157,24 @@ function jeux_trous($texte, $indexJeux, $form=true) {
elseif ($valeur==_JEUX_TROU) {
// remplacement des trous par : <ATTENTE_TROU>ii</ATTENTE_TROU>
$html .= "<ATTENTE_TROU>$indexTrou</ATTENTE_TROU>";
$propositionsTROUS[$indexTrou] = jeux_liste_mots($tableau[$i+1]);
$trous['propositions'][$indexTrou] = jeux_liste_mots($tableau[$i+1]);
$indexTrou++;
}
}
// reinserer les trous mis en forme
$texte = trous_inserer_les_trous($html, $indexJeux);
// correction ?
$correction = isset($_POST["var_correction_".$indexJeux]);
if($correction) sort($score_detailTROUS);
$texte = trous_inserer_les_trous($trous, $html, $indexJeux);