Tic Tac Toe – Rendre le jeu fonctionnel grâce au PHP

Dans ce dernier tutoriel sur le Tic Tac Toe, vous allez découvrir une solution possible afin de rendre le jeu fonctionnel grâce à l’utilisation du PHP.

Avant d’aller plus loin, il faut savoir qu’en PHP, comme dans la plupart des langages de programmation, il existe deux façons de programmer :

  • La programmation procédurale
  • La programmation orientée objet (POO ou OOP en anglais)

Il existe bien évidemment d’autres façons de programmer, mais celles-ci sont les plus courantes en PHP.

La programmation procédurale

Comme son nom l’indique, la programmation procédurale consiste à écrire un code qui suit une procédure. Ainsi, nous avons un code linéaire et rigide, qui peut devenir difficilement maintenable à la longue. Le code procédural est aussi plus difficile a lire par les développeurs qui n’ont pas écrit ce code, surtout s’il est mal documenté.

Avec la programmation procédurale, on réalise moins l’interdépendance des différentes parties d’un programme. Cependant, l’avantage de la programmation procédurale pour un débutant consiste en sa facilité de mise en place, puisqu’il n’y a pas d’obligation de penser à toute la structure du programme en amont.

La programmation orientée objet (POO)

La POO nécessite une façon de penser différente du procédural. Il faut bien réfléchir à la structure de son programme et le découper en fonctionnalité ou sous fonctionnalités. Les avantages de ce type de programmation résident dans la modularité du code et la facilité de compréhension pour les développeurs tiers.

Un autre avantage indéniable, outre la facilité de maintenance du code, consiste en la possibilité de réutilisation de tout ou partie de votre code.

Dans ce tutoriel nous aborderons le développement du jeu uniquement en programmation procédurale. Le développement orienté objet sera probablement abordé dans un tutoriel futur.

La structure du programme

Avant de se lancer dans la programmation, il faut réfléchir un minimum à ce dont nous avons besoin dans notre programme, c’est à dire :

  • Une grille de 3×3
  • Garder en mémoire les cases jouées et les joueurs qui ont joué
  • Garder en mémoire le score des deux joueurs
  • Récupérer le clic sur une case et mettre à jour la grille de jeu
  • Tester s’il y a un vainqueur
  • Réinitialiser la partie
  • Indiquer quel joueur doit jouer
  • Afficher sur la grille les ronds et les croix

Développons le programme

La grille de jeu

La grille de jeu est composée de 9 cases. Ces cases peuvent être stockées dans un tableau (array), chaque case doit pouvoir prendre trois états : vide, rond, croix.

Cette grille doit être stockée en mémoire grâce à l’utilisation des variables de session. Pour simplifier et accélérer le développement, les trois états seront représentés par des chiffres, ainsi nous avons 0 lorsque la case est vide, 1 pour les croix et 2 pour les ronds.

Cela se concrétise sous cette forme :

// Création de la grille de neuf cases
$_SESSION['grille'] = array(0,0,0,0,0,0,0,0,0);

// Peut être aussi matérialisé de cette façon
$_SESSION['grille'] = array(
0,0,0,
0,0,0,
0,0,0);

Le score des joueurs

Le score doit être enregistré dans des variables de session. Pour cela nous avons besoin de deux variables (J1 et J2) et d’une variable pour savoir quel joueur doit jouer.

$_SESSION['scoreJ1'] = 0;
$_SESSION['scoreJ2'] = 0;
$_SESSION['auJoueur'] = 1;

// Pour faciliter la lecture de notre programme on créé les variables de joueurs 
$j1 = 1,
$j2 = 2;

Les variables des scores seront incrémentées en fonction des résultats, quand à celle du joueur qui doit jouer aura deux états : 1 ou 2.

Récupérer le clic et mettre à jour

Il existe différentes façons de récupérer le clic d’un utilisateur. Ici, nous allons utiliser les variables GET, transmises directement grâce à l’URL du navigateur.

Pour cela, il faut d’abord attribuer une valeur à chaque case en HTML. Nous reprenons donc le code donné dans le tutoriel précédent, et nous lui ajoutons les liens pour pouvoir transmettre les cases.

<section class="container">

<p>Le joueur 1 doit jouer</p>
<div class="tg-wrap"> // le tableau est entouré d’une div
<table> // ouverture du tableau
<tr> // ceci est une ligne du tableau
<th><a href="?case=1"></a></th> // ceci une case
<th><a href="?case=2"></a></th>
<th><a href="?case=3"></a></th>
</tr>

<tr>
<td><a href="?case=4"></a></td>
<td><a href="?case=5"></a></td>
<td><a href="?case=6"></a></td>
</tr>

<tr>
<td><a href="?case=7"></a></td>
<td><a href="?case=8"></a></td>
<td><a href="?case=9"></a></td>
</tr>
</table> // fermeture du tableau
</div>

Nous pouvons ainsi récupérer grâce à PHP, les cases sur lesquels le joueur à cliqué et effectuer les tests afin de savoir :

  • Qui a cliqué
  • Est-ce qu’il y a un vainqueur
  • Est-ce qu’il faut afficher une croix ou un rond

Afin de pouvoir effectuer tous les tests et aussi à ne pas avoir à réinitialiser les variables à chaque chargement de la page, il va falloir tester si les variables sont initialisées et surtout si elles ne sont pas vides.

// Il ne faut pas oublier de faire le test pour la grille
if(empty($_SESSION['grille']))
		$_SESSION['grille'] = array(0,0,0,0,0,0,0,0,0);

// Puis on fait les tests pour les joueurs
if(empty($_SESSION['scoreJ1']))
		$_SESSION['scoreJ1'] = 0;

if(empty($_SESSION['scoreJ2']))
		$_SESSION['scoreJ2'] = 0;

if(empty($_SESSION['auJoueur']))
		$_SESSION['auJoueur'] = 1;

Maintenant nous pouvons effectuer le test afin de savoir si une case a été cliquée.

// On récupère la valeur de GET si ce n'est pas vide
if(!empty($_GET['case'])){
	// On récupère la case jouée et on la décrémente pour que cela corresponde avec notre tableau (array). Il ne faut pas oublier que les array commencent leur valeur à 0.
	$leJoueurJoueLaCase = $_GET['case'] - 1;

	// On test si la case est égale à 0
	if($_SESSION['grille'][$leJoueurJoueLaCase] == 0){
		// la case est libre, on peut y placer le pion
		$_SESSION['grille'][$leJoueurJoueLaCase] = $_SESSION['auJoueur'];
	}

}

Et pour fini, il ne faut surtout pas oublier d’afficher les croix et les ronds sur la grille. Pour cela nous récupérons notre tableau (array) et nous affichons les images en fonction des valeurs. Souvenez-vous, une case libre lorsque la valeur est à 0, une croix à 1 et un rond à 2.

<section class="container">
	<p id="player">Le joueur <?php echo $_SESSION['auJoueur']; ?> doit jouer</p>
		<div class="tg-wrap">
		<table class="tg">
  <tr>
    <th class="tg-031e"><a href="?case=1#"><?php if($_SESSION['grille'][0] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][0] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></th>
    <th class="tg-031e"><a href="?case=2#"><?php if($_SESSION['grille'][1] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][1] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></th>
    <th class="tg-031e"><a href="?case=3#"><?php if($_SESSION['grille'][2] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][2] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></th>
  </tr>
  <tr>
    <td class="tg-031e"><a href="?case=4#"><?php if($_SESSION['grille'][3] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][3] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
    <td class="tg-031e"><a href="?case=5#"><?php if($_SESSION['grille'][4] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][4] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
    <td class="tg-031e"><a href="?case=6#"><?php if($_SESSION['grille'][5] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][5] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
  </tr>
  <tr>
    <td class="tg-031e"><a href="?case=7#"><?php if($_SESSION['grille'][6] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][6] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
    <td class="tg-031e"><a href="?case=8#"><?php if($_SESSION['grille'][7] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][7] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
    <td class="tg-031e"><a href="?case=9#"><?php if($_SESSION['grille'][8] == 1) echo '<img src="img/cross.png" alt="Croix">'; elseif($_SESSION['grille'][8] == 2) echo '<img src="img/circle.png" alt="Circle">'; else echo " "; ?></a></td>
  </tr>
</table>
</div>

Tester s’il y a un vainqueur

Pour tester s’il y a un vainqueur, il y a plusieurs façons d’y arriver. Ici nous ne donnerons qu’une solution élémentaire et très probablement la moins optimisée qui soit. A vous de trouver une meilleure façon de faire les tests.

// Le principe étant de tester toutes les possibilités grâce à des conditions.
if(
	($_SESSION['grille'][0] == $_SESSION['grille'][1]) && 
	($_SESSION['grille'][1] == $_SESSION['grille'][2]) && 
	($_SESSION['grille'][2] == $auJoueur)){
		++$_SESSION[$score];

		// Réinitialise
		$_SESSION['grille'] = array(0,0,0,0,0,0,0,0,0);
		$_SESSION['auJoueur'] = 1;
	} elseif(
	($_SESSION['grille'][3] == $_SESSION['grille'][4]) && 
	($_SESSION['grille'][4] == $_SESSION['grille'][5]) && 
	($_SESSION['grille'][5] == $auJoueur)){
		++$_SESSION[$score];
		
		// Réinitialise
		$_SESSION['grille'] = array(0,0,0,0,0,0,0,0,0);
		$_SESSION['auJoueur'] = 1;
	}

Réinitialiser la partie

Pour cela nous appliquons le même principe de la transmission de variables GET

<div class="reset"><a href="?case=reset">Réinitialiser la partie</a></div>

Puis nous réinitialisons la grille.

if($_GET['case'] == "reset"){
	$_SESSION['grille'] = array(0,0,0,0,0,0,0,0,0);
}

Informer les joueurs

Il nous reste à informer le joueur qui doit jouer et afficher les scores.

<p id="player">Le joueur <?php echo $_SESSION['auJoueur']; ?> doit jouer</p>

<div class="score">
	<h1>Score</h1>
	<p>Joueur 1 (croix) : <?php echo $_SESSION['scoreJ1']; ?></p> 
	<p>Joueur 2 (rond) : <?php echo $_SESSION['scoreJ2']; ?></p>
	<p class="draw"><?php if(!empty($matchNul)) echo $matchNul; ?></p>
</div>

Nous arrivons à la fin de ce tutoriel sur la création d’un Tic Tac Toe en PHP. Bien évidemment, il est loin d’être parfait ou complet, cela vous laissera l’occasion de l’améliorer en y ajoutant une intelligence artificielle à plusieurs niveaux de difficulté, améliorer le code, etc.

Gardez à l’esprit que votre premier code ne pourra jamais être parfait, il vous faudra persévérer et beaucoup de pratique afin de produire du bon code rapidement.