/* Coloriage dans une matrice de int            */

public class ColoriageRecursif {

  static void cercle(int px,int py,int r,int [][] t,int coul) {
    int dx;
    int dy;
    for ( int l = 0 ; l < t.length ; l++ ) {
      for ( int c = 0 ; c < t[0].length ; c++ ) {
        dx = px-c;
        dy = py-l;
        if ( dx*dx+dy*dy < r*r ) {
          t[l][c] = coul; } } }
  }
  
/* Fonction de creation d'une matrice de int    */
/* a 0 initialisee avec deux cercles de int     */
/* aux valeurs 1 et 2                           */

  static int [][] initMatrice(int colonnes,int lignes) {
    int [][] tab = new int[lignes][colonnes];
    cercle(20,10,9,tab,1);
    cercle(40,15,11,tab,2);
    cercle(30,12,6,tab,3);
    return tab;
  }

/* Fonction d'affichage des valeurs contenues   */
/* dans une matrice de int                      */
  
  static void affichageMatrice(boolean [][] t) {
    for ( int i = 0 ; i < t.length ; i++ ) {
      for ( int j = 0 ; j < t[0].length ; j++ ) {
        if ( t[i][j] ) {
          Ecran.afficher("  X"); }
          else {
          Ecran.afficher("  O"); } }
      Ecran.sautDeLigne(); }
  }

/* Fonction d'affichage des valeurs contenues   */
/* dans une matrice de int                      */
  
  static void affichageMatrice(int [][] t) {
    for ( int i = 0 ; i < t.length ; i++ ) {
      for ( int j = 0 ; j < t[0].length ; j++ ) {
        Ecran.formater("%1d",t[i][j]); }
      Ecran.sautDeLigne(); }
  }

//////////////////////////////////////////////////

/* Fonction recursive de coloriage d'une zone   */
/* de pixels de valeurs identiques              */
/* px : La position en x du pixel germe         */
/* py : la position en y du pixel germe         */
/* t  : la matrice des valeurs des pixels       */
/* c  : la couleur de remplissage               */
/* ct : la couleur de la tache à remplir        */

  static void coloriageRecursif(int px,int py,int [][] t,
                                int c,int ct) {
    if ( ( px >= 0 ) && ( px < t[0].length ) &&
         ( py >= 0 ) && ( py < t.length ) ) {
      if ( ( t[py][px] != c ) && ( t[py][px] == ct ) ) {
        t[py][px] = c;
        coloriageRecursif(px+1,py,t,c,ct);
        coloriageRecursif(px-1,py,t,c,ct);
        coloriageRecursif(px,py+1,t,c,ct);
        coloriageRecursif(px,py-1,t,c,ct); } }
  }

/* Fonction de coloriage d'une zone de pixels   */
/* de valeurs identiques                        */
/* px : La position en x du pixel germe         */
/* py : la position en y du pixel germe         */
/* t  : la matrice des valeurs des pixels       */
/* c  : la couleur de remplissage               */

  static void coloriage(int px,int py,int [][] t,int c) {
    coloriageRecursif(px,py,t,c,t[py][px]);
  }

/* Fonction recursive de remplissage d'une zone */
/* de pixels delimitee par une valeur           */
/* px : La position en x du pixel germe         */
/* py : la position en y du pixel germe         */
/* t  : la matrice des valeurs des pixels       */
/* c  : la couleur de remplissage               */
/* cl : la couleur de delimitation              */
/*      de la tache à remplir                   */

  static void remplissageRecursif(int px,int py,int [][] t,
                                  int c,int cl) {
    if ( ( px >= 0 ) && ( px < t[0].length ) &&
         ( py >= 0 ) && ( py < t.length ) ) {
      if ( ( t[py][px] != c ) && ( t[py][px] != cl ) ) {
        t[py][px] = c;
        remplissageRecursif(px+1,py,t,c,cl);
        remplissageRecursif(px-1,py,t,c,cl);
        remplissageRecursif(px,py+1,t,c,cl);
        remplissageRecursif(px,py-1,t,c,cl); } }
  }
  
//////////////////////////////////////////////////

/* Menu principal                               */
  
  static int menuPrincipal() {
    int v;
    Ecran.sautDeLigne();
    Ecran.afficherln("1: Colorier une tache");
    Ecran.afficherln("2: Colorier une zone delimitee");
    Ecran.afficherln("0: Quitter");
    Ecran.afficher("Que voulez vous faire ? ");
    v = Clavier.saisirInt();
    Ecran.sautDeLigne();
    return v;
  }

/* Programme principal                          */

  public static void main(String [] args) {
    int [][] t = initMatrice(60,20);
    Ecran.afficherln("Image avant dessin");
    affichageMatrice(t);
    Ecran.sautDeLigne();
    int px;
    int py;
    int c;
    int cl;
    int choix;
    choix = menuPrincipal();
    while ( choix != 0 ) {
      switch (choix) {
        case 1 : {
          Ecran.afficher("Position en x du germe ? ");
          px = Clavier.saisirInt();
          Ecran.afficher("Position en y du germe ? ");
          py = Clavier.saisirInt();
          Ecran.afficher("Couleur de trace       ? ");
          c = Clavier.saisirInt();
          coloriage(px,py,t,c);
          Ecran.sautDeLigne();
          Ecran.afficherln("Image après dessin");
          affichageMatrice(t); }
          break;
        case 2 : {
          Ecran.afficher("Position en x du germe ? ");
          px = Clavier.saisirInt();
          Ecran.afficher("Position en y du germe ? ");
          py = Clavier.saisirInt();
          Ecran.afficher("Couleur de trace       ? ");
          c = Clavier.saisirInt();
          Ecran.afficher("Couleur limite         ? ");
          cl = Clavier.saisirInt();
          remplissageRecursif(px,py,t,c,cl);
          Ecran.sautDeLigne();
          Ecran.afficherln("Image après dessin");
          affichageMatrice(t); }
          break; }
    choix = menuPrincipal(); }
  }
}