⏱️ 4h
📚 Algorithmie en langage C
📅 Mis à jour le 23/09/2025

🎯 Objectifs

  • Premier jeu en C
  • Manipuler les fichiers header (.h)

🔧 Matériel nécessaire

  • Ordinateur avec compilateur gcc
  • CodeBlocks/VS Code

Règles du puissance 4

L’objectif du puissance 4 est d’aligner quatre jetons sur une grille verticale composée de 6 lignes et 7 colonnes. Deux joueurs s’affrontent en tour par tour en plaçant un jeton dans une colonne. Lorsqu’un joueur aligne quatre jetons horizontalement, verticalement ou diagonalement, il remporte la partie. Si toutes les cases sont remplies sans qu’un joueur n’ait réussi à aligner quatre jetons, alors la partie est déclarée nulle.

Fichier header

Sur Arche, vous trouverez un fichier header nommé puissance4.h. Créez un projet sous CodeBlocks et y ajouter ce fichier.

#include <stdio.h>
#include <stdlib.h>
#define LIGNES 6
#define COLONNES 7

enum jeton {CROIX=1, ROND=2};
typedef struct {
  char pseudo[20];
  enum jeton couleur;
} joueur;

//Prototypes de fonctions
void afficher_plateau(int tab[LIGNES][COLONNES]);
int combien_dans_colonne(int tab[LIGNES][COLONNES],int col);
int empiler(int tab[LIGNES][COLONNES], int col, int couleur);
int combien_dans_direction(int tab[LIGNES][COLONNES], int couleur, int col, int d_l ,int d_c);
int test_ligne(int tab[LIGNES][COLONNES], int couleur, int col);
int test_colonne(int tab[LIGNES][COLONNES], int couleur, int col);
int test_diagonales(int tab[LIGNES][COLONNES], int couleur, int col);
int test_tout(int tab[LIGNES][COLONNES], int couleur, int col);

Dans ce TP, on ne se concentre pas sur le rendu graphique du jeu, l’affichage se fera directement dans la console. Pour différencier les jetons, on utilisera les symboles x (CROIX) et o (ROND) à la place des couleurs jaune et rouge.

Note

La syntaxe #define NOM valeur permet la création de macros. À la compilation, toutes les occurences de NOM dans le programme sont remplacées par valeur.

Tip

Pensez à utiliser des macros pour les constantes de vos programmes. Cela permet de diminuer le nombre de variables utilisées en mémoire.

Q1. Déclarez dans ce fichier un tableau d’entiers composé de 6 lignes et 7 colonnes nommé plateau.

On considère le codage suivant :

  • 0 : case vide
  • 1 : jeton CROIX
  • 2 : jeton ROND

Affichage de la grille

Q2. Créez un fichier utilitaires.c qui va contenir toutes vos fonctions utiles.

Q3. Écrivez une fonction de prototype void afficher_plateau(int tab[LIGNES][COLONNES]); qui permet d’afficher le plateau de jeu selon la représentation suivante.

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | |x| | |
| | |x|o|o| | |
---------------
 1 2 3 4 5 6 7

Warning

La ligne d’indice 0 du plateau correspond à la ligne du bas.

Q4. Créez un fichier puissance4.c contenant une fonction main() qui permet de tester votre fonction d’affichage.

Note

Pensez à importer votre ficher puissance4.h avec le mot clé #include.

Empilement des jetons

Afin d’empiler correctement les jetons, il est utile de connaître le nombre de jetons déjà présents dans une colonne.

Q5. Écrivez une fonction de prototype int combien_dans_colonne(int tab[LIGNES][COLONNES], int col); qui renvoie le nombre de jetons déjà présents dans la colonne col du tableau tab.

Q6. Écrivez une fonction de prototype int empiler(int tab[LIGNES][COLONNES], int col, int couleur); qui empile un jeton de couleur couleur dans la colonne col du tableau tab. Elle doit renvoyer 1 si l’empilage a été effectué, 0 si l’opération n’est pas faisable.

Note

Lorsque que l’on passe un tableau en argument, on y passe en réalité son adresse. Ainsi, lorsque l’on modifie le tableau à l’intérieur de la fonction, la variable est modifiée à l’extérieur également, ce qui explique que l’on ne renvoie pas la valeur du tableau.

Boucle de jeu

Q7. Modifiez la fonction main() afin de permettre à deux joueurs de jouer l’un après l’autre indéfiniment après avoir renseigné leurs pseudos. Pour l’instant, on ne vérifie pas si l’un des joueurs a gagné.

Note

Pensez à redemander une colonne au joueur tant qu’il ne renseigne pas une colonne jouable.

Vérification de succès

On va maintenant implémenter les différentes fonctions permettant de vérifier si un alignement de quatre jetons de la même couleur a été complété.

Tip

Si l’on vérifie les alignements à chaque coup, alors un des quatre jetons d’un alignement gagant est forcément le dernier jeton joué.

Q8. Écrivez une fonction de prototype int combien_dans_direction(int tab[LIGNES][COLONNES], int couleur, int col, int d_l, int d_c) qui compte le nombre de jetons successifs de couleur couleur dans la direction donnée par (d_l, d_c) depuis la position du dernier jeton joué en colonne col. On ne compte pas le jeton d’où l’on part.

Pour le plateau tab suivant :

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |x|x|x| | |
| | |x|o|o|o| |
---------------
 1 2 3 4 5 6 7

le code

int c1, c2, c3;
c1 = combien_dans_direction(tab, 1, 3, 0, 1);
c2 = combien_dans_direction(tab, 2, 6, 0, -1);
c3 = combien_dans_direction(tab, 1, 4, -1, -1);
printf("%d, %d, %d", c1, c2, c3);

affiche

2, 2, 1

Warning

Veillez à garder vos indices dans les limites du tableau.

Alignement horizontal

Q9. Écrivez une fonction de prototype int test_ligne(int tab[LIGNES][COLONNES], int couleur, int col); qui renvoie 1 si un alignement de quatre jetons de couleur couleur est présent sur la ligne du dernier jeton joué en colonne col. Sinon, elle renvoie 0.

Alignement vertical

Q10. Écrivez une fonction de prototype int test_colonne(int tab[LIGNES][COLONNES], int couleur, int col); qui renvoie 1 si un alignement de quatre jetons de couleur couleur est présent en colonne col. Sinon, elle renvoie 0.

Alignement diagonal

Q11. Écrivez une fonction de prototype int test_diagonales(int tab[LIGNES][COLONNES], int couleur, int col); qui renvoie 1 si un alignement de quatre jetons de couleur couleur est présent dans au moins une des diagonales passant par le dernier jeton joué en colonne col. Sinon, elle renvoie 0.

Synthèse des tests

Q12. Écrivez une fonction de prototype int test_tout(int tab[LIGNES][COLONNES], int couleur, int col); qui renvoie 1 si un alignement de quatre jetons de couleur couleur passant par le dernier jeton joué en colonne col est présent dans le tableau tab. Sinon, elle renvoie 0.

Programme final

Q13. Modifiez votre fonction main() pour obtenir le comportement suivant :

  • au lancement du jeu, les joueurs renseignent leurs pseudos ;
  • lorsqu’un joueur gagne :
    • il est félicité par le programme ;
    • son pseudo est ajouté au fichier texte gagnants.txt ;
  • à la fin d’une partie, qu’elle soit nulle ou non, on propose de lancer une nouvelle partie.

Pour les plus téméraires

Proposez un algorithme de décision qui suggère une colonne à jouer pour un tableau et une couleur donnés. Votre algorithme doit pouvoir battre un joueur jouant de façon aléatoire.