next up previous contents
suivant: Complexes monter: Corrigés des programmes précédent: Pgcd   Table des matières

Pavage avec des L

pavage.c


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



klaus 2010-08-05