2021-10-24 14:23:33 +02:00
|
|
|
/* Jeu de Hanoï pour implémenter les piles */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "hanoi.h"
|
|
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
Pile p1, p2, p3;
|
|
|
|
|
|
|
|
creer_pile(&p1);
|
|
|
|
creer_pile(&p2);
|
|
|
|
creer_pile(&p3);
|
|
|
|
|
2021-10-24 19:35:22 +02:00
|
|
|
ajout_tous_disques(&p2);
|
2021-10-24 14:23:33 +02:00
|
|
|
|
|
|
|
while (!partie_finie(p1, p2, p3)) {
|
|
|
|
affiche_etat_piles(p1, p2, p3);
|
2021-10-24 19:35:22 +02:00
|
|
|
faire_coup(&p1, &p2, &p3);
|
2021-10-24 14:23:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
printf("Bravo, vous avez terminé\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-24 19:35:22 +02:00
|
|
|
void ajout_tous_disques(Pile *p) {
|
2021-10-24 14:23:33 +02:00
|
|
|
int nombre_disques;
|
|
|
|
|
|
|
|
printf("Combien de disques ? ");
|
|
|
|
scanf("%d", &nombre_disques);
|
|
|
|
|
|
|
|
for (int i = nombre_disques; i >= 1; i--) {
|
2021-10-24 19:35:22 +02:00
|
|
|
empile(p, i);
|
2021-10-24 14:23:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void creer_pile(Pile *p) {
|
|
|
|
*p = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int partie_finie(Pile p1, Pile p2, Pile p3) {
|
|
|
|
return (est_vide(p2) && (est_vide(p1) || est_vide(p3)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void affiche_etat_piles(Pile p1, Pile p2, Pile p3) {
|
|
|
|
printf("Pile 1 : ");
|
|
|
|
affiche_etat(p1);
|
|
|
|
printf("Pile 2 : ");
|
|
|
|
affiche_etat(p2);
|
|
|
|
printf("Pile 3 : ");
|
|
|
|
affiche_etat(p3);
|
|
|
|
}
|
|
|
|
|
|
|
|
void affiche_etat(Pile p) {
|
|
|
|
int diam;
|
|
|
|
|
|
|
|
if (est_vide(p)) {
|
|
|
|
printf("vide\n");
|
|
|
|
} else {
|
|
|
|
diam = valeur_top(p);
|
|
|
|
printf("Le disque en haut de la pile est de diamètre %d\n", diam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-24 19:35:22 +02:00
|
|
|
void faire_coup(Pile *p1, Pile *p2, Pile *p3) {
|
2021-10-24 14:23:33 +02:00
|
|
|
int num_pile, diam;
|
|
|
|
Pile pile_a_depiler, pile_ou_empiler;
|
|
|
|
|
|
|
|
printf("Où voulez-vous prendre le disque ? ");
|
|
|
|
scanf("%d", &num_pile);
|
2021-10-24 19:35:22 +02:00
|
|
|
pile_a_depiler = *selection_pile(p1, p2, p3, num_pile);
|
2021-10-24 14:23:33 +02:00
|
|
|
|
|
|
|
if (est_vide(pile_a_depiler)) {
|
|
|
|
printf("Impossible, cette pile est vide\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
diam = valeur_top(pile_a_depiler);
|
|
|
|
printf("Vous avez sélectionné un disque de diamètre %d\n", diam);
|
|
|
|
|
|
|
|
printf("Où voulez-vous poser le disque ? ");
|
|
|
|
scanf("%d", &num_pile);
|
2021-10-24 19:35:22 +02:00
|
|
|
pile_ou_empiler = *selection_pile(p1, p2, p3, num_pile);
|
2021-10-24 14:23:33 +02:00
|
|
|
|
|
|
|
if (!est_vide(pile_ou_empiler) && (diam > valeur_top(pile_ou_empiler))) {
|
|
|
|
printf("Coup non autorisé\n");
|
|
|
|
} else {
|
|
|
|
depile(&pile_a_depiler);
|
|
|
|
empile(&pile_ou_empiler, diam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int est_vide(Pile p) {
|
|
|
|
return (p == NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void empile(Pile *p, int nombre) {
|
|
|
|
struct maillon *q;
|
|
|
|
|
|
|
|
q = malloc(sizeof(*q));
|
|
|
|
q->val = nombre;
|
|
|
|
q->suiv = *p;
|
|
|
|
*p = q;
|
|
|
|
}
|
|
|
|
|
|
|
|
void depile(Pile *p) {
|
|
|
|
struct maillon *q;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
if (est_vide(*p)) {
|
|
|
|
printf("La pile est vide\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
x = (*p)->val;
|
|
|
|
q = *p;
|
|
|
|
*p = (*p)->suiv;
|
|
|
|
free(q);
|
|
|
|
|
|
|
|
printf("Valeur dépilée : %d\n", x);
|
|
|
|
}
|
|
|
|
|
|
|
|
int valeur_top(Pile p) {
|
|
|
|
return p->val;
|
|
|
|
}
|
|
|
|
|
2021-10-24 19:35:22 +02:00
|
|
|
Pile* selection_pile(Pile *p1, Pile *p2, Pile *p3, int num_pile) {
|
2021-10-24 14:23:33 +02:00
|
|
|
switch (num_pile) {
|
|
|
|
case 1:
|
|
|
|
return p1;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
return p2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return p3;
|
|
|
|
}
|
|
|
|
}
|