Drawing a flag with diagonal crosses in a V-Shape (ADA)

我的未来我决定 提交于 2020-06-17 00:06:32

问题


I turn to Stackoverflow yet again. having gotten help here previously I hope to be received equally friendly once more. I have an assignment where I need to draw a flag (including a box-like shape around it and a V-shape of crosses in its midst) in ADA. Ive managed to make the box and roughly half of the crosses. can anyone clue me in as to how one easiest fills in the remainder of the crosses?

Its supposed to be a V-shape, like this:

+   +
 + +
  + 

etc

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure exercise2 is
   subtype Cross_Rows is Integer range 2..80;
   Rows       : Cross_Rows;
   Flag_Width : Cross_Rows;
   Left       : Positive;
   Right      : Positive;

   procedure Row_Get (Rows: out Cross_Rows) is

      begin

      Put("Enter the number of cross rows (min is 3): ");
      Get(Rows);
      Skip_Line;
      end Row_Get;

      procedure Print_Top (Rows: in Cross_Rows) is

      begin

     Flag_Width := (Rows  * 2) + 4;

     Put("+");
     for Col in 1..Flag_Width-3 loop
        Put("-");
     end loop;
     Put("+");
     New_Line;

      end Print_Top;

      procedure Print_Middle (Rows: in Cross_Rows) is

      begin

     Left := 1;
     Right := Flag_Width - 5;
     for R in 1..Rows loop
        Put("! ");
        for C in 1..Flag_Width - 4 loop
           if C = Left or else C = Right then
          Put("+");
           else
          Put(" ");
           end if;
        end loop;
        Left := Left + 1;
        Right := Right - 1;

        Put_Line("!");
     end loop;

      end Print_Middle;

      procedure Print_Bottom (Rows: in Cross_Rows) is

      begin

     Flag_Width := (Rows  * 2) + 4;

     Put("+");
     for C in 1..Flag_Width-3 loop
        Put("-");
     end loop;
     Put_Line("+");

      end Print_Bottom;

begin
   Row_Get(Rows);
   Print_Top(Rows);
   Print_Middle(Rows);
   Print_Bottom(Rows);
end exercise2;

EDIT: Thanks to Jim Rogers I managed to edit my program to draw the flag. Unfortunately its not exactly the way its meant to be as the top crosses are supposed to touch the sides and not be spaced like they are now. Additionally the Main program and the subprograms arent allowed to be more than 15 lines each so I compartmentalized them.

The smallest flag is supposed to look like this. I'll try to work with his code to achieve this. But any help is of value! :)

n=1
+---+
!+ +!
! + !
+---+

n=2
+-----+
!+   +!
! + + !
!  +  !
+-----+


回答1:


You need to keep track of the left and right columns for the '+' characters, increasing the left column position and decreasing the right column position with each iteration of your loop for printing the crosses. The following program works for any number of rows of crosses from 3 to 80.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main is
   subtype Cross_Rows is Integer range 3..80;
   Rows       : Cross_Rows;
   Flag_Width : Cross_Rows;
   Left       : Positive;
   Right      : Positive;

begin
   Put("Enter the number of cross rows (minimum is 3): ");
   Get(Rows);
   Skip_Line;
   Flag_Width := (Rows  * 2) + 4;
   -- Print top row of flag boundary
   for Col in 1..Flag_Width loop
      Put("-");
   end loop;
   Put("-");
   New_Line;
   -- Print empty row below top flag boundary
   Put("-  ");
   for C in 3..Flag_Width - 2 loop
      Put(" ");
   end loop;
   Put_Line(" -");

   -- Print crosses
   Left := 1;
   Right := Flag_Width - 5;
   for R in 1..Rows loop
      Put("-  ");
      for C in 1..Flag_Width - 4 loop
         if C = Left or else C = Right then
            Put("+");
         else
            Put(" ");
         end if;
      end loop;
         Left := Left + 1;
         Right := Right - 1;

      Put_Line(" -");
   end loop;
   -- Print bottom flag rows
   Put("-  ");
   for C in 3..Flag_Width - 2 loop
      Put(" ");
   end loop;
   Put_Line(" -");
   for C in 1..Flag_Width loop
      Put("-");
   end loop;
   Put_Line("-");
end Main;

Example output is:

Enter the number of cross rows (minimum is 3): 7
-------------------
-                 -
-  +           +  -
-   +         +   -
-    +       +    -
-     +     +     -
-      +   +      -
-       + +       -
-        +        -
-                 -
-------------------



回答2:


Another approach uses the Set_Col procedure from Ada.Text_Io. Set_Col set the cursor to the specified column number in the current output line. For example, if the cursor starts at position 1 and you call Set_Col(10) the procedure will output 9 blank characters and set the column number to 10. You can then begin writing your non-blank output at column 10.

with Ada.Text_Io; use Ada.Text_IO;
with Ada.Integer_Text_Io; use Ada.Integer_Text_IO;

procedure V_columns is
   subtype Cross_Rows is Integer range 3..80;

   Rows       : Cross_Rows;
   Flag_Width : Positive;
   Left       : Positive;
   Right      : Positive;
begin
   Put("Enter the number of cross rows (minimum is 3): ");
   Get(Rows);
   Skip_Line;
   Flag_Width := (Rows  * 2) + 4;
   -- Print top row of flag boundary
   for Col in 1..Flag_Width loop
      Put("-");
   end loop;
   New_Line;
   -- Print empty row below top flag boundary
   Set_Col(1);
   Put("|");
   Set_Col(Positive_Count(Flag_Width));
   Put_Line("|");

   -- Print crosses
   Left := 3;
   Right := Flag_Width - 3;
   for R in 1..Rows loop
      Set_Col(1);
      Put("|");
      if Left < Right then
         Set_Col(Positive_Count(Left));
         Put("+");
         Set_Col(Positive_Count(Right));
         Put("+");
      else
         Set_Col(Positive_Count(Right));
         Put("+");
      end if;
      Set_Col(Positive_Count(Flag_Width));
      Put("|");
      New_Line;
      Left := Left + 1;
      Right := Right - 1;
   end loop;
   -- Print bottom flag rows
   Set_Col(1);
   Put("|");
   Set_Col(Positive_Count(Flag_Width));
   Put_Line("|");
   for C in 1..Flag_Width loop
      Put("-");
   end loop;
   New_Line;
end V_Columns;

The output of the program is:

Enter the number of cross rows (minimum is 3): 7
------------------
|                |
| +           +  |
|  +         +   |
|   +       +    |
|    +     +     |
|     +   +      |
|      + +       |
|       +        |
|                |
------------------



回答3:


You could also choose an approach in which the definition of the pattern (here: a flag) and the output mechanism are almost completely decoupled. This approach also allows you to parallelize the flag rendering in case you need to render really, really huge flags ;-):

main.adb

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is

   N : constant := 2;

   Width  : constant := 3 + 2 * N;
   Height : constant := 3 + 1 * N;

   type Screen_X is new Natural range 0 .. Width  - 1;
   type Screen_Y is new Natural range 0 .. Height - 1;

   -------------
   -- Pattern --
   -------------

   function Pattern (X : Screen_X; Y : Screen_Y) return Character is

      Is_Border_LR : constant Boolean :=
        X = Screen_X'First or else X = Screen_X'Last;

      Is_Border_TB : constant Boolean :=
        Y = Screen_Y'First or else Y = Screen_Y'Last;

      --  The V-Shape is based on the implicit function:
      --
      --    abs (X - X0) + (Y - Y0) = 0

      X0 : constant := (Screen_X'Last + Screen_X'First) / 2;
      Y0 : constant :=  Screen_Y'Last - 1;     

      Is_V_Shape : constant Boolean :=
        Integer (abs (X - X0)) + Integer (Y - Y0) = 0;

   begin

      if Is_Border_LR and Is_Border_TB then
         return '+';
      elsif Is_Border_LR then
         return '!';
      elsif Is_Border_TB then
         return '-';
      elsif Is_V_Shape then
         return '+';
      else
         return ' ';
      end if;

   end Pattern;

begin

   --  The Render loop.

   for Y in Screen_Y loop
      for X in Screen_X loop
         Put (Pattern (X, Y));
      end loop;
      New_Line;
   end loop;

end Main;

output (N = 1)

$ ./main
+---+
!+ +!
! + !
+---+

output (N = 2)

$ ./main
+-----+
!+   +!
! + + !
!  +  !
+-----+


来源:https://stackoverflow.com/questions/61922604/drawing-a-flag-with-diagonal-crosses-in-a-v-shape-ada

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!