efrei/algorithmique/structures-de-donnees/hanoi.c

137 lines
2.7 KiB
C

/* 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);
ajout_tous_disques(&p2);
while (!partie_finie(p1, p2, p3)) {
affiche_etat_piles(p1, p2, p3);
faire_coup(&p1, &p2, &p3);
}
printf("Bravo, vous avez terminé\n");
return 0;
}
void ajout_tous_disques(Pile *p) {
int nombre_disques;
printf("Combien de disques ? ");
scanf("%d", &nombre_disques);
for (int i = nombre_disques; i >= 1; i--) {
empile(p, i);
}
}
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);
}
}
void faire_coup(Pile *p1, Pile *p2, Pile *p3) {
int num_pile, diam;
Pile pile_a_depiler, pile_ou_empiler;
printf("Où voulez-vous prendre le disque ? ");
scanf("%d", &num_pile);
pile_a_depiler = *selection_pile(p1, p2, p3, num_pile);
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);
pile_ou_empiler = *selection_pile(p1, p2, p3, num_pile);
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;
}
Pile* selection_pile(Pile *p1, Pile *p2, Pile *p3, int num_pile) {
switch (num_pile) {
case 1:
return p1;
break;
case 2:
return p2;
break;
default:
return p3;
}
}