/* Pour des raisons de simplicité, la plupart des fonctions ne prennent aucun argument et ne renvoient rien. En effet, cela permet de créer les pièces voulues directement dans la fonction, et non dans le main. Les interfaces donnent le type hypothétique de la fonction. Pour respecter cela, il suffit de mettre en argument les éléments définis au début de la fonction.
*/
// Définition de la structure d'une pièce de puzzle
typedef struct Piece Piece;
struct Piece
{
int bas; // couleur du bas
int gauche; // couleur de gauche
int haut; // couleur du haut
int droite; // couleur de droite
int rotation; // angle de rotation
int ligne; // ligne sur laquelle est placée la pièce dans le puzzle
int colonne; // colonne sur laquelle est placée la pièce dans le puzzle
};
// Fonction de création de pièces
/* Interface make_piece
type : int*int*int*int*int -> Piece
arg : pour une pièce : couleur du bas, couleur de gauche, couleur du haut, couleur de droite, angle de rotation
pre : les couleurs sont des chiffres compris entre 1 et 4, la rotation est 0, 90, 180 ou 270
post : crée une pièce avec les paramètres donnés en argument
*/
Piece make_piece(int b, int g, int h, int d, int r)
{
Piece p;
p.bas = b; // 1er argument donne la couleur du bas
p.gauche = g; // 2ème argument donne la couleur de gauche
p.haut = h; // 3ème argument donne la couleur du haut
p.droite = d; // 4ème argument donne la couleur de droite
p.rotation = r; // 5ème argument donne l'angle de rotation
return(p); // renvoie la pièce créée
}
// Définition de la structure d'un puzzle
typedef struct Puzzle Puzzle;
struct Puzzle
{
int longueur; // longueur L du puzzle (nombre de colonnes)
int largeur; // largeur l du puzzle (nombre de lignes)
Piece *piecesDispo; // tableau de pièces disponibles, utilisables pour remplir le puzzle
FILE *solutionCourante; // fichier contenant une solution du puzzle
};
/* *** Pour afficher les pièces *** */
void affichePiece(struct Piece p)
{
printf("Piece : %d %d %d %d\n", p.bas, p.gauche, p.haut, p.droite);
}
/* *** Pour afficher un puzzle *** */
void affichePuzzle(struct Puzzle puz)
{
int i;
int L = puz.longueur;
int l = puz.largeur;
printf("\nPuzzle : \n");
for(i=1;i<=L*l;i++)
{
affichePiece(puz.piecesDispo[i]);
}
}
// Fonction de recherche du nombre de pièces bien placées dans un puzzle
/* Interface check_solution
type : Puzzle -> int
arg : puz un puzzle
pre : on considère un puzzle tel que p[1] est la pièce en haut à gauche, p[2] celle de droite, ... etc)
post : retourne le nombre de pièces bien placées dans le puzzle, c'est-à-dire respectant les contraintes de frontières avec les autres pièces autour
*/
void check_solution()
{
Puzzle *puz;
puz=(Puzzle*)malloc(sizeof(Puzzle));
Piece *p;
p=(Piece *)malloc(20*sizeof(Piece));
int L=puz->longueur;
int l=puz->largeur;
L = 4;
l = 4;
/* Test 1 :
Réponse : 8 pièces bien placées
p[1].bas=2;
p[1].gauche=3;
p[1].haut=3;
p[1].droite=1;
p[1].rotation=0;
p[1].ligne=1;
p[1].colonne=1;
p[2].bas=3;
p[2].gauche=1;
p[2].haut=3;
p[2].droite=2;
p[2].rotation=90;
p[2].ligne=1;
p[2].colonne=2;
p[3].bas=4;
p[3].gauche=2;
p[3].haut=1;
p[3].droite=4;
p[3].rotation=180;
p[3].ligne=2;
p[3].colonne=1;
p[4].bas=2;
p[4].gauche=2;
p[4].haut=2;
p[4].droite=2;
p[4].rotation=270;
p[4].ligne=2;
p[4].colonne=2;
p[5].bas=4;
p[5].gauche=1;
p[5].haut=2;
p[5].droite=3;
p[5].rotation=28;
p[5].ligne=3;
p[5].colonne=1;
p[6].bas=2;
p[6].gauche=3;
p[6].haut=3;
p[6].droite=1;
p[6].rotation=0;
p[6].ligne=3;
p[6].colonne=2;
p[7].bas=4;
p[7].gauche=1;
p[7].haut=4;
p[7].droite=2;
p[7].rotation=0;
p[7].ligne=1;
p[7].colonne=1;
p[8].bas=4;
p[8].gauche=2;
p[8].haut=3;
p[8].droite=1;
p[8].rotation=0;
p[8].ligne=1;
p[8].colonne=1;
p[9].bas=3;
p[9].gauche=4;
p[9].haut=2;
p[9].droite=1;
p[9].rotation=0;
p[9].ligne=1;
p[9].colonne=1;
p[10].bas=1;
p[10].gauche=2;
p[10].haut=2;
p[10].droite=3;
p[10].rotation=0;
p[10].ligne=1;
p[10].colonne=1;
p[11].bas=1;
p[11].gauche=3;
p[11].haut=4;
p[11].droite=3;
p[11].rotation=0;
p[11].ligne=1;
p[11].colonne=1;
p[12].bas=3;
p[12].gauche=3;
p[12].haut=4;
p[12].droite=1;
p[12].rotation=0;
p[12].ligne=1;
p[12].colonne=1;
p[13].bas=4;
p[13].gauche=1;
p[13].haut=3;
p[13].droite=2;
p[13].rotation=0;
p[13].ligne=1;
p[13].colonne=1;
p[14].bas=1;
p[14].gauche=1;
p[14].haut=2;
p[14].droite=4;
p[14].rotation=0;
p[14].ligne=1;
p[14].colonne=1;
p[15].bas=3;
p[15].gauche=4;
p[15].haut=1;
p[15].droite=4;
p[15].rotation=0;
p[15].ligne=1;
p[15].colonne=1;
p[16].bas=4;
p[16].gauche=4;
p[16].haut=3;
p[16].droite=1;
p[16].rotation=0;
p[16].ligne=1;
p[16].colonne=1;*/
/* Test 2 :
Réponse : 16 pièces bien placées
p[1].bas=2;
p[1].gauche=1;
p[1].haut=4;
p[1].droite=2;
p[1].rotation=0;
p[1].ligne=1;
p[1].colonne=1;
p[2].bas=4;
p[2].gauche=2;
p[2].haut=4;
p[2].droite=2;
p[2].rotation=90;
p[2].ligne=1;
p[2].colonne=2;
p[3].bas=1;
p[3].gauche=2;
p[3].haut=1;
p[3].droite=3;
p[3].rotation=180;
p[3].ligne=1;
p[3].colonne=3;
p[4].bas=4;
p[4].gauche=3;
p[4].haut=3;
p[4].droite=3;
p[4].rotation=270;
p[4].ligne=1;
p[4].colonne=4;
p[5].bas=1;
p[5].gauche=3;
p[5].haut=2;
p[5].droite=3;
p[5].rotation=28;
p[5].ligne=2;
p[5].colonne=1;
p[6].bas=2;
p[6].gauche=3;
p[6].haut=4;
p[6].droite=4;
p[6].rotation=0;
p[6].ligne=2;
p[6].colonne=2;
p[7].bas=1;
p[7].gauche=4;
p[7].haut=1;
p[7].droite=2;
p[7].rotation=0;
p[7].ligne=2;
p[7].colonne=3;
p[8].bas=3;
p[8].gauche=2;
p[8].haut=4;
p[8].droite=1;
p[8].rotation=0;
p[8].ligne=2;
p[8].colonne=4;
p[9].bas=2;
p[9].gauche=2;
p[9].haut=1;
p[9].droite=3;
p[9].rotation=0;
p[9].ligne=3;
p[9].colonne=1;
p[10].bas=3;
p[10].gauche=3;
p[10].haut=2;
p[10].droite=4;
p[10].rotation=0;
p[10].ligne=3;
p[10].colonne=2;
p[11].bas=2;
p[11].gauche=4;
p[11].haut=1;
p[11].droite=2;
p[11].rotation=0;
p[11].ligne=3;
p[11].colonne=3;
p[12].bas=4;
p[12].gauche=2;
p[12].haut=3;
p[12].droite=3;
p[12].rotation=0;
p[12].ligne=3;
p[12].colonne=4;
p[13].bas=1;
p[13].gauche=3;
p[13].haut=2;
p[13].droite=1;
p[13].rotation=0;
p[13].ligne=4;
p[13].colonne=1;
p[14].bas=2;
p[14].gauche=1;
p[14].haut=3;
p[14].droite=1;
p[14].rotation=0;
p[14].ligne=4;
p[14].colonne=2;
p[15].bas=3;
p[15].gauche=1;
p[15].haut=2;
p[15].droite=4;
p[15].rotation=0;
p[15].ligne=4;
p[15].colonne=3;
p[16].bas=3;
p[16].gauche=4;
p[16].haut=4;
p[16].droite=2;
p[16].rotation=0;
p[16].ligne=4;
p[16].colonne=4;
*/
int i=1; // numéro de la pièce
int k=1;
int j=0; // compteur de pièces bien placées
// Nous allons parcourir le puzzle méthodiquement, en commençant par les coins, puis les extrémités, puis l'intérieur
// coin en haut à gauche
if (p[1].droite == p[2].gauche && p[1].bas == p[1+L].haut)
{
j++;
}
// coin en bas à gauche
if (p[1+(l-1)*L].haut == p[1+(l-2)*L].bas && p[1+(l-1)*L].droite == p[2+(l-1)*L].gauche)
{
j++;
}
// coin en haut à droite
if (p[L].gauche == p[L-1].droite && p[L].bas == p[2*L].haut)
{
j++;
}
// coin en bas à droite
if (p[l*L].gauche == p[l*L-1].droite && p[l*L].haut == p[(l-1)*L].bas)
{
j++;
}
// première colonne
for (i=L+1;i<=1+(l-2)*L;i+=L)
{
if ( (p[i].haut == p[i-L].bas) && (p[i].droite == p[i+1].gauche) && (p[i].bas == p[i+L].haut))
{
j++;
}
}
// première ligne
for (i=2;i<=L-1;i++)
{
if (p[i].gauche == p[i-1].droite && p[i].bas == p[i+L].haut && p[i].droite == p[i+1].gauche)
{
j++;
}
}
// dernière colonne
for (i=2*L;i<=(l-1)*L;i+=L)
{
if (p[i].haut == p[i-L].bas && p[i].gauche == p[i-1].droite && p[i].bas == p[i+L].haut)
{
j++;
}
}
// derniere ligne
for (i=L*(l-1)+2;i<=l*L-1;i++)
{
if (p[i].gauche == p[i-1].droite && p[i].haut == p[i-L].bas && p[i].droite == p[i+1].gauche)
{
j++;
}
}
// intérieur du puzzle sans les extrémités
for (k=1;k<=l-1;k++)
{
for (i=k*L+2;i<=(k+1)*L-1;i++)
{
if (p[i].gauche == p[i-1].droite && p[i].haut == p[i-L].bas && p[i].droite == p[i+1].gauche && p[i].bas == p[i+L].haut)
{
j++;
}
}
}
printf("%d",j); // affichage du compteur
free(puz);
free(p);
}
// Création d'un puzzle
/* Interface make_puzzle
type : FILE -> Puzzle
arg : un fichier contenant les éléments du puzzle
pre : le fichier doit avoir été créé au préalable et doit etre de la forme suivante
____________
longueur largeur
c1 c2 c3 c4 // pièce p[1]
c'1 c'2 c'3 c'4 // pièce p[2]
... etc
____________
et ne doit pas comporter d'espaces ou de caractères supplémentaires
post : renvoie le puzzle formé par les éléments du fichier
raises : le fichier n'a pas été créé au préalable -> "Erreur make_puzzle : fichier inexistant"
*/
Puzzle make_puzzle (char *(nomFich))
{
struct Puzzle puz;
FILE* fichier = NULL;
fichier = fopen("puzzle.txt", "r+"); // puzzle.txt doit etre créé au préalable
if (fichier == NULL) // si le fichier n'a pas été créé au préalable
{
printf("Erreur make_puzzle : fichier inexistant\n");
}
else
{
fscanf(fichier, "%d %d", &(puz.longueur), &(puz.largeur)); // récupère la longueur et la largeur
printf("Le puzzle est de taille %d*%d\n", puz.longueur, puz.largeur); // affiche la taille du puzzle
// Replacement du curseur en fonction du nombre de caractères contenu dans la longueur et la largeur du puzzle
if (puz.longueur<=9 && puz.largeur<=9)
{
fseek(fichier,4,SEEK_SET);
}
else if (puz.longueur>=10 && puz.largeur<=9)
{
fseek(fichier,5,SEEK_SET);
}
else if (puz.longueur<=9 && puz.largeur>=10)
{
fseek(fichier,5,SEEK_SET);
}
else
{
fseek(fichier,6,SEEK_SET);
}
int i=0;
char c;
char *chaine = NULL;
int taille = 9*(puz.longueur)*(puz.largeur); // 9 pour 4 couleurs, 4 espaces et un '\n'
chaine = malloc(taille*sizeof(char));
while((c=fgetc(fichier)) != EOF) // Récupére tous les caractères du fichier (espaces et \n inclus)
{
chaine[i]=c;
i++;
}
for (i=1;i {
printf("%c", chaine[i]);;
}
printf("\n");
int* z;
z = malloc(10*taille*sizeof(char));
int add = 0;
int add2 = 0;
for (i=1;i {
switch (chaine[i+add2])
{
case 'B':
z[i+add2]=1;
break;
case 'J':
z[i+add2]=2;
break;
case 'R':
z[i+add2]=3;
break;
case 'V':
z[i+add2]=4;
break;
default:
z[i+add2]=0;
break;
}
add++;
if (add == 4) // quand on a écrit 4 couleurs (donc une pièce)
{
add = 0;
add2++; // on décale à cause de l'espace
}
}
// Replacement du curseur en fonction du nombre de caractères contenu dans la longueur et la largeur du puzzle
if (puz.longueur<=9 && puz.largeur<=9)
{
fseek(fichier,4,SEEK_SET);
}
else if (puz.longueur>=10 && puz.largeur<=9)
{
fseek(fichier,5,SEEK_SET);
}
else if (puz.longueur<=9 && puz.largeur>=10)
{
fseek(fichier,5,SEEK_SET);
}
else
{
fseek(fichier,6,SEEK_SET);
}
int j=1;
int k;
struct Piece* p=(Piece*)malloc(taille*sizeof(struct Piece));
for (k=1;k<=(puz.largeur*puz.longueur);k++)
{
p[k]=make_piece(z[j+8*(k-1)],z[j+2+8*(k-1)],z[j+4+8*(k-1)],z[j+6+8*(k-1)],0);
j++;
}
fclose(fichier);
puz.piecesDispo=p;
for (k=1;k<=6;k++) // On affiche toutes les pièces ainsi créées à partir du fichier
{
affichePiece(p[k]);
}
free(chaine);
free(z);
free(p);
return(puz);
}
}
// Ecriture de la solution du puzzle dans un fichier
/* Interface write_solution
type : Puzzle -> FILE
arg : puz un puzzle
pre : puz doit etre correctement construit, complet, et ne pas contenir d'erreur
post : écrit la solution du puzzle dans un fichier nommé "solution.txt"
*/
void write_solution ()
{
Puzzle *puz;
puz=(Puzzle*)malloc(sizeof(Puzzle));
puz->longueur = 3; // Pour le test
puz->largeur = 2;
Piece *p;
p=(Piece *)malloc(10*sizeof(Piece)); // Remplacer de manière à définir + de mémoire qu'il n'y a de pièces. Le passage par des variables L et l ne fonctionne pas dans cette fonction mais fonctionne dans les autres...
int i;
// Définition des chaines de caractères nécéssaires pour écrire dans le fichier
char cbas[(puz->longueur)*(puz->largeur)+1];
char cgauche[(puz->longueur)*(puz->largeur)+1];
char chaut[(puz->longueur)*(puz->largeur)+1];
char cdroite[(puz->longueur)*(puz->largeur)+1];
// Test avec les valeurs suivantes
/* p[1].bas=1;
p[1].gauche=2;
p[1].haut=3;
p[1].droite=1;
p[1].rotation=0;
p[1].ligne=1;
p[1].colonne=1;
p[2].bas=4;
p[2].gauche=3;
p[2].haut=2;
p[2].droite=1;
p[2].rotation=90;
p[2].ligne=1;
p[2].colonne=2;
p[3].bas=1;
p[3].gauche=1;
p[3].haut=2;
p[3].droite=2;
p[3].rotation=180;
p[3].ligne=2;
p[3].colonne=1;
p[4].bas=3;
p[4].gauche=3;
p[4].haut=3;
p[4].droite=4;
p[4].rotation=270;
p[4].ligne=2;
p[4].colonne=2;
p[5].bas=4;
p[5].gauche=4;
p[5].haut=4;
p[5].droite=4;
p[5].rotation=0;
p[5].ligne=3;
p[5].colonne=1;
p[6].bas=1;
p[6].gauche=2;
p[6].haut=3;
p[6].droite=1;
p[6].rotation=0;
p[6].ligne=3;
p[6].colonne=2;
*/
FILE* fichiersolution = NULL;
//puz->solutionCourante = fichiersolution;
fichiersolution = fopen("solution.txt","w");
// Changer les chiffres par le caractère correspondant
for (i=1;i<=((puz->longueur)*(puz->largeur));i++)
{
if (p[i].bas==1)
{
cbas[i]='B';
}
else if (p[i].bas==2)
{
cbas[i]='J';
}
else if (p[i].bas==3)
{
cbas[i]='R';
}
else if (p[i].bas==4)
{
cbas[i]='V';
}
if (p[i].haut==1)
{
chaut[i]='B';
}
else if (p[i].haut==2)
{
chaut[i]='J';
}
else if (p[i].haut==3)
{
chaut[i]='R';
}
else if (p[i].haut==4)
{
chaut[i]='V';
}
if (p[i].gauche==1)
{
cgauche[i]='B';
}
else if (p[i].gauche==2)
{
cgauche[i]='J';
}
else if (p[i].gauche==3)
{
cgauche[i]='R';
}
else if (p[i].gauche==4)
{
cgauche[i]='V';
}
if (p[i].droite==1)
{
cdroite[i]='B';
}
else if (p[i].droite==2)
{
cdroite[i]='J';
}
else if (p[i].droite==3)
{
cdroite[i]='R';
}
else if (p[i].droite==4)
{
cdroite[i]='V';
}
}
if (fichiersolution != NULL)
{
fprintf(fichiersolution,"%d %d\n",puz->longueur,puz->largeur); // affiche la longueur et la largeur du puzzle
for (i=1;i<=((puz->longueur)*(puz->largeur));i++) // affiche les couleurs des pièces, leur emplacement et leur rotation
{
fprintf(fichiersolution,"%c %c %c %c %d %d %d\n",cbas[i],cgauche[i],chaut[i],cdroite[i],p[i].ligne,p[i].colonne,p[i].rotation);
}
}
fclose(fichiersolution);
free(puz);
free(p);
}
/* *** Rotation *** */
/* Interface rotationPiece
type : Piece -> Piece
arg : p une pièce
pre : aucune
post : tourne les éléments de la pièce de 90°
*/
Piece rotationPiece (struct Piece p)
{
struct Piece pi;
struct Piece pi2;
// On fait tourner la pièce de 90° dans le sens des aiguilles d'une montre
pi.droite = p.haut;
pi.bas = p.droite;
pi.gauche = p.bas;
pi.haut = p.gauche;
pi.ligne = p.ligne;
pi.colonne = p.colonne;
// On réalise une copie du pointeur afin de pouvoir réaliser des rotations de rotations
pi2.droite = pi.droite;
pi2.bas = pi.bas;
pi2.gauche = pi.gauche;
pi2.haut = pi.haut;
pi2.ligne = pi.ligne;
pi2.colonne = pi.colonne;
return pi2;
}
/* Interface heuristique1
type : Puzzle -> Puzzle
arg : puz un puzzle
pre : aucune
post : si aucun problème ne se pose, renvoie le puzzle reformé selon les règles de l'heuristique
raises : en cas de placement de pièce impossible -> exit()
*/
void heuristique1 ()
{
Puzzle *puz;
puz=(Puzzle*)malloc(sizeof(Puzzle));
Piece *p;
p=(Piece *)malloc(10*sizeof(Piece));
int L = puz->longueur;
int l = puz->largeur;
/* L = 3;
l = 3;
p[1].bas=2;
p[1].gauche=2;
p[1].haut=2;
p[1].droite=3;
p[2].bas=2;
p[2].gauche=1;
p[2].haut=1;
p[2].droite=1;
p[3].bas=2;
p[3].gauche=1;
p[3].haut=2;
p[3].droite=2;
p[4].bas=2;
p[4].gauche=1;
p[4].haut=2;
p[4].droite=2;
p[5].bas=2;
p[5].gauche=2;
p[5].haut=1;
p[5].droite=2;
p[6].bas=3;
p[6].gauche=3;
p[6].haut=3;
p[6].droite=3;
p[7].bas=4;
p[7].gauche=4;
p[7].haut=3;
p[7].droite=4;
p[8].bas=3;
p[8].gauche=1;
p[8].haut=1;
p[8].droite=1;
p[9].bas=1;
p[9].gauche=1;
p[9].haut=1;
p[9].droite=4;
*/
int i; // numéro de la pièce
int col=2; // numéro de la colonne
int lig; // numéro de la ligne
for (i=1;i<=l*L;i++) // initialisation des lignes et colonnes
{
p[i].ligne = 0;
p[i].colonne = 0;
p[i].rotation = 0;
}
// La pièce en haut à gauche est la pièce p[1]
p[1].colonne = 1;
p[1].ligne = 1;
int j;
struct Piece q = p[1]; // q gardera en mémoire la pièce qu'on place, pour pouvoir comparer avec la suivante à placer
// Premiere ligne
for (col=2;col<=L;col++)
{
for (i=2;i<=L*l;i++) // boucle sur les pieces p[i]
{
if (p[i].gauche == q.droite && p[i].ligne == 0) // p[i].ligne == 0 assure que la pièce n'a pas été utilisée
{
p[i].ligne = 1;
p[i].colonne = col;
q = p[i]; // on place p[i] et on la garde en mémoire pour la prochaine itération
break; // sort de la boucle pour entamer une nouvelle colonne
}
else if (rotationPiece(p[i]).gauche == q.droite && p[i].ligne == 0) // rotation de 90°
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(p[i]); // lors d'une rotation, on donne à p[i] sa nouvelle "configuration", c'est-à-dire elle-meme mais tournée
p[i].rotation = 90;
q = p[i];
break;
}
else if (rotationPiece(rotationPiece(p[i])).gauche == q.droite && p[i].ligne == 0) // rotation de 180°
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
q = p[i];
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).gauche == q.droite && p[i].ligne == 0) // rotation de 270°
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
q = p[i];
break;
}
if (i == l*L) // si toutes les pièces n'ont pas respecté les conditions de placement, on exit
{
exit (5);
}
}
}
col = 1;
lig = 2;
q = p[1];
/* Maintenant, pour le reste du puzzle, le principe est le meme, à ceci près que l'on rajoute une boucle pour se déplacer sur les lignes du puzzle (de 2 à l) et qu'il faudra garder 3 pièces en mémoire.
q gardera en mémoire la première pièce d'une ligne, afin de pouvoir placer celle en dessous sur la première colonne
s aura le meme effet que le q de la première partie, c'est-à-dire sauvegarder la pièce que l'on place
r gardera en mémoire la pièce placée une case à droite et une case en haut de s, et se déplacera de la meme façon que s
Le but de cette manoeuvre est de pouvoir placer une pièce p[i] en la comparant à s (à sa gauche) et à r (au dessus) et de pouvoir faire "glisser" r et s le long de la ligne
*/
struct Piece r;
struct Piece s;
s = p[L+1];
for (lig=2;lig<=l;lig++) // lignes 2 à l
{
for (i=2;i<=l*L;i++) // initialisation de r à chaque fois qu'une nouvelle ligne débute
{
if (p[i].ligne == lig-1 && p[i].colonne == 2)
{
r = p[i];
break;
}
}
for (col=1;col<=L;col++)
{
if (col == 1) // si on est sur la première colonne, il suffit de comparer avec q qui est au dessus
{
for (i=2;i<=l*L;i++)
{
if (p[i].haut == q.bas && p[i].ligne == 0) // on vérifiera toujours que p[i].ligne = 0
{
p[i].ligne = lig;
p[i].colonne = col;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(p[i]).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(rotationPiece(p[i])).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
q = p[i];
s = p[i];
break;
}
if (i == l*L) // si on ne trouve pas de pièce plaçable, on exit
{
exit(6);
}
}
}
else if (col <= L && col > 1) // pour les autres colonnes, on compare avec s à gauche, et r en haut
{
for (i=2;i<=l*L;i++)
{
if (p[i].gauche == s.droite && p[i].haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
s = p[i]; // s devient la nouvelle pièce
for (j=2;j<=l*L;j++) // on déplace r selon les coordonnées
{
if (p[j].ligne == lig-1 && p[j].colonne == col+1)
{
r = p[j];
}
}
break;
}
else if (rotationPiece(p[i]).gauche == s.droite && rotationPiece(p[i]).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
s = p[i];
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == lig-1 && p[j].colonne == col+1)
{
r = p[j];
}
}
break;
}
else if (rotationPiece(rotationPiece(p[i])).gauche == s.droite && rotationPiece(rotationPiece(p[i])).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
s = p[i];
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == lig-1 && p[j].colonne == col+1)
{
r = p[j];
break;
}
}
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).gauche == s.droite && rotationPiece(rotationPiece(rotationPiece(p[i]))).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
s = p[i];
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == lig-1 && p[j].colonne == col+1)
{
r = p[j];
}
}
break;
}
if (i == l*L) // si aucune pièce plaçable, exit
{
exit(7);
}
}
}
}
}
// On affiche les coordonnées de toutes les pièces
printf("%d %d %d\n",p[1].ligne, p[1].colonne, p[1].rotation);
printf("%d %d %d\n",p[2].ligne, p[2].colonne, p[2].rotation);
printf("%d %d %d\n",p[3].ligne, p[3].colonne, p[3].rotation);
printf("%d %d %d\n",p[4].ligne, p[4].colonne, p[4].rotation);
printf("%d %d %d\n",p[5].ligne, p[5].colonne, p[5].rotation);
printf("%d %d %d\n",p[6].ligne, p[6].colonne, p[6].rotation);
printf("%d %d %d\n",p[7].ligne, p[7].colonne, p[7].rotation);
printf("%d %d %d\n",p[8].ligne, p[8].colonne, p[8].rotation);
printf("%d %d %d\n",p[9].ligne, p[9].colonne, p[9].rotation);
free(puz);
free(p);
}
/* Interface heuristique2
type : Puzzle -> Puzzle
arg : puz un puzzle
pre : aucune
post : si aucun problème ne se pose, renvoie le puzzle reformé selon les règles de l'heuristique
en cas de placement de pièce impossible -> laisse une case vide
*/
void heuristique2 ()
{
/* Le principe de cette fonction est le meme que précédemment. Simplement, au lieu d'exit, on donne aux variables q, s et r des cases vides, qui ont comme couleur : 0.
Il faudra ensuite traiter tous les cas (s case vide ou non, r case vide ou non, q case vide ou non) pour placer les pièces. D'où la longueur de la fonction
*/
Puzzle *puz;
puz=(Puzzle*)malloc(sizeof(Puzzle));
int L = puz->longueur;
int l = puz->largeur;
L = 3;
l = 3;
Piece *p;
p=(Piece *)malloc((l*L+1)*sizeof(Piece));
/* p[1].bas=2;
p[1].gauche=1;
p[1].haut=1;
p[1].droite=1;
p[2].bas=4;
p[2].gauche=4;
p[2].haut=4;
p[2].droite=4;
p[3].bas=2;
p[3].gauche=2;
p[3].haut=2;
p[3].droite=2;
p[4].bas=2;
p[4].gauche=2;
p[4].haut=2;
p[4].droite=2;
p[5].bas=1;
p[5].gauche=1;
p[5].haut=1;
p[5].droite=1;
p[6].bas=1;
p[6].gauche=1;
p[6].haut=3;
p[6].droite=1;
p[7].bas=3;
p[7].gauche=3;
p[7].haut=3;
p[7].droite=3;
p[8].bas=1;
p[8].gauche=1;
p[8].haut=1;
p[8].droite=1;
p[9].bas=1;
p[9].gauche=1;
p[9].haut=1;
p[9].droite=1;
*/
/* p[1].bas=1;
p[1].gauche=2;
p[1].haut=3;
p[1].droite=4;
p[2].bas=2;
p[2].gauche=3;
p[2].haut=4;
p[2].droite=4;
p[3].bas=1;
p[3].gauche=4;
p[3].haut=2;
p[3].droite=3;
p[4].bas=1;
p[4].gauche=1;
p[4].haut=2;
p[4].droite=1;
p[5].bas=2;
p[5].gauche=3;
p[5].haut=1;
p[5].droite=3;
p[6].bas=4;
p[6].gauche=4;
p[6].haut=3;
p[6].droite=3;
p[7].bas=1;
p[7].gauche=2;
p[7].haut=3;
p[7].droite=3;
p[8].bas=1;
p[8].gauche=4;
p[8].haut=4;
p[8].droite=2;
p[9].bas=1;
p[9].gauche=1;
p[9].haut=1;
p[9].droite=4;
*/
// cases vides
Piece *cv;
cv=(Piece *)malloc((l*L+1)*sizeof(Piece));
/* cv[1].ligne = 1;
cv[1].colonne = 1;
cv[2].ligne = 1;
cv[2].colonne = 2;
cv[3].ligne = 1;
cv[3].colonne = 3;
cv[4].ligne = 2;
cv[4].colonne = 1;
cv[5].ligne = 2;
cv[5].colonne = 2;
cv[6].ligne = 2;
cv[6].colonne = 3;
cv[7].ligne = 3;
cv[7].colonne = 1;
cv[8].ligne = 3;
cv[8].colonne = 2;
cv[9].ligne = 3;
cv[9].colonne = 3;
*/
int col=2; // numéro de la colonne
int lig; // numéro de la ligne
for (i=1;i<=l*L;i++)
{
p[i].ligne = 0;
p[i].colonne = 0;
p[i].rotation = 0;
}
p[1].colonne = 1;
p[1].ligne = 1;
int j;
int k;
struct Piece q = p[1];
// Premiere ligne
for (col=2;col<=L;col++)
{
for (i=2;i<=L*l;i++) // boucle sur les pieces p[i]
{
if (q.bas != 0) // si q n'est pas une case vide, idem que heuristique1
{
if (p[i].gauche == q.droite && p[i].ligne == 0)
{
p[i].ligne = 1;
p[i].colonne = col;
q = p[i];
break;
}
else if (rotationPiece(p[i]).gauche == q.droite && p[i].ligne == 0)
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
q = p[i];
break;
}
else if (rotationPiece(rotationPiece(p[i])).gauche == q.droite && p[i].ligne == 0)
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
q = p[i];
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).gauche == q.droite && p[i].ligne == 0)
{
p[i].ligne = 1;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
q = p[i];
break;
}
}
if (q.bas == 0) // si q case vide, on peut placer n'importe quelle pièce à la suite sur la ligne 1
{
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == 0)
{
p[j].ligne = 1;
p[j].colonne = col;
q=p[j];
break;
}
}
break;
}
if (i == l*L) // si aucune pièce n'est plaçable, on crée une case vide
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == 1 && cv[j].colonne == col)
{
q = cv[j];
break;
}
}
}
}
}
col = 1;
lig = 2;
q = p[1];
/* Le meme principe va etre répété pour tout le puzzle.
*/
struct Piece r;
struct Piece s;
// de la ligne 2 jusqu'au bout
for (lig=2;lig<=l;lig++)
{
for (i=2;i<=l*L;i++) // initialisation de r
{
if (p[i].ligne == lig-1 && p[i].colonne == 2)
{
r = p[i];
break;
}
if (i == l*L)
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == lig-1 && cv[j].colonne == 2)
{
r = cv[j];
break;
}
}
}
}
for (col=1;col<=L;col++)
{
if (col == 1) // pour la première case de la ligne
{
if (q.bas != 0) // idem à heuristique1
{
for (i=2;i<=(l*L);i++)
{
if (p[i].haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(p[i]).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(rotationPiece(p[i])).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
q = p[i];
s = p[i];
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).haut == q.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
q = p[i];
s = p[i];
break;
}
if (i == l*L) // si pas de pièce plaçable, on crée une case vide
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == lig && cv[j].colonne == col)
{
printf("%d\n",j);
q = cv[j];
s = cv[j];
break;
}
}
}
}
}
else if (q.bas == 0) // sur la colonne 1, on peut placer n'importe quelle pièce si celle du dessus est vide
{
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == 0)
{
p[j].ligne = lig;
p[j].colonne = col;
q=p[j];
s=p[j];
break;
}
}
}
}
else if (col <= L && col > 1) // pour compléter la ligne
{
if (r.bas != 0 && s.bas != 0) // si r et s ne sont pas des cases vides
{
for (i=2;i<=(l*L);i++)
{
if (p[i].gauche == s.droite && p[i].haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(p[i]).gauche == s.droite && rotationPiece(p[i]).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(p[i])).gauche == s.droite && rotationPiece(rotationPiece(p[i])).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).gauche == s.droite && rotationPiece(rotationPiece(rotationPiece(p[i]))).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
}
if (i == l*L)
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == lig && cv[j].colonne == col)
s = cv[j];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (k == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
break;
}
}
break;
}
}
}
}
}
else if (r.bas != 0 && s.bas == 0) // si r est une case non vide, et s une case vide
{
for (i=2;i<=l*L;i++)
{
if (p[i].haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(p[i]).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(p[i])).haut == r.bas && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).haut == r.bas && rotationPiece(rotationPiece(rotationPiece(p[i]))).ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
}
if (i == l*L)
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == lig && cv[j].colonne == col)
{
s = cv[j];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (k == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
break;
}
}
}
}
}
}
}
else if (r.bas == 0 && s.bas != 0) // si r est une case vide, et s une case non vide
{
for (i=2;i<=(l*L);i++)
{
if (p[i].gauche == s.droite && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(p[i]).gauche == s.droite && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(p[i]);
p[i].rotation = 90;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(p[i])).gauche == s.droite && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(p[i]));
p[i].rotation = 180;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
else if (rotationPiece(rotationPiece(rotationPiece(p[i]))).gauche == s.droite && p[i].ligne == 0)
{
p[i].ligne = lig;
p[i].colonne = col;
p[i] = rotationPiece(rotationPiece(rotationPiece(p[i])));
p[i].rotation = 270;
s = p[i];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
}
if (i == l*L)
{
for (j=2;j<=l*L;j++)
{
if (cv[j].ligne == lig && cv[j].colonne == col)
{
s = cv[j];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (k == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
break;
}
}
}
}
}
}
}
else if (r.bas == 0 && s.bas == 0) // si r et s sont des cases vides
{
for (j=2;j<=l*L;j++)
{
if (p[j].ligne == 0)
{
p[j].ligne = lig;
p[j].colonne = col;
s=p[j];
for (k=2;k<=l*L;k++)
{
if (p[k].ligne == lig-1 && p[k].colonne == col+1)
{
r = p[k];
break;
}
if (i == l*L)
{
for (k=2;k<=l*L;k++)
{
if (cv[k].ligne == lig-1 && cv[k].colonne == col+1)
{
r = cv[k];
break;
}
}
}
}
break;
}
}
}
}
}
}
// affichage des emplacements des pièces
printf("%d %d %d\n",p[1].ligne, p[1].colonne, p[1].rotation);
printf("%d %d %d\n",p[2].ligne, p[2].colonne, p[2].rotation);
printf("%d %d %d\n",p[3].ligne, p[3].colonne, p[3].rotation);
printf("%d %d %d\n",p[4].ligne, p[4].colonne, p[4].rotation);
printf("%d %d %d\n",p[5].ligne, p[5].colonne, p[5].rotation);
printf("%d %d %d\n",p[6].ligne, p[6].colonne, p[6].rotation);
printf("%d %d %d\n",p[7].ligne, p[7].colonne, p[7].rotation);
printf("%d %d %d\n",p[8].ligne, p[8].colonne, p[8].rotation);
printf("%d %d %d\n",p[9].ligne, p[9].colonne, p[9].rotation);
free(puz);
free(p);
free(cv);
}
/* Interface remplacer
type : (Puzzle*Piece) -> void
arg : puz un puzzle
pre : on considère un puzzle bien construit et sans erreur
post : dit si une pièce peut remplacer celles du puzzle
*/
void remplacer ()
{
Puzzle *puz;
puz=(Puzzle*)malloc(sizeof(Puzzle));
Piece *p;
p=(Piece *)malloc(20*sizeof(Piece));
int L=puz->longueur;
int l=puz->largeur;
// p[0] est la pièce à tenter de remplacer dans le puzzle
/* p[0].bas=4;
p[0].gauche=4;
p[0].haut=2;
p[0].droite=3;
p[0].rotation=0;
p[0].ligne=0;
p[0].colonne=0;*/
// On considère un puzzle tel que p[1] est la pièce en haut à gauche, p[2] celle de droite, ... etc)
/* L = 4;
l = 4;
p[1].bas=2;
p[1].gauche=1;
p[1].haut=4;
p[1].droite=2;
p[1].rotation=0;
p[1].ligne=1;
p[1].colonne=1;
p[2].bas=4;
p[2].gauche=2;
p[2].haut=4;
p[2].droite=2;
p[2].rotation=90;
p[2].ligne=1;
p[2].colonne=2;
p[3].bas=1;
p[3].gauche=2;
p[3].haut=1;
p[3].droite=3;
p[3].rotation=180;
p[3].ligne=1;
p[3].colonne=3;
p[4].bas=4;
p[4].gauche=3;
p[4].haut=3;
p[4].droite=3;
p[4].rotation=270;
p[4].ligne=1;
p[4].colonne=4;
p[5].bas=1;
p[5].gauche=3;
p[5].haut=2;
p[5].droite=3;
p[5].rotation=28;
p[5].ligne=2;
p[5].colonne=1;
p[6].bas=2;
p[6].gauche=3;
p[6].haut=4;
p[6].droite=4;
p[6].rotation=0;
p[6].ligne=2;
p[6].colonne=2;
p[7].bas=1;
p[7].gauche=4;
p[7].haut=1;
p[7].droite=2;
p[7].rotation=0;
p[7].ligne=2;
p[7].colonne=3;
p[8].bas=3;
p[8].gauche=2;
p[8].haut=4;
p[8].droite=1;
p[8].rotation=0;
p[8].ligne=2;
p[8].colonne=4;
p[9].bas=2;
p[9].gauche=2;
p[9].haut=1;
p[9].droite=3;
p[9].rotation=0;
p[9].ligne=3;
p[9].colonne=1;
p[10].bas=3;
p[10].gauche=3;
p[10].haut=2;
p[10].droite=4;
p[10].rotation=0;
p[10].ligne=3;
p[10].colonne=2;
p[11].bas=2;
p[11].gauche=4;
p[11].haut=1;
p[11].droite=2;
p[11].rotation=0;
p[11].ligne=3;
p[11].colonne=3;
p[12].bas=4;
p[12].gauche=2;
p[12].haut=3;
p[12].droite=3;
p[12].rotation=0;
p[12].ligne=3;
p[12].colonne=4;
p[13].bas=1;
p[13].gauche=3;
p[13].haut=2;
p[13].droite=1;
p[13].rotation=0;
p[13].ligne=4;
p[13].colonne=1;
p[14].bas=2;
p[14].gauche=1;
p[14].haut=3;
p[14].droite=1;
p[14].rotation=0;
p[14].ligne=4;
p[14].colonne=2;
p[15].bas=3;
p[15].gauche=1;
p[15].haut=2;
p[15].droite=4;
p[15].rotation=0;
p[15].ligne=4;
p[15].colonne=3;
p[16].bas=3;
p[16].gauche=4;
p[16].haut=4;
p[16].droite=2;
p[16].rotation=0;
p[16].ligne=4;
p[16].colonne=4;*/
int i;
int k;
/* Le principe est le meme que dans la question 4. On examinera d'abord les coins, puis les extrémités, puis l'intérieur du puzzle. Il faudra séparer les cas où on fait rotater la pièce qui remplace.
*/
printf("Possibilites de remplacement de la piece : bas %d, gauche %d, haut %d, droite %d\n", p[0].bas, p[0].gauche, p[0].haut, p[0].droite);
/* Sans rotation */
// coin en haut à gauche
if (p[0].droite == p[2].gauche && p[0].bas == p[1+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[1].ligne,p[1].colonne);
}
// coin en bas à gauche
if (p[0].haut == p[1+(l-2)*L].bas && p[0].droite == p[2+(l-1)*L].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[1+(l-1)*L].ligne,p[1+(l-1)*L].colonne);
}
// coin en haut à droite
if (p[0].gauche == p[L-1].droite && p[0].bas == p[2*L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[L].ligne,p[L].colonne);
}
// coin en bas à droite
if (p[0].gauche == p[l*L-1].droite && p[0].haut == p[(l-1)*L].bas)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[l*L].ligne,p[l*L].colonne);
}
// première colonne
for (i=L+1;i<=1+(l-2)*L;i+=L)
{
if ( (p[0].haut == p[i-L].bas) && (p[0].droite == p[i+1].gauche) && (p[0].bas == p[i+L].haut))
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[i].ligne,p[i].colonne);
}
}
// première ligne
for (i=2;i<=L-1;i++)
{
if (p[0].gauche == p[i-1].droite && p[0].bas == p[i+L].haut && p[0].droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[i].ligne,p[i].colonne);
}
}
// dernière colonne
for (i=2*L;i<=(l-1)*L;i+=L)
{
if (p[0].haut == p[i-L].bas && p[0].gauche == p[i-1].droite && p[0].bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[i].ligne,p[i].colonne);
}
}
// derniere ligne
for (i=L*(l-1)+2;i<=l*L-1;i++)
{
if (p[0].gauche == p[i-1].droite && p[0].haut == p[i-L].bas && p[0].droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[i].ligne,p[i].colonne);
}
}
// puzzle sans les extrémités
for (k=1;k<=l-1;k++)
{
for (i=k*L+2;i<=(k+1)*L-1;i++)
{
if (p[0].gauche == p[i-1].droite && p[0].haut == p[i-L].bas && p[0].droite == p[i+1].gauche && p[0].bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 0\n",p[i].ligne,p[i].colonne);
}
}
}
/* Rotation de 90° */
// coin en haut à gauche
if (rotationPiece(p[0]).droite == p[2].gauche && rotationPiece(p[0]).bas == p[1+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[1].ligne,p[1].colonne);
}
// coin en bas à gauche
if (rotationPiece(p[0]).haut == p[1+(l-2)*L].bas && rotationPiece(p[0]).droite == p[2+(l-1)*L].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[1+(l-1)*L].ligne,p[1+(l-1)*L].colonne);
}
// coin en haut à droite
if (rotationPiece(p[0]).gauche == p[L-1].droite && rotationPiece(p[0]).bas == p[2*L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[L].ligne,p[L].colonne);
}
// coin en bas à droite
if (rotationPiece(p[0]).gauche == p[l*L-1].droite && rotationPiece(p[0]).haut == p[(l-1)*L].bas)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[l*L].ligne,p[l*L].colonne);
}
// première colonne
for (i=L+1;i<=1+(l-2)*L;i+=L)
{
if ( (rotationPiece(p[0]).haut == p[i-L].bas) && (rotationPiece(p[0]).droite == p[i+1].gauche) && (rotationPiece(p[0]).bas == p[i+L].haut))
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[i].ligne,p[i].colonne);
}
}
// première ligne
for (i=2;i<=L-1;i++)
{
if (rotationPiece(p[0]).gauche == p[i-1].droite && rotationPiece(p[0]).bas == p[i+L].haut && rotationPiece(p[0]).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[i].ligne,p[i].colonne);
}
}
// dernière colonne
for (i=2*L;i<=(l-1)*L;i+=L)
{
if (rotationPiece(p[0]).haut == p[i-L].bas && rotationPiece(p[0]).gauche == p[i-1].droite && rotationPiece(p[0]).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[i].ligne,p[i].colonne);
}
}
// derniere ligne
for (i=L*(l-1)+2;i<=l*L-1;i++)
{
if (rotationPiece(p[0]).gauche == p[i-1].droite && rotationPiece(p[0]).haut == p[i-L].bas && rotationPiece(p[0]).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[i].ligne,p[i].colonne);
}
}
// puzzle sans les extrémités
for (k=1;k<=l-1;k++)
{
for (i=k*L+2;i<=(k+1)*L-1;i++)
{
if (rotationPiece(p[0]).gauche == p[i-1].droite && rotationPiece(p[0]).haut == p[i-L].bas && rotationPiece(p[0]).droite == p[i+1].gauche && rotationPiece(p[0]).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 90\n",p[i].ligne,p[i].colonne);
}
}
}
/* Rotation de 180° */
// coin en haut à gauche
if (rotationPiece(rotationPiece(p[0])).droite == p[2].gauche && rotationPiece(rotationPiece(p[0])).bas == p[1+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[1].ligne,p[1].colonne);
}
// coin en bas à gauche
if (rotationPiece(rotationPiece(p[0])).haut == p[1+(l-2)*L].bas && rotationPiece(rotationPiece(p[0])).droite == p[2+(l-1)*L].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[1+(l-1)*L].ligne,p[1+(l-1)*L].colonne);
}
// coin en haut à droite
if (rotationPiece(rotationPiece(p[0])).gauche == p[L-1].droite && rotationPiece(rotationPiece(p[0])).bas == p[2*L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[L].ligne,p[L].colonne);
}
// coin en bas à droite
if (rotationPiece(rotationPiece(p[0])).gauche == p[l*L-1].droite && rotationPiece(rotationPiece(p[0])).haut == p[(l-1)*L].bas)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[l*L].ligne,p[l*L].colonne);
}
// première colonne
for (i=L+1;i<=1+(l-2)*L;i+=L)
{
if ( (rotationPiece(rotationPiece(p[0])).haut == p[i-L].bas) && (rotationPiece(rotationPiece(p[0])).droite == p[i+1].gauche) && (rotationPiece(rotationPiece(p[0])).bas == p[i+L].haut))
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[i].ligne,p[i].colonne);
}
}
// première ligne
for (i=2;i<=L-1;i++)
{
if (rotationPiece(rotationPiece(p[0])).gauche == p[i-1].droite && rotationPiece(rotationPiece(p[0])).bas == p[i+L].haut && rotationPiece(rotationPiece(p[0])).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[i].ligne,p[i].colonne);
}
}
// dernière colonne
for (i=2*L;i<=(l-1)*L;i+=L)
{
if (rotationPiece(rotationPiece(p[0])).haut == p[i-L].bas && rotationPiece(rotationPiece(p[0])).gauche == p[i-1].droite && rotationPiece(rotationPiece(p[0])).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[i].ligne,p[i].colonne);
}
}
// derniere ligne
for (i=L*(l-1)+2;i<=l*L-1;i++)
{
if (rotationPiece(rotationPiece(p[0])).gauche == p[i-1].droite && rotationPiece(rotationPiece(p[0])).haut == p[i-L].bas && rotationPiece(rotationPiece(p[0])).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[i].ligne,p[i].colonne);
}
}
// puzzle sans les extrémités
for (k=1;k<=l-1;k++)
{
for (i=k*L+2;i<=(k+1)*L-1;i++)
{
if (rotationPiece(rotationPiece(p[0])).gauche == p[i-1].droite && rotationPiece(rotationPiece(p[0])).haut == p[i-L].bas && rotationPiece(rotationPiece(p[0])).droite == p[i+1].gauche && rotationPiece(rotationPiece(p[0])).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 180\n",p[i].ligne,p[i].colonne);
}
}
}
/* Rotation de 270° */
// coin en haut à gauche
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[2].gauche && rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[1+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[1].ligne,p[1].colonne);
}
// coin en bas à gauche
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[1+(l-2)*L].bas && rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[2+(l-1)*L].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[1+(l-1)*L].ligne,p[1+(l-1)*L].colonne);
}
// coin en haut à droite
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[L-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[2*L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[L].ligne,p[L].colonne);
}
// coin en bas à droite
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[l*L-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[(l-1)*L].bas)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[l*L].ligne,p[l*L].colonne);
}
// première colonne
for (i=L+1;i<=1+(l-2)*L;i+=L)
{
if ( (rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[i-L].bas) && (rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[i+1].gauche) && (rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[i+L].haut))
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[i].ligne,p[i].colonne);
}
}
// première ligne
for (i=2;i<=L-1;i++)
{
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[i-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[i+L].haut && rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[i].ligne,p[i].colonne);
}
}
// dernière colonne
for (i=2*L;i<=(l-1)*L;i+=L)
{
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[i-L].bas && rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[i-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[i].ligne,p[i].colonne);
}
}
// derniere ligne
for (i=L*(l-1)+2;i<=l*L-1;i++)
{
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[i-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[i-L].bas && rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[i+1].gauche)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[i].ligne,p[i].colonne);
}
}
// puzzle sans les extrémités
for (k=1;k<=l-1;k++)
{
for (i=k*L+2;i<=(k+1)*L-1;i++)
{
if (rotationPiece(rotationPiece(rotationPiece(p[0]))).gauche == p[i-1].droite && rotationPiece(rotationPiece(rotationPiece(p[0]))).haut == p[i-L].bas && rotationPiece(rotationPiece(rotationPiece(p[0]))).droite == p[i+1].gauche && rotationPiece(rotationPiece(rotationPiece(p[0]))).bas == p[i+L].haut)
{
printf("La piece est remplacable : ligne %d, colonne %d, rotation 270\n",p[i].ligne,p[i].colonne);
}
}
}
free(puz);
free(p);
}
/* *** Fonction main *** */
int main(int argc, char *argv[])
{
/* Test affichePiece */
/* struct Piece p00;
p00.bas=1;
p00.gauche=2;
p00.haut=3;
p00.droite=1;
p00.rotation=0;
affichePiece(p00); */
/* Test make_piece */
/* struct Piece p0;
Piece* l=(Piece*)malloc(1000*sizeof(struct Piece));
l=&p0;
*l=make_piece(3,2,3,4,0);
affichePiece(*l); */
/* Test make_puzzle */
// make_puzzle("puzzle.txt");
return 0 ;
};i+=2)
;i++)>
Commentaires récents