'' et '''' qui sont respectivement le tableau, la ligne de tableau et la case de tableau.
Un tableau contient des lignes qui contient des colonnes. Ainsi une grille vide avec que des [] en guise de case vide ressemblera à :
Etant donné qu'on va faire du traitement pour gérer l'affichage des cases, on peut utiliser des boucles en PHP pour gérer le tableau.
';
for($colonne = 0; $colonne < 3; $colonne++){
echo '[] | ';
}
echo '';
}
?>
Un lien commençant par ? point toujours vers la page courante. C'est un raccourci de **morpion.php?...** si la page s'appelle **morpion.php**.
===== Seconde partie : le traitement =====
On va maintenant s'occuper de ce code de début de page qui va faire le traitement. Il faut faire plusieurs choses :
* Déterminer sur quel "mode" on est : formulaire, jeu ou fin.
* En fonction du mode, écouter les bonnes entrées (données formulaire, case cliquée)
* Déterminer si un joueur a gagné
==== Retenir les données & savoir où on en est ====
Lorsqu'on va d'une page à une autre, toutes les données sont réinitialisées, pas de possibilité donc de mémoriser des choses facilement... Sauf avec les **sessions**. Les sessions nous permettent d'avoir des variables qui résistent au changement de page. Ici on va les utiliser pour stocker 4 variables :
* Le nom du joueur 1
* Le nom du joueur 2
* L'état de la grille (sous forme d'un tableau de tableau, une matrice de 3*3 quoi)
* Le tour actuel (qui du joueur 1 ou 2 doit jouer)
Pour pouvoir utiliser les sessions, il faut mettre au tout début du code :
Il est important de le mettre au début du code, ou du moins avant tout code HTML et avant toute utilisation des sessions. Si il n'y a ne serait-ce qu'un espace de html avant l'appel de cette fonction, **ça ne fonctionnera pas** !
Les sessions l'utilisent simplement avec la variable ''$_SESSION'' qui est un array où on va venir assigner les valeurs qu'on veut aux clés qu'on veut.
On va utiliser le fait que ces variables existent ou non pour déterminer si on affiche le formulaire ou le jeu. Une fois le formulaire validé on va créer ces variables.
==== Récupérer les données du formulaire ====
Les données du formulaire sont stocké dans une des deux variables ''$_GET'' et ''$_POST'' selon la méthode choisie. Ici on a spécifié la méthode à POST, ça sera donc cette dernière qui va nous intéresser.
Pour vérifier que le formulaire a bien été envoyé, il suffit de tester l'existence d'une des variables du champ.
if(isset($_POST['nom1']) && isset($_POST['nom2'])){
// Traiter le formulaire
}else{
// Afficher le formulaire
}
Le nom de la valeur qu'on récupère dans ''$_POST'' correspond au nom donné dans l'attribut **name** de la balise **input**.
Une fois les données crées, il suffit d'initialiser les 4 variables de jeu pour lancer une partie.
Pour un peu plus de fun, on choisit aléatoirement quel joueur commence avec la fonction ''mt_rand(1,2)'' qui renvoie un entier au hasard entre 2 bornes (ici 1 et 2...)
A la fin du traitement, il faut relancer le script, pour que la condition vérifiant si les variables existe soit exécutée et ainsi afficher la grille. Une autre solution est de faire deux **if** indépendants pour ces deux vérifications. Pour faire une redirection : ''header('location: page.php');'' et ne pas oublier n'arrêter le script après la redirection avec l'instruction ''exit;''
Le code de traitement devrait donc jusque là ressembler à ça :
Si votre fichier ne s'appelle pas **morpion.php**, changez la ligne avec le ''header('location: ./morpion.php');''
==== Afficher nos belles données ====
Il serait dommage de ne pas afficher ces données récupérées non ?
Pour afficher le nom du joueur actuel, il suffit d'afficher ''$_SESSION['nom1']'' ou ''$_SESSION['nom2']'' en fonction du contenu de ''$_SESSION['tour']'' (qui vaut 1 ou 2).
simplement, on a :
echo 'C\'est au tour de '.htmlspecialchars($_SESSION['nom'.$_SESSION['tour']]).'';
On applique toujours la fonction ''htmlspecialchars($var)'' sur une variable venant de l'utilisateur qu'on affiche. Cela lui empêche d'injecter son propre code HTML : **C'est une des fonctions de base pour la sécurité de vos sites***
==== Et pour jouer ? ====
Il est temps de pouvoir placer ses croix et ses ronds !
Pour rappel, lorsque qu'on veut jouer on se rend sur le lien //morpion.php?**ligne=0**&**colonne=2**//. Les variables dans l'URL se récupèrent avec la variable ''$_GET'', ici ''$_GET['ligne']'' et ''$_GET['colonne']''. Il faudra vérifier si aux coordonnées données la valeur est bien à 0 (aucun joueur n'a déjà joué). Ensuite il faut appliquer la valeur de ''$_SESSION['tour']'' (qui contient le numéro du joueur dont c'est le tour) et changer cette valeur.
Après avoir fait ça le code de traitement devrait ressembler à ça :
Si votre fichier ne s'appelle pas **morpion.php**, changez la ligne avec le ''header('location: ./morpion.php');''
Maintenant pour que ça marche il faut modifier le code d'affichage du tableau pour afficher une X ou un O en fonction de la valeur stockée pour la grille.
Les boucles affichant le tableau fait parcourir les valeurs 0, 1 et 2 aux variables ''$ligne'' et ''$colonne'', il suffit donc de faire une simple vérification.
for($ligne = 0; $ligne < 3; $ligne++){
echo '';
for($colonne = 0; $colonne < 3; $colonne++){
if($_SESSION['grid'][$ligne][$colonne] == 0)
echo '[] | ';
elseif($_SESSION['grid'][$ligne][$colonne] == 1)
echo 'X | ';
else
echo 'O | ';
}
echo ' ';
}
On enlève les liens quand une case est jouée : on ne doit pas rejouer dessus !
==== Vérifier si il y a un gagnant ====
Il faut maintenant écrire un code vérifiant si un des joueurs a gagné. Pour cela il faut faire des conditions sur les valeurs de ''$_SESSION['grid']''
Il y a 8 cas de victoire :
* 3 en ligne
* 3 en colonne
* 2 en diagonale
Et un cas de match nul : toutes les cases sont remplies.
Pour vérifier qu'il y a un gagnant sur une ligne il faut vérifier que les 3 cases aient la même valeur et qu'elles soient différentes de zéro (sinon y'a victoire dès le début...). Par exemple :
if($_SESSION['grid'][0][0] != 0 && $_SESSION['grid'][0][0] == $_SESSION['grid'][0][1] && $_SESSION['grid'][0][1] == $_SESSION['grid'][0][2]){
// Victoire sur la première ligne
}
Bien évidemment on ne va pas écrire 8 lignes comme ça, on peut utiliser des boucles pour réduire le tout à 4 conditions (sans compter la vérification du match nul...)
Personnellement, j'a écrit une fonction ''is_there_a_winner()'' qui peut renvoyer 4 valeurs :
* 1 ou 2 si un des joueurs a gagné
* -1 s'il y a un match nul
* 0 si la partie continue
function is_there_a_winner(){
$grid = $_SESSION['grid'];
// Vérifications sur les lignes et colonnes :
for($i = 0;$i<3;$i++){
if($grid[$i][0] == $grid[$i][1] && $grid[$i][1] == $grid[$i][2] && $grid[$i][0] != 0) return $grid[$i][0];
if($grid[0][$i] == $grid[1][$i] && $grid[1][$i] == $grid[2][$i] && $grid[0][$i] != 0) return $grid[0][$i];
}
// vérifications sur les 2 diagonales :
if($grid[0][0] == $grid[1][1] && $grid[1][1] == $grid[2][2] && $grid[1][1] != 0) return $grid[1][1];
if($grid[0][2] == $grid[1][1] && $grid[1][1] == $grid[2][0] && $grid[1][1] != 0) return $grid[1][1];
// Vérification de match nul : est-ce que la grille est remplie N
$nb0 = 0; // On compte les zéros restants
for($i = 0;$i<3;$i++){
for($j = 0;$j<3;$j++){
if($grid[$i][$j]==0)
$nb0++;
}
}
if(!$nb0) return -1;
return 0;
}
Une fois cette fonction écrite, il suffit de l'appeler en cours de jeu pour vérifier si il faut continuer ou arrêter le jeu. Arrêter le jeu pourra se résumer à afficher une vue spécifique.
$winner = is_there_a_winner();
if($winner != 0){ // Il se passe quelque chose
$affichage = 'resultats';
}else{
// Vérifier si il y a un coup joué...
}
Le fait de stocker le résultat du calcul dans ''$winner'' permet d'éviter l'appel de ''is_there_a_winner()'' plusieurs fois, et donc d'éviter de faire plusieurs fois inutilement le même calcul. Ici le gain est négligeable, mais c'est une habitude
à prendre avec les fonctions faisant du traitement.
Il faudra ensuite modifier la vue en conséquence.
case 'resultats':
if($winner > 0){
echo 'Le joueur '.htmlspecialchars($_SESSION['nom'.$winner]).' a gagné ! ';
}else{
echo 'Match nul...';
}
break;
**Rappel :** On applique toujours la fonction ''htmlspecialchars($var)'' sur une variable venant de l'utilisateur qu'on affiche. Cela lui empêche d'injecter son propre code HTML : **C'est une des fonctions de base pour la sécurité de vos sites***
==== Rejouer ====
Dans l'état, le jeu est bloqué à une seule partie. Pour recommencer, il suffirait de détruire 4 variables pour retourner à l'écran de sélection des noms.
La fonction ''unset($variable)'' permet de supprimer une variable. Il suffit donc de l'appliquer à nos 4 variables de session à la fin d'une partie pour réinitialiser le jeu.
unset($_SESSION['nom1']);
unset($_SESSION['nom2']);
unset($_SESSION['grid']);
unset($_SESSION['tour']);
Ou encore plus simple, la fonction ''session_destroy()'' supprimera toute trace des variables de session.
===== Et voila, c'est fini =====
==== Correction ====
Normalement si vous avez bien suivi et compris ce tuto, votre version devrait marcher. Mais si vous voulez une correction, demandez moi. (rgrondin)
==== Idées d'améliorations ====
On a maintenant une première version basique du morpion. Bien entendu on peut facilement l'améliorer, voici quelques idées :
* Rajouter à coté du nom du joueur si il joue avec les X ou les O.
* Afficher les deux noms des joueurs avec les X et les O
* Après une fin de partie, retenir les noms des joueurs et les mettre par défaut dans le formulaire (Il ne faut donc pas utiliser la fonction ''session_destroy()'' et détruire sélectivement les variables.)
* Mettre en place un système de scores (Qui durera que dans le temps de la session du coup)
* Faire une IA contre laquelle jouer (On passe à un autre niveau là) |