labs_solar_system_1.0.0_4f650637/src/050_array_types/template/array_types_main.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
-----------------------------------------------------------------------
--                              Ada Labs                             --
--                                                                   --
--                 Copyright (C) 2008-2023, AdaCore                  --
--                                                                   --
-- This program is free software: you can redistribute it and/or     --
-- modify it under the terms of the GNU General Public License as    --
-- published by the Free Software Foundation, either version 3 of    --
-- the License, or (at your option) any later version.               --
--                                                                   --
-- This program is distributed in the hope that it will be useful,   --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of    --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     --
-- GNU General Public License for more details.                      --
--                                                                   --
-- You should have received a copy of the GNU General Public License --
-- along with this program.  If not, see                             --
-- <https://www.gnu.org/licenses/>.                                  --
-----------------------------------------------------------------------

with Ada.Real_Time; use Ada.Real_Time;
with Mage;          use Mage;
with Mage.Draw;     use Mage.Draw;
with Mage.Event;    use Mage.Event;
with Float_Maths;   use Float_Maths;

procedure Array_Types_Main is

   --  QUESTION 1 - Part 1

   --  define type Bodies_Enum_T as an enumeration of Sun, Earth, Moon,
   --  and Satellite
   --$ line answer
   type Bodies_Enum_T is (Sun, Earth, Moon, Satellite);

   --  define type Parameters_Enum_T as an enumeration of parameter X, Y,
   --  Radius, Speed, Distance, Angle
   --$ line answer
   type Parameters_Enum_T is (X, Y, Radius, Speed, Distance, Angle);

   --  define type Bodies_Array_T as an array of float indexed by bodies and
   --  parameters
   --$ line answer
   type Bodies_Array_T is array (Bodies_Enum_T, Parameters_Enum_T) of Float;

   --  define type Colors_Array_T as an array of color (RGBA_T) indexed by
   --  bodies
   --$ line answer
   type Colors_Array_T is array (Bodies_Enum_T) of RGBA_T;

   --  declare variable Bodies which is an instance of Bodies_Array_T
   --$ line answer
   Bodies : Bodies_Array_T;

   --  declare variable Colors which is an instance of Colors_Array_T
   --$ line answer
   Colors : Colors_Array_T;

   --  declare a variable Next of type Time to store the Next step time
   Next : Time;

   --  declare a constant Period of 40 milliseconds of type Time_Span
   --  which defines the looping period
   Period  : constant Time_Span := Milliseconds (40);

   --  reference to the application window
   Window : Window_ID;

   --  reference to the graphical canvas associated with the application window
   Canvas : Canvas_ID;

begin

   --  create a window 240x320
   Window := Create_Window (Width  => 240,
                            Height => 320,
                            Name   => "Solar System");

   --  retrieve the graphical canvas from the window
   Canvas := Get_Canvas (Window);

   --  QUESTION 1 - Part 2
   --  initialize Bodies variable with parameters for each body using an
   --  aggregate:
   --    Sun Distance = 0.0, Angle = 0.0, Speed = 0.0, Radius = 20.0;
   --    Earth Distance = 50.0, Angle = 0.0, Speed = 0.02, Radius = 5.0;
   --    Moon Distance = 15.0, Angle = 0.0, Speed = 0.04, Radius = 2.0;
   --    Satellite Distance = 8.0, Angle = 0.0, Speed = 0.1, Radius = 1.0;
   --$ begin answer
   Bodies := (Sun => (Distance => 0.0,
                      Speed => 0.0,
                      Radius => 20.0,
                      X => 0.0,
                      Y => 0.0,
                      Angle => 0.0),
              Earth => (Distance => 50.0,
                        Speed => 0.02,
                        Radius => 5.0,
                        X => 0.0,
                        Y => 0.0,
                        Angle => 0.0),
              Moon => (Distance => 15.0,
                       Speed => 0.04,
                       Radius => 2.0,
                       X => 0.0,
                       Y => 0.0,
                       Angle => 0.0),
              Satellite => (Distance => 8.0,
                            Speed => 0.1,
                            Radius => 1.0,
                            X => 0.0,
                            Y => 0.0,
                            Angle => 0.0));
   --$ end answer

   --  QUESTION 1 - Part 3
   --  initialize Colors variable:
   --  Sun is Yellow, Earth is Blue, Moon is White, Satellite is Red
   --$ begin answer
   Colors := (Sun => Yellow,
              Earth => Blue,
              Moon => White,
              Satellite => Red);
   --$ end answer

   --  initialize the Next step time as current time (Clock) + period
   Next := Clock + Period;

   while not Is_Killed loop

      --  QUESTION 2 - part 1
      --  create a loop to update each body position and angles
      --  Note: the Sun does not orbit against any body, you may declare
      --  and use a subtype to reference the orbiting bodies
      --    - the position of an object around (0,0) at distance d with an
      --    angle a is (d*cos(a), d*sin(a))
      --    - update angle parameter of each body adding speed to the previous
      --    angle.
      --$ begin answer
      for B in Earth .. Satellite loop
         --  This solution illustrates the use of a block statement with
         --  local constants to reduce repetition and improve readability
         --  in the loop body.
         declare
            This_Pred : constant Bodies_Enum_T := Bodies_Enum_T'Pred (B);
            D         : constant Float := Bodies (B, Distance);
            A         : constant Float := Bodies (B, Angle);
         begin
            Bodies (B, X) := Bodies (This_Pred, X) + D * Cos (A);
            Bodies (B, Y) := Bodies (This_Pred, Y) + D * Sin (A);
            Bodies (B, Angle) := A + Bodies (B, Speed);
         end;
      end loop;
      --$ end answer

      --  loop to draw every objects

      --  QUESTION 2 - part 2
      --  create a loop to draw every objects
      --    use the Draw_Sphere procedure with the Point3D
      --    argument (using Z = 0.0) to draw
      --$ begin answer
      for B in Bodies_Enum_T loop
         Draw_Sphere (Canvas   => Canvas,
                      Position => (Bodies (B, X), Bodies (B, Y), 0.0),
                      Radius   => Bodies (B, Radius),
                      Color    => Colors (B));
      end loop;
      --$ end answer

      --  update the screen using procedure Swap_Buffers
      Handle_Events (Window);

      --  wait until Next
      delay until Next;

      --  update the Next time adding the period for the next step
      Next := Next + Period;

   end loop;
end Array_Types_Main;