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