/*************************************************************************************************************************************/ /* */ /* P L A C E M E N T D E R E C T A N G L E 1 x 2 D A N S L E P L A N : */ /* */ /* */ /* Nota : */ /* */ /* Ce programme '$K' est issu du */ /* programme 'v $xtc/dominos.11$vv$c'. */ /* */ /* */ /* Author of '$xrk/dominos.01$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20230807125812). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N T E R F A C E ' listG ' : */ /* */ /* */ /* :Debut_listG: */ /* :Fin_listG: */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F I C H I E R S D ' I N C L U D E S : */ /* */ /*************************************************************************************************************************************/ #include INCLUDES_BASE /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A R A M E T R E S : */ /* */ /*************************************************************************************************************************************/ #define NOMBRE_MAXIMAL_DE_RECTANGLES \ INFINI #define NOMBRE_DE_CARRES_UNITES_1 \ UN #define NOMBRE_DE_CARRES_UNITES_2 \ DEUX #define DIMENSION_X \ HUIT #define DIMENSION_Y \ HUIT #define GRAINE_DU_GENERATEUR_ALEATOIRE \ PARE(1789) #define SEUIL_CHOIX_ORIENTATION \ FDU #define NIVEAU_INTERDIT__ \ GRIS_0 #define NIVEAU_VIDE \ GRIS_0 #define NIVEAU_HORIZONTAL \ GRIS_8 #define NIVEAU_VERTICAL__ \ GRIS_4 #define NIVEAU_GRILLE_HORIZONTAL \ GRIS_2 #define NIVEAU_GRILLE_VERTICAL__ \ GRIS_2 Denumer06(INIS(Mode_LigneLigne_HV,UN) ,Mode_LigneLigne_VH ,Mode_ColonneColonne_HV ,Mode_ColonneColonne_VH ,Mode_SpiraleCarree ,Mode_Aleatoire ,Mode_ModesDisponibles ); #define FACTEUR_ALEATOIRE \ 100 #define EDITER_LES_STATISTIQUES \ VRAI #define EDITER_LES_MESSAGES_DE_DIMENSIONNEMENT \ VRAI \ /* Introduit le 20240626183115... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define dimX_reduite \ DIVI(dimX,dimension_X) #define dimY_reduite \ DIVI(dimY,dimension_Y) #define TEST_IMAGE(x,y) \ load_point_valide(ImageR,x,y) #define DEFINITION_DES_SOMMETS_D_UN_RECTANGLE(x,y,nx,ny) \ DEFV(Int,INIT(Xcm,x)); \ DEFV(Int,INIT(Ycm,y)); \ DEFV(Int,INIT(XcM,PRED(ADD2(x,MUL2(nx,dimension_X))))); \ DEFV(Int,INIT(YcM,PRED(ADD2(y,MUL2(ny,dimension_Y))))); #define PEUT_ON_TRACER_UN_RECTANGLE(on_peut_tracer_un_rectangle,x,y,nx,ny) \ Bblock \ DEFINITION_DES_SOMMETS_D_UN_RECTANGLE(x,y,nx,ny); \ \ EGAL(on_peut_tracer_un_rectangle,VRAI); \ /* A priori... */ \ begin_ligneQ(DoIn,Xcm,XcM,PasX) \ Bblock \ begin_colonneQ(DoIn,Ycm,YcM,PasY) \ Bblock \ Test(TEST_DANS_L_IMAGE(X,Y)) \ Bblock \ Test(IFNE(TEST_IMAGE(X,Y),niveau_vide)) \ Bblock \ EGAL(on_peut_tracer_un_rectangle,FAUX); \ /* Le point {X,Y} est deja marque... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ EGAL(on_peut_tracer_un_rectangle,FAUX); \ /* Le point {X,Y} est en dehors du domaine... */ \ Eblock \ ETes \ Eblock \ end_colonneQ(EDoI) \ Eblock \ end_ligneQ(EDoI) \ Eblock #define TRACE_RECTANGLE(x,y,nx,ny,niveau_rectangle) \ Bblock \ Test(IFEQ(load_point_valide(ImageA,x,y),niveau_autorise__)) \ Bblock \ INCR(nombre_courant_de_rectangles,I); \ \ Test(IFLE(nombre_courant_de_rectangles,nombre_maximal_de_rectangles)) \ Bblock \ DEFINITION_DES_SOMMETS_D_UN_RECTANGLE(x,y,nx,ny); \ \ DEFV(genere_p,INIT(niveau_grille \ ,COND(IFEQ(niveau_rectangle,niveau_horizontal) \ ,niveau_grille_horizontal \ ,COND(IFEQ(niveau_rectangle,niveau_vertical__) \ ,niveau_grille_vertical__ \ ,MOYE(niveau_grille_horizontal,niveau_grille_vertical__) \ ) \ ) \ ) \ ); \ \ begin_ligneQ(DoIn,Xcm,XcM,PasX) \ Bblock \ begin_colonneQ(DoIn,Ycm,YcM,PasY) \ Bblock \ store_point_valide(COND(IFOU(IFOU(IFEQ(X,Xcm),IFEQ(X,XcM)) \ ,IFOU(IFEQ(Y,Ycm),IFEQ(Y,YcM)) \ ) \ ,niveau_grille \ ,niveau_rectangle \ ) \ ,ImageR \ ,X,Y \ ,FVARIABLE \ ); \ Eblock \ end_colonneQ(EDoI) \ Eblock \ end_ligneQ(EDoI) \ \ Test(IFEQ(niveau_rectangle,niveau_horizontal)) \ Bblock \ INCR(CompteurRectanglesHorizontaux,I); \ Eblock \ ATes \ Bblock \ Test(IFEQ(niveau_rectangle,niveau_vertical__)) \ Bblock \ INCR(CompteurRectanglesVerticaux__,I); \ Eblock \ ATes \ Bblock \ CAL1(Prer1("le niveau %d n'est pas reconnu\n",niveau_rectangle)); \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock #define TENTATIVE_HORIZONTALE(x,y) \ Bblock \ DEFV(Logical,INIT(on_peut_tracer_un_rectangle,LUNDEF)); \ PEUT_ON_TRACER_UN_RECTANGLE(on_peut_tracer_un_rectangle \ ,x,y \ ,nombre_de_carres_unites_2 \ ,nombre_de_carres_unites_1 \ ); \ \ Test(EST_VRAI(on_peut_tracer_un_rectangle)) \ Bblock \ TRACE_RECTANGLE(x,y,nombre_de_carres_unites_2,nombre_de_carres_unites_1,niveau_horizontal); \ /* Trace d'un rectangle horizontal 2x1. */ \ Eblock \ ATes \ Bblock \ DEFV(Logical,INIT(on_peut_tracer_un_rectangle,LUNDEF)); \ PEUT_ON_TRACER_UN_RECTANGLE(on_peut_tracer_un_rectangle \ ,x,y \ ,nombre_de_carres_unites_1 \ ,nombre_de_carres_unites_2 \ ); \ \ Test(EST_VRAI(on_peut_tracer_un_rectangle)) \ Bblock \ TRACE_RECTANGLE(x,y,nombre_de_carres_unites_1,nombre_de_carres_unites_2,niveau_vertical__); \ /* Trace d'un rectangle vertical 1x1. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock #define TENTATIVE_VERTICALE__(x,y) \ Bblock \ DEFV(Logical,INIT(on_peut_tracer_un_rectangle,LUNDEF)); \ PEUT_ON_TRACER_UN_RECTANGLE(on_peut_tracer_un_rectangle \ ,x,y \ ,nombre_de_carres_unites_1 \ ,nombre_de_carres_unites_2 \ ); \ \ Test(EST_VRAI(on_peut_tracer_un_rectangle)) \ Bblock \ TRACE_RECTANGLE(x,y,nombre_de_carres_unites_1,nombre_de_carres_unites_2,niveau_vertical__); \ /* Trace d'un rectangle vertical 1x1. */ \ Eblock \ ATes \ Bblock \ DEFV(Logical,INIT(on_peut_tracer_un_rectangle,LUNDEF)); \ PEUT_ON_TRACER_UN_RECTANGLE(on_peut_tracer_un_rectangle \ ,x,y \ ,nombre_de_carres_unites_2 \ ,nombre_de_carres_unites_1 \ ); \ \ Test(EST_VRAI(on_peut_tracer_un_rectangle)) \ Bblock \ TRACE_RECTANGLE(x,y,nombre_de_carres_unites_2,nombre_de_carres_unites_1,niveau_horizontal); \ /* Trace d'un rectangle horizontal 2x1. */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock #define DEFINITION_TUILE_1x2(x,y,test,tentative_1,tentative_2) \ Bblock \ Test(IFEQ(TEST_IMAGE(x,y),niveau_vide)) \ Bblock \ DEFV(Float,INIT(random,GENERE_VALEUR_ALEATOIRE)); \ \ Test(test) \ Bblock \ BLOC(tentative_1); \ Eblock \ ATes \ Bblock \ BLOC(tentative_2); \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock #define PARCOURS_SEQUENTIEL(boucle1,boucle2,Eboucle2,Eboucle1,test,tentative_1,tentative_2) \ Bblock \ boucle1 \ Bblock \ boucle2 \ Bblock \ DEFINITION_TUILE_1x2(X,Y,test,tentative_1,tentative_2); \ Eblock \ Eboucle2 \ Eblock \ Eboucle1 \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define GENERE_VALEUR_ALEATOIRE \ RDN_STANDARD /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P L A C E M E N T D E R E C T A N G L E 1 x 2 D A N S L E P L A N : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(CHAR,INIC(POINTERc(nom_imageA),NOM_PIPE)); DEFV(CHAR,INIC(POINTERc(nom_imageR),NOM_PIPE)); DEFV(Int,INIT(nombre_maximal_de_rectangles,NOMBRE_MAXIMAL_DE_RECTANGLES)); DEFV(Int,INIT(nombre_courant_de_rectangles,ZERO)); DEFV(Int,INIT(CompteurRectanglesHorizontaux,ZERO)); DEFV(Int,INIT(CompteurRectanglesVerticaux__,ZERO)); DEFV(Int,INIT(graine_du_generateur_aleatoire,GRAINE_DU_GENERATEUR_ALEATOIRE)); DEFV(Float,INIT(seuil_choix_orientation,SEUIL_CHOIX_ORIENTATION)); DEFV(genere_p,INIT(niveau_autorise__,NIVEAU_INTERDIT__)); DEFV(genere_p,INIT(niveau_vide,NIVEAU_VIDE)); DEFV(genere_p,INIT(niveau_horizontal,NIVEAU_HORIZONTAL)); DEFV(genere_p,INIT(niveau_vertical__,NIVEAU_VERTICAL__)); DEFV(genere_p,INIT(niveau_grille_horizontal,NIVEAU_GRILLE_HORIZONTAL)); DEFV(genere_p,INIT(niveau_grille_vertical__,NIVEAU_GRILLE_VERTICAL__)); /* Le 20230811095026, il a ete introduit un niveau de grille par type de rectangles ('H' */ /* ou 'V') et ce afin de pouvoir faire disparaitre la grille en faisant : */ /* */ /* niveau_grille_horizontal = niveau_horizontal */ /* niveau_grille_vertical__ = niveau_vertical__ */ /* */ /* et ainsi, par exemple, faire des tests de percolation... */ DEFV(Int,INIT(nombre_de_carres_unites_1,NOMBRE_DE_CARRES_UNITES_1)); DEFV(Int,INIT(nombre_de_carres_unites_2,NOMBRE_DE_CARRES_UNITES_2)); DEFV(Int,INIT(dimension_X,DIMENSION_X)); DEFV(Int,INIT(dimension_Y,DIMENSION_Y)); DEFV(Int,INIT(mode_de_placement_des_rectangles,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 "carree", */ /* mode=6 : Mode aleatoire. */ /* */ DEFV(Logical,INIT(editer_les_statistiques,EDITER_LES_STATISTIQUES)); DEFV(Int,INIT(facteur_aleatoire,FACTEUR_ALEATOIRE)); DEFV(Logical,INIT(editer_les_messages_de_dimensionnement,EDITER_LES_MESSAGES_DE_DIMENSIONNEMENT)); /* Introduit le 20240626183115... */ /*..............................................................................................................................*/ GET_ARGUMENTSi(nombre_d_arguments ,BLOC(GET_ARGUMENT_C("imageA=""A=",nom_imageA); GET_ARGUMENT_C("imageR=""R=",nom_imageR); GET_ARGUMENT_P("niveau_autorise=""na=",niveau_autorise__); GET_ARGUMENT_P("niveau_vide=""nv=",niveau_vide); GET_ARGUMENT_P("niveau_horizontal=""nH=",niveau_horizontal); GET_ARGUMENT_P("niveau_vertical=""nV=",niveau_vertical__); GET_ARGUMENT_P("niveau_grille_horizontal=""nGH=",niveau_grille_horizontal); GET_ARGUMENT_P("niveau_grille_vertical=""nGV=",niveau_grille_vertical__); GET_ARGUMENT_I("nombre_rectangles=""nr=",nombre_maximal_de_rectangles); GET_ARGUMENT_I("graine=",graine_du_generateur_aleatoire); GET_ARGUMENT_F("seuil=",seuil_choix_orientation); GET_ARGUMENT_I("nombre_carres_1=""nc1=",nombre_de_carres_unites_1); GET_ARGUMENT_I("nombre_carres_2=""nc2=",nombre_de_carres_unites_2); /* Arguments introduits le 20230814093106... */ GET_ARGUMENT_I("dimensionX=""dX=""dx=",dimension_X); GET_ARGUMENT_I("dimensionY=""dY=""dy=",dimension_Y); GET_ARGUMENT_I("mode=",mode_de_placement_des_rectangles); GET_ARGUMENT_I("facteur=""fa=",facteur_aleatoire); GET_ARGUMENT_L("editer=""statistiques=""es=",editer_les_statistiques); GET_ARGUMENT_L("messages_dimensionnement=""md=",editer_les_messages_de_dimensionnement); /* Argument introduit le 20240626183115... */ ) ); Test(IFOU(IFOU(NON_DIVISIBLE(dimX,MUL2(nombre_de_carres_unites_1,dimension_X)) ,NON_DIVISIBLE(dimX,MUL2(nombre_de_carres_unites_2,dimension_X)) ) ,IFOU(NON_DIVISIBLE(dimY,MUL2(nombre_de_carres_unites_1,dimension_Y)) ,NON_DIVISIBLE(dimY,MUL2(nombre_de_carres_unites_2,dimension_Y)) ) ) ) Bblock Test(IL_FAUT(editer_les_messages_de_dimensionnement)) /* Test introduit le 20240626183115... */ Bblock PRINT_ATTENTION("les dimensions de l'image ne sont pas divisibles par les dimensions des rectangles"); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Test(IFOU(DIVISIBLE(nombre_de_carres_unites_1,nombre_de_carres_unites_2) ,DIVISIBLE(nombre_de_carres_unites_2,nombre_de_carres_unites_1) ) ) Bblock Eblock ATes Bblock PRINT_ATTENTION("les dimensions des rectangles ne sont pas multiples l'une de l'autre, on reinitialise donc"); /* Ceci est une condition sine qua non si l'on veut que les emboitements se fassent bien... */ EGAL(nombre_de_carres_unites_1,NOMBRE_DE_CARRES_UNITES_1); EGAL(nombre_de_carres_unites_2,NOMBRE_DE_CARRES_UNITES_2); Eblock ETes CALi(Iload_image_si_present(ImageA,nom_imageA,NOM_PIPE_Local,niveau_autorise__)); CALi(Iinitialisation(ImageR,niveau_vide)); INITIALISATION_RDN_STANDARD(GRAINE_DU_GENERATEUR_ALEATOIRE); Choi(mode_de_placement_des_rectangles) Bblock Ca1e(Mode_LigneLigne_HV) /* Mode ligne par ligne (HORIZONTALE,VERTICALE__) : */ Bblock PARCOURS_SEQUENTIEL(begin_colonneQ(DoIn,Ymin,Ymax,dimension_Y) ,begin_ligneQ(DoIn,Xmin,Xmax,dimension_X) ,end_ligneQ(EDoI) ,end_colonneQ(EDoI) ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_HORIZONTALE(X,Y) ,TENTATIVE_VERTICALE__(X,Y) ); Eblock ECa1 Ca1e(Mode_LigneLigne_VH) /* Mode ligne par ligne (VERTICALE__,HORIZONTALE) : */ Bblock PARCOURS_SEQUENTIEL(begin_colonneQ(DoIn,Ymin,Ymax,dimension_Y) ,begin_ligneQ(DoIn,Xmin,Xmax,dimension_X) ,end_ligneQ(EDoI) ,end_colonneQ(EDoI) ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_VERTICALE__(X,Y) ,TENTATIVE_HORIZONTALE(X,Y) ); Eblock ECa1 Ca1e(Mode_ColonneColonne_HV) /* Mode colonne par colonne (HORIZONTALE,VERTICALE__) : */ Bblock PARCOURS_SEQUENTIEL(begin_ligneQ(DoIn,Xmin,Xmax,dimension_X) ,begin_colonneQ(DoIn,Ymin,Ymax,dimension_Y) ,end_colonneQ(EDoI) ,end_ligneQ(EDoI) ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_HORIZONTALE(X,Y) ,TENTATIVE_VERTICALE__(X,Y) ); Eblock ECa1 Ca1e(Mode_ColonneColonne_VH) /* Mode colonne par colonne (VERTICALE__,HORIZONTALE) : */ Bblock PARCOURS_SEQUENTIEL(begin_ligneQ(DoIn,Xmin,Xmax,dimension_X) ,begin_colonneQ(DoIn,Ymin,Ymax,dimension_Y) ,end_colonneQ(EDoI) ,end_ligneQ(EDoI) ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_VERTICALE__(X,Y) ,TENTATIVE_HORIZONTALE(X,Y) ); Eblock ECa1 Ca1e(Mode_SpiraleCarree) /* Mode spirale "carre" : */ Bblock DEFV(Int,INIT(X,COXA(iMULTIPLE(COXR(Xcentre),dimension_X)))); DEFV(Int,INIT(Y,COYA(iMULTIPLE(COYR(Ycentre),dimension_Y)))); DEFV(Int,INIT(index,UNDEF)); SPIRALE_DEFINITION /* Donnees de generation d'une spirale de parcours d'une image. */ SPIRALE_VALIDATION; DoIn(index,UN,ADD2(MUL2(dimX_reduite,dimY_reduite),DOUB((ADD2(dimX_reduite,dimY_reduite)))),I) Bblock Test(TEST_DANS_L_IMAGE(X,Y)) Bblock DEFINITION_TUILE_1x2(X ,Y ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_HORIZONTALE(X,Y) ,TENTATIVE_VERTICALE__(X,Y) ); Eblock ATes Bblock Eblock ETes SPIRALE_INITIALISATION; INCR(X,MUL2(dimension_X,spirale_delta_horizontal)); INCR(Y,MUL2(dimension_Y,spirale_delta_vertical)); SPIRALE_PARCOURS; Eblock EDoI Eblock ECa1 Ca1e(Mode_Aleatoire) /* Mode aleatoire : */ Bblock DEFV(Int,INIT(index,UNDEF)); DoIn(index,UN,INTE(MUL2(facteur_aleatoire,MUL2(dimX_reduite,dimY_reduite))),I) Bblock DEFV(Int,INIT(X,COXA(MULTIPLE(INTE(MUL2(COXR(Xmax),GENERE_VALEUR_ALEATOIRE)) ,MUL2(MIN2(nombre_de_carres_unites_1,nombre_de_carres_unites_2),dimension_X) ) ) ) ); DEFV(Int,INIT(Y,COYA(MULTIPLE(INTE(MUL2(COXR(Ymax),GENERE_VALEUR_ALEATOIRE)) ,MUL2(MIN2(nombre_de_carres_unites_1,nombre_de_carres_unites_2),dimension_Y) ) ) ) ); /* Le 20230814104624, j'hesite entre 'MIN2(...)' et 'MAX2(...)' plus logique, mais je */ /* retiens la premiere solution pour conserver 'v $xiirv/DOMI.11.6'... */ Test(TEST_DANS_L_IMAGE(X,Y)) Bblock DEFINITION_TUILE_1x2(X ,Y ,IFLT(random,seuil_choix_orientation) ,TENTATIVE_HORIZONTALE(X,Y) ,TENTATIVE_VERTICALE__(X,Y) ); Eblock ATes Bblock Eblock ETes Eblock EDoI Eblock ECa1 Defo Bblock CAL1(Prer1("le mode %d n'est pas reconnu\n",mode_de_placement_des_rectangles)); Eblock EDef Eblock ECho Test(IL_FAUT(editer_les_statistiques)) Bblock DEFV(Int,INIT(NombreTotalRectangles,ADD2(CompteurRectanglesHorizontaux,CompteurRectanglesVerticaux__))); CAL3(Prme1("NombreRectangles.=%d\n",NombreTotalRectangles)); CAL3(Prme2("NombreRectanglesH=%d (%.2f%%)\n" ,CompteurRectanglesHorizontaux ,CONVERTIR_EN_UN_POURCENTAGE(CompteurRectanglesHorizontaux,NombreTotalRectangles) ) ); CAL3(Prme2("NombreRectanglesV=%d (%.2f%%)\n" ,CompteurRectanglesVerticaux__ ,CONVERTIR_EN_UN_POURCENTAGE(CompteurRectanglesVerticaux__,NombreTotalRectangles) ) ); Test(IFET(IFET(DIVISIBLE(dimX,MUL2(nombre_de_carres_unites_1,dimension_X)) ,DIVISIBLE(dimX,MUL2(nombre_de_carres_unites_2,dimension_X)) ) ,IFET(DIVISIBLE(dimY,MUL2(nombre_de_carres_unites_1,dimension_Y)) ,DIVISIBLE(dimY,MUL2(nombre_de_carres_unites_2,dimension_Y)) ) ) ) Bblock CAL3(Prme1("NombreSitesInaccessibles=%d\n" ,SOUS(MUL2(dimX_reduite,dimY_reduite) ,DOUB(NombreTotalRectangles) ) ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes CALi(Iupdate_image(nom_imageR,ImageR)); RETU_Commande; Eblock ECommande