/*************************************************************************************************************************************/ /* */ /* P L A C E M E N T A L E A T O I R E D E D O M I N O S D A N S L E P L A N : */ /* */ /* */ /* Author of '$xtc/dominos.11$vv$c' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20230804113616). */ /* */ /*************************************************************************************************************************************/ #include "INCLUDES.01.I" extern void *malloc(); extern void srand48(); extern double drand48(); static int dimX=0; #define Xmin 0 #define Xmax (Xmin + (dimX-1)) /* Definition des abscisses. */ static int dimY=0; #define Ymin 0 #define Ymax (Ymin + (dimY-1)) /* Definition des ordonnees. */ #define dimX_reduite \ (dimX/PAS_X) #define dimY_reduite \ (dimY/PAS_Y) #define PAS_X \ (8) #define PAS_Y \ (8) #define IMAGE(x,y) \ (*(image + ((((y)-Ymin)*dimY) + ((x)-Xmin)))) \ /* Acces a un point de l'image. */ #define store(n,x,y) \ { \ if ((x >= Xmin) && (x <= Xmax) && (y >= Ymin) && (y <= Ymax)) \ { \ IMAGE(x,y) = n; \ } \ else \ { \ } \ } \ /* Rangement d'un point valide d'une image. */ #define GRAINE_DU_GENERATEUR_ALEATOIRE \ 1789 #define SEUIL_CHOIX_ORIENTATION \ 0.5 #define NIVEAU_VIDE______ \ NOIR #define NIVEAU_HORIZONTAL \ (BLANC/1) #define NIVEAU_VERTICAL__ \ (BLANC/2) #define NIVEAU_GRILLE____ \ (BLANC/4) enum ModesDisponibles { LigneLigne_HV=1 ,LigneLigne_VH ,ColonneColonne_HV ,ColonneColonne_VH ,SpiraleCarree ,Aleatoire }; int mode=LigneLigne_HV; /* Definition du mode de parcours du domaine : */ /* */ /* mode=1 : Ligne apres ligne (HV), */ /* mode=2 : Ligne apres ligne (VH), */ /* mode=3 : Colonne apres colonne (HV), */ /* mode=4 : Colonne apres colonne (VH), */ /* mode=5 : Suivant une spirale "caree", */ /* mode=6 : Mode aleatoire. */ /* */ #define FACTEUR_ALEATOIRE \ 100 #define TEST_IMAGE(x,y) \ IMAGE((MIN2((x)+(PAS_X/2),Xmax)),((MIN2((y)+(PAS_Y/2),Ymax)))) #define TRACE_RECTANGLE(x,y,nx,ny,niveau) \ { \ int xc; \ int yc; \ int xcm=(x); \ int ycm=(y); \ int xcM=(x+(nx*PAS_X))-1; \ int ycM=(y+(ny*PAS_Y))-1; \ \ for (xc=xcm ; xc <= xcM ; xc++) \ { \ for (yc=ycm ; yc <= ycM ; yc++) \ { \ IMAGE(xc,yc) = \ COND(IFOU(IFOU(IFEQ(xc,xcm),IFEQ(xc,xcM)) \ ,IFOU(IFEQ(yc,ycm),IFEQ(yc,ycM)) \ ) \ ,NIVEAU_GRILLE____ \ ,niveau \ ); \ } \ } \ \ if (niveau == NIVEAU_HORIZONTAL) \ { \ CompteurH++; \ } \ else \ { \ if (niveau == NIVEAU_VERTICAL__) \ { \ CompteurV++; \ } \ else \ { \ fprintf(stderr,"Le niveau %d n'est pas reconnu\n",niveau); \ } \ } \ } #define TENTATIVE_HORIZONTALE(x,y) \ { \ if (((x+PAS_X+1) <= Xmax) && (TEST_IMAGE(x+PAS_X+1,y) == NIVEAU_VIDE______)) \ { \ TRACE_RECTANGLE(x,y,2,1,NIVEAU_HORIZONTAL); \ /* Trace d'un rectangle horizontal 2x1. */ \ } \ else \ { \ if (((y+PAS_Y+1) <= Ymax) && (TEST_IMAGE(x,y+PAS_Y+1) == NIVEAU_VIDE______)) \ { \ TRACE_RECTANGLE(x,y,1,2,NIVEAU_VERTICAL__); \ /* Trace d'un rectangle vertical 1x1. */ \ } \ else \ { \ } \ } \ } #define TENTATIVE_VERTICALE__(x,y) \ { \ if (((y+PAS_Y+1) <= Ymax) && (TEST_IMAGE(x,y+PAS_Y+1) == NIVEAU_VIDE______)) \ { \ TRACE_RECTANGLE(x,y,1,2,NIVEAU_VERTICAL__); \ /* Trace d'un rectangle vertical 1x1. */ \ } \ else \ { \ if (((x+PAS_X+1) <= Xmax) && (TEST_IMAGE(x+PAS_X+1,y) == NIVEAU_VIDE______)) \ { \ TRACE_RECTANGLE(x,y,2,1,NIVEAU_HORIZONTAL); \ /* Trace d'un rectangle horizontal 2x1. */ \ } \ else \ { \ } \ } \ } #define DEFINITION_TUILE_1x2(x,y,test,tentative_1,tentative_2) \ { \ if (TEST_IMAGE(x,y) == NIVEAU_VIDE______) \ { \ double random=drand48(); \ \ if test \ { \ tentative_1; \ } \ else \ { \ tentative_2; \ } \ } \ else \ { \ } \ } #define PARCOURS_SEQUENTIEL(boucle1,boucle2,test,tentative_1,tentative_2) \ { \ for boucle1 \ { \ for boucle2 \ { \ DEFINITION_TUILE_1x2(x,y,test,tentative_1,tentative_2); \ } \ } \ } int editer_les_statistiques=VRAI; void main(int argc,char *argv[]) { int x,y; /* Definition des coordonnees. */ unsigned char *image; /* Definition de l'image a generer... */ int CompteurH=0; int CompteurV=0; if (argc > 1) { mode=atoi(argv[1]); /* Recuperation du mode de remplissage... */ } else { } Get(dimX,"dimX"); Get(dimY,"dimY"); /* Recuperation des dimensions en 'X' et en 'Y' de l'image a generer. */ image=malloc(dimX*dimY); /* Definition de l'image a generer... */ srand48(GRAINE_DU_GENERATEUR_ALEATOIRE); for (y=Ymin ; y<=Ymax ; y++) { for (x=Xmin ; x<=Xmax ; x++) { store(NIVEAU_VIDE______,x,y); } } switch (mode) { case LigneLigne_HV: /* Mode ligne par ligne (HORIZONTALE,VERTICALE__) : */ { PARCOURS_SEQUENTIEL((y=Ymin ; y<=Ymax ; y=y+PAS_Y) ,(x=Xmin ; x<=Xmax ; x=x+PAS_X) ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_HORIZONTALE(x,y) ,TENTATIVE_VERTICALE__(x,y) ); break; } case LigneLigne_VH: /* Mode ligne par ligne (VERTICALE__,HORIZONTALE) : */ { PARCOURS_SEQUENTIEL((y=Ymin ; y<=Ymax ; y=y+PAS_Y) ,(x=Xmin ; x<=Xmax ; x=x+PAS_X) ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_VERTICALE__(x,y) ,TENTATIVE_HORIZONTALE(x,y) ); break; } case ColonneColonne_HV: /* Mode colonne par colonne (HORIZONTALE,VERTICALE__) : */ { PARCOURS_SEQUENTIEL((x=Xmin ; x<=Xmax ; x=x+PAS_X) ,(y=Ymin ; y<=Ymax ; y=y+PAS_Y) ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_HORIZONTALE(x,y) ,TENTATIVE_VERTICALE__(x,y) ); break; } case ColonneColonne_VH: /* Mode colonne par colonne (VERTICALE__,HORIZONTALE) : */ { PARCOURS_SEQUENTIEL((x=Xmin ; x<=Xmax ; x=x+PAS_X) ,(y=Ymin ; y<=Ymax ; y=y+PAS_Y) ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_VERTICALE__(x,y) ,TENTATIVE_HORIZONTALE(x,y) ); break; } case SpiraleCarree: /* Mode spirale "carre" : */ { int x = Xmin+(dimX / 2); int y = Ymin+(dimY / 2); int SdeltaX = 1; int SdeltaY = 0; int Slongueur_du_bras = 1; int Snombre_de_points = 0; int index; for (index = 1 ; index <= ((dimX_reduite * dimY_reduite) + ((dimX_reduite + dimY_reduite) * 2)) ; index++ ) { if ((x >= Xmin) && (x <= Xmax) && (y >= Ymin) && (y <= Ymax)) { DEFINITION_TUILE_1x2(x ,y ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_HORIZONTALE(x,y) ,TENTATIVE_VERTICALE__(x,y) ); } else { } if (Snombre_de_points == 0) { Snombre_de_points = Slongueur_du_bras; } else { } x += SdeltaX*PAS_X; y += SdeltaY*PAS_Y; Snombre_de_points--; if (Snombre_de_points == 0) { int intermediaire; if (SdeltaX == 0) { Slongueur_du_bras++; } else { } intermediaire = SdeltaX ^ SdeltaY; SdeltaX ^= intermediaire; SdeltaY ^= intermediaire; SdeltaX = - SdeltaX; /* Parcours de la spirale "carre" : ... */ } else { } } Snombre_de_points++; break; } case Aleatoire: /* Mode aleatoire : */ { int index; for (index = 1 ; index <= (FACTEUR_ALEATOIRE*(dimX_reduite * dimY_reduite)) ; index++) { int x = Xmin+((((int)(Xmax*drand48()))/PAS_X)*PAS_X); int y = Ymin+((((int)(Ymax*drand48()))/PAS_Y)*PAS_Y); if ((x >= Xmin) && (x <= Xmax) && (y >= Ymin) && (y <= Ymax)) { DEFINITION_TUILE_1x2(x ,y ,(random < SEUIL_CHOIX_ORIENTATION) ,TENTATIVE_HORIZONTALE(x,y) ,TENTATIVE_VERTICALE__(x,y) ); } else { } } break; } default: { fprintf(stderr,"Le mode %d n'est pas reconnu\n",mode); break; } } write(1,image,dimX*dimY); /* Sortie de l'image... */ if (editer_les_statistiques == VRAI) { fprintf(stderr,"NombreRectanglesH=%d\n",CompteurH); fprintf(stderr,"NombreRectanglesV=%d\n",CompteurV); fprintf(stderr,"NombreSitesInaccessibles=%d\n",(dimX_reduite*dimY_reduite)-(2*(CompteurH+CompteurV))); } else { } }