Cours de programmation séquentielle

Puissance 4

But du travail pratique

Le but de ce travail pratique est de réaliser un jeu de puissance 4. Le jeu doit implémenter trois modes différents :

Le rendu visuel du jeu sera réalisé en mode texte “ASCII Art” tel qu’illustré ci-dessous (vous pouvez copier-coller les symboles depuis la version HTML de cet énoncé ou depuis le repo git:

Column number? (starts at 1):
4
┌─┬─┬─┬─┬─┬─┬─┐
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │X│ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │X│O│ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│O│X│X│O│ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│X│O│X│O│ │ │ │
└─┴─┴─┴─┴─┴─┴─┘
 1 2 3 4 5 6 7
Player one won!

En outre, une batterie de tests (testbed) permettant de valider que votre implémentation est correcte vous est fournie, de même que le programme fonctionnel. Ainsi, vous pourrez vous assurez que votre implémentation produit exactement l’affichage souhaité. Ce dernier point est particulièrement important, car si l’affichage exact n’est pas respecté, tous les tests de validation échoueront.

Syntaxe du programme à implémenter

Le programme à implémenter doit impérativement respecter la syntaxe suivante :

Usage: puissance4 <mode> <row> <col>
    mode  specifies the mode: 1 = single player game (random),
          2 = single player game (AI), 3 = two players game
    row   specifies the number of rows (>= 4)
    col   specifies the number of columns (>= 4)

A noter que l’ordre des arguments est fixé. Voici un exemple d’exécution avec le mode deux joueurs sur une grille de 6x7 (lignes x colonnes) :

./puissance4 3 6 7

Un autre exemple avec une partie contre l’ordinateur “intelligent” sur une grille de 11x9 :

./puissance4 2 11 9

Règles du jeu

Le jeu se joue à deux. Chacun leur tour, les joueurs choisissent une colonne. Quand le choix est fait, une pastille “tombe” au bas de la colonne spécifiée. Le premier joueur qui aligne quatre pastilles soit verticalement, soit horizontalement, soit en diagonale a gagné.

Mode ordinateur aléatoire

Programmer le jeu pour une seule personne face à l’ordinateur. Dans la première version de cette variante l’ordinateur jouera toujours au hasard.

Mode ordinateur “intelligent”

Dans une version plus sophistiquée l’ordinateur sera en mesure d’empêcher la victoire de son adversaire s’il gagne au prochain coup, ou gagnera s’il est en mesure de gagner au prochain coup. Dans tous les autres cas l’ordinateur jouera au hasard.

Cahier des charges

  1. Programmer le jeu entre un humain et un ordinateur :
  2. Programmer une “intelligence artificielle” un peu plus évoluée :
  3. Programmer le jeu à deux joueurs humains :
  4. Les paramètres du jeu sont lus sur la ligne de commande selon la syntaxe définie au paragraphe Syntaxe du programme à implémenter.

Important: à cause de la “mise en mémoire tampon” des chaînes de caractères lues ou affichées (avec printf() ou scanf()) vous aurez besoin de la fonction suivante pour vider cette mémoire tampon pour lire les entrées comme il faut:

void flush_input() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF); 
}

Tests automatisés

Paramètres d’entrée

Il est très important de respecter le format de la ligne de commande comme indiquées ci-dessus.

Le joueur doit rentrer une colonne à la fois. On supposera qu’il rentrera toujours un nombre entre 1 et le nombre de colonnes (pour simplifier).

Début de la partie

  1. Si M et N correspondent au row et col des paramètres d’entrée. Vous devez afficher la taille du plateau de jeu sur la première ligne
Board size is MxN (rows x col)
  1. Vous devez afficher en “ASCII Art” l’état du tableau au début de la partie :
┌─┬─┬─┬─┬─┬─┬─┐
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
└─┴─┴─┴─┴─┴─┴─┘
 1 2 3 4 5 6 7

En cours de partie

  1. Lorsqu’un joueur doit jouer, la chaine de caractères suivante doit être affichée :
Column number? (starts at 1):
  1. Après chaque coup (que ce soit d’un joueur ou de l’ordinateur), le tableau de jeu doit aussi être affiché :
┌─┬─┬─┬─┬─┬─┬─┐
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│ │ │ │ │ │ │ │
├─┼─┼─┼─┼─┼─┼─┤
│X│O│ │ │ │ │ │
└─┴─┴─┴─┴─┴─┴─┘
 1 2 3 4 5 6 7

Victoire/défaite/match nul

Un certain nombre de tests automatisés sont fournis avec le code. Il est impératif que le format de sortie soit scrupuleusement respecté pour pouvoir passer les tests. En d’autres termes:

Player one won!
Player two won!
Computer won!
It is a draw.

Tests automatisés fournis

Un squelette comprenant les tests automatisés vous est fourni sur la page dans l’archive skeleton_for_students.tar.gz.

A l’intérieur du répertoire se trouve un Makefile. Celui-ci sera utilisé pour compiler votre programme et nettoyer les fichiers finaux et intermédiaires générés. Ce Makefile doit contenir les cibles suivantes :

Important: Il est impératif d’initialiser la graine de votre générateur de nombre aléatoire à 0 pour que les tests passent avec succès (srand(0)).

Il est impératif que votre programme passe tous les tests ! Vous pouvez vérifier simplement ceci en exécutant “make tests” dans le répertoire racine du travail pratique. En cas d’exécution sans erreur, vous devriez obtenir un affichage similaire à ceci :

$ make tests
make -C testbed
make[1]: Entering directory '/home/orestis/git/projects/puissance4/testbed'
make -C 2players
make[2]: Entering directory '/home/orestis/git/projects/puissance4/testbed/2players'
=============[2 player tests]=============
test1
-----------------------------
test2
-----------------------------
test3
-----------------------------
test4
-----------------------------
test5
-----------------------------
make[2]: Leaving directory '/home/orestis/git/projects/puissance4/testbed/2players'
make -C rand_ai
make[2]: Entering directory '/home/orestis/git/projects/puissance4/testbed/rand_ai'
=============[random AI tests]=============
test1
-----------------------------
test2
-----------------------------
test3
-----------------------------
test4
-----------------------------
make[2]: Leaving directory '/home/orestis/git/projects/puissance4/testbed/rand_ai'
make -C smart_ai
make[2]: Entering directory '/home/orestis/git/projects/puissance4/testbed/smart_ai'
=============[smart AI tests]=============
test1
-----------------------------
test2
-----------------------------
test3
-----------------------------
test4
-----------------------------
test5
-----------------------------
make[2]: Leaving directory '/home/orestis/git/projects/puissance4/testbed/smart_ai'
make[1]: Leaving directory '/home/orestis/git/projects/puissance4/testbed'

Notes importantes