# mission2b.adb

    --
    -- Nom    :
    -- Prenom :
    -- Groupe :
    --

    with EcoRobot ;
    with Gada.Text_IO ;

    procedure Mission2b is

       package E renames EcoRobot ;
       package Txt renames GAda.Text_IO ;

       -- Renvoie le nombre de voisins du robot.
       function Nb_Voisins(Num : Integer) return Integer is
          Nb : Integer := 0 ;
          X : Integer := E.Abscisse(Num) ;
          Y : Integer := E.Ordonnee(Num) ;
       begin
          -- On teste dans les quatre directions.
          if E.Scan(X-1, Y) = E.Robot then
             Nb := Nb + 1 ;
          end if ;

          if E.Scan(X+1, Y) = E.Robot then
             Nb := Nb + 1 ;
          end if ;

          if E.Scan(X, Y-1) = E.Robot then
             Nb := Nb + 1 ;
          end if ;

          if E.Scan(X, Y+1) = E.Robot then
             Nb := Nb + 1 ;
          end if ;
          return Nb ;
       end Nb_Voisins ;

       -- Renvoie le numéro de robot avec le moins de voisins.
       function Num_Danseur return Integer is
          Nb_Min_Voisins : Integer := Integer'Last ;
          Robot_Elu : Integer ;
       begin
          for Num in 1..E.Nombre_Robots loop
             if (not E.Robot_Content(Num)) and Nb_Voisins(Num) < Nb_Min_Voisins then
                Nb_Min_Voisins := Nb_Voisins(Num) ;
                Robot_Elu := Num ;
             end if ;
          end loop ;
          return Robot_Elu ;
       end Num_Danseur ;

       procedure Test_Num_Danseur is
       begin
          Txt.Put_Line("Le robot ayant le moins de voisins est le robot " &
                       "numéro " & Integer'Image(Num_Danseur) & " car il a " &
                       Integer'Image(Nb_Voisins(Num_Danseur)) & " voisins.") ;
       end Test_Num_Danseur ;

       -- Déplace le robot si possible et indique si le déplacement a été fait.
       --
       -- Recopié directement depuis mission1
       --
       function Safe_Walk(Num : Integer ; Direction : Integer) return Boolean is
          -- Coordonnées du robot
          X : Integer := E.Abscisse(Num) ;
          Y : Integer := E.Ordonnee(Num) ;
          Result : Boolean := False ;
       begin
          -- Nouvelles coordonnées selon la direction voulue.
          if Direction = E.Nord then
             Y := Y - 1 ;
          elsif Direction = E.Sud then
             Y := Y + 1 ;
          elsif Direction = E.Est then
             X := X + 1 ;
          else
             X := X - 1 ;
          end if ;

          if E.Scan(X,Y) /= E.Billets and E.Scan(X,Y) /= E.Dehors then
             E.Step(Num, X, Y) ;
             Result := True ;
          end if ;
          return Result ;
       end Safe_Walk ;

       -- Avance jusqu'à un obstacle et revient au point de départ.
       procedure AllerRetour(Num : Integer ; Direction :Integer) is
          Total : Integer := 0 ;
          Res : Boolean ;
          InvDirection : Integer ;
       begin
          while Safe_Walk(Num, Direction) loop
             Total := Total + 1 ;
          end loop ;

          if Direction = E.Nord then
             InvDirection := E.Sud ;
          elsif Direction = E.Sud then
             InvDirection := E.Nord ;
          elsif Direction = E.Est then
             InvDirection := E.Ouest ;
          else
             InvDirection := E.Est ;
          end if ;

          for Pas in 1 .. Total loop
             Res := Safe_Walk(Num, InvDirection) ;
          end loop ;
       end AllerRetour ;

       -- Effectue la chorégraphie d'un robot
       procedure Choregraphie(Num : Integer) is
          Nb_Bords : constant Integer := 4 ;
       begin
          for Ordre in 1..Nb_Bords loop

             if E.Preferences(Num).Bord_Nord = Ordre then
                AllerRetour(Num, E.Nord) ;
             end if ;
             if E.Preferences(Num).Bord_Sud = Ordre then
                AllerRetour(Num, E.Sud) ;
             end if ;
             if E.Preferences(Num).Bord_Est = Ordre then
                AllerRetour(Num, E.Est) ;
             end if ;
             if E.Preferences(Num).Bord_Ouest = Ordre then
                AllerRetour(Num, E.Ouest) ;
             end if ;

          end loop ;

          -- Chemin vers la cible.
          while Safe_Walk(Num, E.Nord) loop
             null ;
          end loop ;

          while Safe_Walk(Num, E.Est) loop
             null ;
          end loop ;
       end Choregraphie ;

       -- Chaque robot fait sa chorégraphie dans l'ordre.
       procedure Sauver_Tous is
       begin
          for Compteur in 1..E.Nombre_Robots loop
             Txt.Put_Line("Nombre de robots contents = " & Integer'Image(E.Nb_Robots_Contents)) ;
             Choregraphie(Num_Danseur) ;
          end loop ;
       end Sauver_Tous ;

    begin

       Sauver_Tous ;

    end Mission2b ;