/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        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
                    {
                    }
          }



Copyright © Jean-François COLONNA, 2023-2023.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2023-2023.