【问题标题】:Drawing a flag with diagonal crosses in a V-Shape (ADA)以 V 形 (ADA) 绘制带有斜十字的旗帜
【发布时间】:2020-05-20 20:46:51
【问题描述】:

我再次求助于 Stackoverflow。以前在这里得到过帮助,我希望再次得到同样友好的接待。我有一个任务,我需要在 ADA 中绘制一面旗帜(包括围绕它的盒子状形状和中间的 V 形十字架)。我设法制造了盒子和大约一半的十字架。谁能告诉我如何用最简单的方法填充其余的十字架?

它应该是一个V形,像这样:

+   +
 + +
  + 

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;

编辑:感谢 Jim Rogers,我设法编辑了我的程序来绘制旗帜。不幸的是,它并不完全是它的意思,因为顶部十字架应该接触侧面而不是像现在这样间隔开。另外,主程序和子程序都不允许超过 15 行,所以我把它们分开了。

最小的标志应该是这样的。我将尝试使用他的代码来实现这一目标。但任何帮助都是有价值的! :)

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

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

【问题讨论】:

    标签: ada spaces


    【解决方案1】:

    您需要跟踪“+”字符的左列和右列,在循环的每次迭代中增加左列位置并减少右列位置以打印十字。 以下程序适用于从 3 到 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;
    

    示例输出为:

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

    【讨论】:

      【解决方案2】:

      另一种方法使用 Ada.Text_Io 中的 Set_Col 过程。 Set_Col 将光标设置到当前输出行中的指定列号。例如,如果光标从位置 1 开始并且您调用 Set_Col(10),则该过程将输出 9 个空白字符并将列号设置为 10。然后您可以在第 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;
      

      程序的输出是:

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

      【讨论】:

      • 非常感谢吉姆!真的很感激!我通过编辑我的主要帖子来回答。你怎么看?
      • @GustavAgrell 恭喜。你实现了一个工作程序。一些小观察:当您只需要计算一次 Flag_Width 的值时,您计算了两次。当您的程序允许最少 2 行时,您提示最小行数为 3。使用一致的代码缩进提高了代码的可读性。
      【解决方案3】:

      您还可以选择一种方法,其中模式的定义(这里:一个标志)和输出机制几乎完全解耦。这种方法还允许您并行化标志渲染,以防您需要渲染非常非常大的标志;-):

      ma​​in.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;
      

      输出(N = 1)

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

      输出(N = 2)

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-30
        • 2012-10-06
        • 2013-01-16
        • 1970-01-01
        • 1970-01-01
        • 2012-05-09
        • 1970-01-01
        相关资源
        最近更新 更多