Date de première publication : 2014/09/17
Principe du jeu
Nous vous proposons de coder le moteur d’un jeu qui s’intitule Flood It (de LabPixies disponible sur iPhone et Android). Le principe est très simple : Vous disposez d’une zone de jeu carrée de 12 cases par 12 cases. Chacune des cases est remplie d’une couleur sur 6 possibles. Vous devez vous arranger pour que toutes les cases soient de la même couleur en 22 coups maximum. Pour cela, vous choisissez une couleur pour la case en haut à gauche et cela peint toutes les cases adjacentes de cette couleur : le raz de marée. On dira qu’une case est adjacente si elle est de la couleur de la première case avant le changement et si elle touche une case de cette couleur soit par le haut/bas, soit par la gauche ou la droite (on ne considère pas les cases en diagonales).
Si vous voulez tester le jeu, voici une version HTML / Javascript
On remplace les couleurs par un chiffre entre 0 et 5. Voici un petit exemple :
Situation initiale :
0 | 1 | 3 | 1 |
2 | 1 | 2 | 2 |
3 | 1 | 1 | 3 |
0 | 0 | 4 | 4 |
Premier coup :
1 | 1 | 3 | 1 |
2 | 1 | 2 | 2 |
3 | 1 | 1 | 3 |
0 | 0 | 4 | 4 |
Deuxième coup :
3 | 3 | 3 | 1 |
2 | 3 | 2 | 2 |
3 | 3 | 3 | 3 |
0 | 0 | 4 | 4 |
La partie se termine alors en 6 coups (choisir dans n'importe quel ordre les couleurs 2, 1, 0 et 4). Vous avez compris ?
Ce qu'il faut faire ...
- Définir deux constantes symboliques
COULEURS
de valeur 6 etTAILLE
de valeur 12. - Écrire une fonction
initialiser()
qui prend en paramètre le tableau à deux dimensions et qui initialise le tableau avec des couleurs au hasard. - Écrire une fonction
afficherGrille()
qui affiche la grille donnée en paramètre. On pourra afficher les entiers mais aussi utiliser des couleurs dans le terminal (grâce aux séquences d'échappement). - Écrire une fonction
fin()
qui renvoie 1 si la grille est remplie de cases de la même couleur, 0 sinon. La grille est donnée en paramètre. - Écrire la fonction
remplir()
qui prend en paramètre la grille courante, la couleur de la première case avant changement, la nouvelle couleur, des coordonnées i et j du tableau. Si la couleur de la case (i,j) est de la couleur originale de la case (0,0), on la change pour la nouvelle puis on propage aux cases adjacentes. - Écrire une fonction
main()
qui définit une grille, initialise la grille et l’affiche. La boucle principale du programme demandera à l’utilisateur un nombre, en général une couleur, et lancera le raz de marée. Le programme se termine : - quand la grille est uniforme
- si l’utilisateur force la fin du programme (code 999 par exemple).
- si le nombre d’itérations dépasse 22.
Si l’utilisateur donne la couleur de la case (0,0), on ne doit rien faire.
Ce TP se poursuit pour en faire une version graphique et en couleurs avec la SDL2. (Une version avec la Xlib est également disponible).
Compléments
Fonction remplir()
Je vous propose de programmer remplir()
de manière récursive en appelant la fonction sur les cases adjacentes :
? | |||
? | ? | ? | |
? |
L'algorithme est très simple :
- Vérifier que les indices de case sont valides
- Vérifier que la case est de la couleur que l'on veut changer
- Changer la couleur
- Appeler la fonction sur les cases adjacentes...
Couleurs dans un terminal
Il est plus facile pour le joueur d'afficher des couleurs en lieu et place des nombres représentant la couleur. C'est tout à fait possible d'afficher de la couleur dans un terminal UNIX en utilisant ce que l'on appelle des séquences d'échappement en octal
Pour modifier la couleur de fond, il faut utiliser la séquence \033[nm
où n est un nombre qui va de 40 (fond noir) au 47.
La séquence \033[0m
permet de restituer les valeurs par défaut au shell.
Plus d'explications ici.
Aller plus loin...
- Quelles(s) fonction(s) doit-on modifier pour que l’utilisateur puisse donner la taille de la zone de jeu, le nombre de couleurs et le nombre maximum de coups en ligne de commande ?
- Faire les modifications. Si aucun paramètre n’est donné, on doit utiliser 12 cases, 6 couleurs et 22 coups au maximum.
- Modifier la fonction
main()
pour que la grille soit maintenant allouée dynamiquement. Mettre à jour les autres fonctions.