#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct { int ligne; int colonne; }coordonnees; typedef struct { char* tab; int n; coordonnees caseInterdite; }grille; int puiss(int b, int n) { if (n == 0) return 1; return b * puiss(b, n-1); } void erreurMemoire() { printf("Pas de memoire\n"); exit(1); } char* retourneAdresseCase(grille g, coordonnees c) { int milieu; if (g.n == 0) return g.tab; milieu = puiss(2, g.n - 1); if (c.ligne >= milieu) { g.tab += 2*milieu*milieu; c.ligne-=milieu; } if (c.colonne >= milieu) { g.tab += milieu*milieu; c.colonne-=milieu; } g.n -= 1; return retourneAdresseCase(g, c); } char retourneValeurCase(grille g, coordonnees c) { return *retourneAdresseCase(g, c); } void affecteValeurCase(grille g, coordonnees c, char valeur) { *retourneAdresseCase(g, c) = valeur; } grille grilleCree(int n, int ligneInterdite, int colonneInterdite, char valeurs, char valeurInterdite) { grille g; int largeur = puiss(2, n); coordonnees c; g.tab = (char*)malloc(largeur * largeur); if (g.tab == NULL) erreurMemoire(); g.n = n; g.caseInterdite.ligne = ligneInterdite; g.caseInterdite.colonne = colonneInterdite; for(c.ligne = 0 ; c.ligne < largeur ; c.ligne++) for(c.colonne = 0 ; c.colonne < largeur; c.colonne++) affecteValeurCase(g, c, valeurs); affecteValeurCase(g, g.caseInterdite, valeurInterdite); return g; } void grilleAffiche(grille g) { int largeur = puiss(2, g.n); coordonnees c; for(c.ligne = 0 ; c.ligne < largeur ; c.ligne++) { for(c.colonne = 0 ; c.colonne < largeur; c.colonne++) printf("%c ", retourneValeurCase(g, c)); printf("\n"); } } void grillePavage(grille g, char c) { int largeur; char valeurInterdite; int nbPieces; grille hd, hg, bd, bg; if (g.n != 0) { largeur = puiss(2, g.n-1); hg.tab = g.tab; hd.tab = hg.tab + largeur*largeur; bg.tab = hd.tab + largeur*largeur; bd.tab = bg.tab + largeur*largeur; hg.n = g.n - 1; hd.n = g.n - 1; bg.n = g.n - 1; bd.n = g.n - 1; hg.caseInterdite.ligne = largeur - 1; hg.caseInterdite.colonne = largeur - 1; hd.caseInterdite.ligne = largeur - 1; hd.caseInterdite.colonne = 0 ; bg.caseInterdite.ligne = 0 ; bg.caseInterdite.colonne = largeur - 1; bd.caseInterdite.ligne = 0 ; bd.caseInterdite.colonne = 0 ; if (g.caseInterdite.ligne < largeur) if (g.caseInterdite.colonne < largeur ) hg.caseInterdite = g.caseInterdite; else { hd.caseInterdite.ligne = g.caseInterdite.ligne ; hd.caseInterdite.colonne = g.caseInterdite.colonne - largeur; } else if (g.caseInterdite.colonne < largeur ) { bg.caseInterdite.ligne = g.caseInterdite.ligne - largeur ; bg.caseInterdite.colonne = g.caseInterdite.colonne - largeur; } else { bd.caseInterdite.ligne = g.caseInterdite.ligne - largeur ; bd.caseInterdite.colonne = g.caseInterdite.colonne - largeur; } valeurInterdite = retourneValeurCase(g, g.caseInterdite); affecteValeurCase(hd, hd.caseInterdite, c + 1); affecteValeurCase(hg, hg.caseInterdite, c + 1); affecteValeurCase(bg, bg.caseInterdite, c + 1); affecteValeurCase(bd, bd.caseInterdite, c + 1); affecteValeurCase(g, g.caseInterdite, valeurInterdite); grillePavage(hd, c+1); nbPieces = (largeur*largeur - 1)/3; grillePavage(hg, c+nbPieces + 1); grillePavage(bg, c+2*nbPieces + 1); grillePavage(bd, c+3*nbPieces + 1); } } void grilleDetruit(grille g) { free(g.tab); } int main() { grille g = grilleCree(4, 5, 12, -1, '!'); grillePavage(g, '!'); grilleAffiche(g); grilleDetruit(g); return 0; }