将旗帜与对角线交叉画成V字形(ADA)。

问题描述 投票:0回答:1

我再次求助于Stackoverflow.以前在这里得到过帮助,我希望能再次得到同样友好的帮助。我有一个任务,我需要在ADA中画一面旗帜(包括周围的一个盒子状的形状和中间的十字的V形)。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?

它应该是一个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;

编辑:感谢吉姆-罗杰斯,我设法编辑我的程序来绘制旗帜。不幸的是,它的方式并不完全是它的意思是,因为顶部的十字架应该接触的两侧,而不是像现在这样的间距。另外,主程序和子程序每一个都不允许超过15行,所以我把它们分开了。

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

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

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

ada spaces
1个回答
2
投票

你需要跟踪'+'字符的左列和右列,每次迭代你的循环时增加左列的位置,减少右列的位置,以打印十字形.下面的程序适用于从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
------------------
|                |
| +           +  |
|  +         +   |
|   +       +    |
|    +     +     |
|     +   +      |
|      + +       |
|       +        |
|                |
------------------

2
投票

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

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;

产出 (N = 1)

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

产出 (N = 2)

$ ./main
+-----+
!+   +!
! + + !
!  +  !
+-----+
© www.soinside.com 2019 - 2024. All rights reserved.