#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;
}