TD05 Morpion

Avant de commencer…

Consultez les corrections du TD4.

Qu’est-ce qu’on apprend

  1. Créer et détruire des tableaux avec malloc et free.
  2. Modifier des tableaux à l’intérieur d’une fonction graçe au passage par adresse.
  3. Tester des fonctions avec des petites fonctions de test.
  4. Créer des nombres aléatoires.

Lecture…

Gestion de mémoire:


C’est l’heure du quizz…

Remplissez le quizz IN102-05 avant 18h.


Au boulot…

Ecrivez un programme pour jouer le jeux de morpion entre un humain et l’ordinateur : sur une grille de taille 3 x 3, chaque joueur place à son tour un symbole (x pour le joueur humain, o pour le joueur ordinateur). Un joueur gagne dès qu’il a placé 3 symboles coté à coté, horizontalement, verticalement ou en diagonale. Le joueur humain commence la partie. A chaque tour, le joueur humain entre un chiffre avec le clavier. Ce chiffre indique la case sur laquelle il souhaite placer son symbole. Le nombre de tours est le nombre de fois que le joueur humain a joué. Les cases sont numérotées comme suivant :

123
456
789

Le joueur ordinateur jouera une case aléatoire, en prenant soin de ne pas jouer sur une case déjà occupée.

IMPORTANT: Donnez votre prénom et nom au début du fichier de réponse, sous forme de commentaire. Ajoutez également les réponses aux questions dans votre programme, sous forme de commentaires. Exemple:

/* Jeanne LAGAFFE */
#include <stdio.h>
int main () {
   printf("Hello World !!\n");
}
/* 
Q1: Ceci est la réponse à la question 1.
Q2: Voilà la réponse à la question 2.
*/

Q1:

La grille sera repreésentée par un tableau d’entiers :

  • 0 représentant une case vide,
  • 1 une case occupée par le joueur humain,
  • 2 une case occupée par le joueur ordinateur.

Créer une fonction

int* creer_grille()

qui crée d’abord un tableau dont les cases sont vides. La fonction doit réserver la mémoire avec malloc et retourner un pointeur vers ce tableau.

Attention : Toute mémoire alloué avec malloc doit être libéré avec free avant la fin du programme.

Rappel : Une fonction ne peut pas retourner un pointeur vers une variable locale. Exemple d’une mauvaise utilisation :

int* nouveau_tableau() {
  int tab[10];
  return tab; // MAUVAISE IDEE!
}

La variable locale est détruite à la fin de la fonction, donc le pointeur sera invalide. Pour qu’une fonction puisse retourner un nouveau tableau, on peut l’allouer avec malloc.

Q2:

Ecrivez une fonction

void afficher(int* grille)

qui prend en argument le tableau et affiche les cases sous forme de grille. Un exemple d’affichage:

xxx
.o.
o..

Q3:

Testez les fonctions précédentes dans une fonction test_affichage(). A l’intérieur de cette fonction, exécutez toutes les actions suivantes : Créez une grille vide, affichez-la. Marquez ensuite la case 4 comme occupé par le joueur humain, 8 comme occupé par le joueur ordinateur. Affichez le résultat.

Q4:

Définissez une fonction

void placer(int* grille, int chiffre, int joueur)

qui prend en argument la grille et place le symbole du joueur à la case correspondant au chiffre. Plus précisément, la fonction modifie la case correspondante du tableau grille pour y affecter l’entier qui correspond au joueur (ordinateur ou humain). Pour simplifier, on ne vérifiera pas si la case est réellement libre avant de placer le symbole.

Q5:

Définissez une fonction

void placer_alea(int* grille, int joueur)

qui choisit un chiffre entre 1 et 9 de façon aléatoire, puis appelle placer(…) pour y placer le symbole.

Attention : Si la coordonnée est telle que la case n’est pas vide, il faut tirer un nouveau chiffre jusqu’à ce qu’on trouve une case vide.

Astuce : Pour tirer un nombre aléatoire entre 0 et N - 1, vous pouvez faire appel au générateur de nombres aléatoires avec rand()%N. Pensez à initialiser le générateur de nombres aléatoires en appelant srand(time(0)); une fois au début de votre programme. Il faudra inclure stdlib.h et time.h.

Q6:

Ajoutez une fonction

int a_gagne(int* grille, int joueur)

qui donne 1 si le joueur a gagné et 0 sinon.

Q7:

Ajoutez à votre main une boucle dans laquelle on

  • affiche la grille,
  • demande au joueur humain d’entrer un chiffre,
  • appelle placer pour placer le symbole du joueur humain,
  • appelle placer_alea pour placer le symbole du joueur ordinateur.

La boucle doit terminer quand un des deux joueurs a gagné. Pour l’instant, on peut ignorer le cas d’un match nul.

Q8:

Modifiez votre programme afin de détecter quand le jeu se termine en match nul : aucun des joueurs a gagneé mais il n’y a plus de case libre. Dans ce cas, afficher

Match nul en X tours.

où X est le nombre de tours joués.

Validez:

Nommez le fichier T05.c et envoyez-le à votre chargé de TD