-- hw8.adb -- This just makes T's P's and M's travel around on screen -- Modify this and HW8pkg to finish homework. with HW8pkg ; use HW8pkg ; with HW8_Screen_IO ; use HW8_screen_IO ; procedure HW8 is begin Clear_Screen ; -- just start all 3 for HW7 experiment Target.Zoom ; Plane.Fly ; Missile.Zip ; -- this gets commented out, the plane launches the missile while T < 12.0 loop -- keep main program alive Put_Char (0, 0, " ") ; delay 1.0; end loop; -- experiment to see if this loop is needed with your compiler end HW8 ; -- HW8pkg.ads package HW8pkg is T : Float := 0.0 ; -- global clock, Target does updates task Target is -- task specification for Target entry Zoom ; end Target ; task Plane is -- task specification for Plane entry Fly ; end Plane ; task Missile is -- task specification for Missile entry Zip ; end Missile ; task Shared is -- Shared task specification entry Report (Who : Integer ; X, Y, VX, VY : Float) ; entry Read_Out (Who : Integer ; X, Y, VX, VY : out Float) ; entry Plot (Who : String ; X, Y : Float) ; end Shared ; end HW8pkg ; -- hw8pkg.adb with Ada.Numerics.Elementary_Functions ; use Ada.Numerics.Elementary_Functions ; with Text_IO ; use Text_IO ; with HW8_Screen_IO ; use HW8_Screen_IO ; package body HW8pkg is Delta_T : Float := 0.01 ; -- change this to adjust speed on screen task body Target is TGT_X : Float := 2.0 ; TGT_Y : Float := 1.0 ; TGT_Xold : Float := 2.0 ; TGT_Yold : Float := 1.0 ; begin accept Zoom ; loop T := T + Delta_T ; -- delay 0.1 ; -- this may help or hurt ? TGT_X := 0.90 * COS(3.0*T) + 1.0 ; TGT_Y := 0.90 * SIN(5.0*T) + 1.0 ; Shared.Plot (" ", TGT_Xold, TGT_Yold ) ; -- erase old Shared.Plot ("T", TGT_X, TGT_Y ) ; Shared.Report ( 1, TGT_X, TGT_Y, (TGT_X-TGT_Xold)/Delta_T , -- velocity (TGT_Y-TGT_Yold)/Delta_T ) ; -- velocity TGT_Xold := TGT_X ; TGT_Yold := TGT_Y ; exit when T > 12.0 ; -- this stops task end loop ; abort Plane ; abort Missile ; abort Shared ; end Target ; task body Plane is -- TASK BODY FOR Plane Plane_X : Float := 1.1 ; Plane_Y : Float := 0.0 ; Plane_Xold : Float := 1.1 ; Plane_Yold : Float := 0.0 ; Target_X : Float ; -- data assumed from radar tracking Target_Y : Float ; Target_VX : Float ; Target_VY : Float ; begin accept Fly ; loop Shared.Read_Out ( 1, Target_X, Target_Y, Target_VX, Target_VY ) ; Plane_X := COS(1.0*T) + 1.0 ; -- Replace this with code Plane_Y := SIN(1.0*T) + 1.0 ; -- to track the target and -- fire the missile when close Shared.Plot (" ", Plane_Xold, Plane_Yold) ; Shared.Plot ("P", Plane_X, Plane_Y) ; Plane_Xold := Plane_X ; Plane_Yold := Plane_Y ; end loop ; end Plane ; task body Missile is -- TASK BODY FOR Missile Missile_X : Float ; Missile_Y : Float ; begin accept Zip ; loop Missile_X := 0.5*COS(2.0*T) + 1.0 ; Missile_Y := 0.5*SIN(2.0*T) + 1.0 ; Shared.Plot ("M", Missile_X, Missile_Y) ; -- no erase end loop ; end Missile ; task body Shared is -- Shared task body TX, TY, TVX, TVY : Float ; -- Who=1 data from Target for Plane and Missile PX, PY, PVX, PVY : Float ; -- Who=2 data from Plane for Missile begin loop select accept Report (Who : Integer ; X, Y, VX, VY : Float) do if Who=1 then TX:=X; TY:=Y; TVX:=VX; TVY:=VY; else PX:=X; PY:=Y; PVX:=VX; PVY:=VY; end if; end ; or accept Read_Out (Who : Integer ; X, Y, VX, VY: out Float) do if Who=1 then X:=TX; Y:=TY; VX:=TVX; VY:=TVY; else X:=PX; Y:=PY; VX:=PVX; VY:=PVY; end if; end ; or accept Plot (Who : String ; X, Y : Float) do declare -- center of screen is (0.0,0.0) I : Integer := Integer ( Y * 11.0 + 1.0 ) ; J : Integer := Integer ( X * 36.0 + 1.0 ) ; begin if Who = "T" then Put_Bold(I, J, Who); -- This is VT100 type output else -- replace this Plot section with Put_Char(I, J, Who ); -- other code if you wish end if; end ; end ; or terminate ; end select ; end loop ; end Shared ; end HW8pkg ; -- hw8_screen_io.ads package HW8_Screen_IO is procedure Put_Char ( Line : in Integer ; Column : in Integer ; Plot_Str : in String ) ; procedure Put_Bold ( Line : in Integer ; Column : in Integer ; Plot_Str : in String ) ; procedure CLEAR_SCREEN ; end HW8_SCREEN_IO ; -- hw8_screen_io.adb with Ada.Text_IO ; use Ada.Text_IO ; package body HW8_Screen_IO is package INT_IO is new Integer_IO ( Integer ) ; use INT_IO ; procedure Put_Char ( Line : in Integer ; Column : in Integer ; Plot_Str : in String ) is L , C : Integer ; begin -- Validate the value passed for the Line number - between 1 and 23 -- 23 is needed because when program terminates it scrools screen if -- at bottom as is the case here. -- Don't raise, a fuss - just clip at top and bottom L := Line ; if L < 1 then L := 1 ; elsif L > 23 then L := 23 ; end if ; -- Validate the value passed for the Column number - between 0 and 79 -- Don't raise a fuss, just clip at each edge C := Column ; if C < 1 then C := 1 ; elsif C + Plot_Str'Length > 80 then C := 80 - Plot_Str'Length ; end if ; -- Now output the whole String, prefixed with [ and -- terminated with "f" PUT ( Ascii.Esc & "[" ) ; -- this might have to be one Put PUT ( L , 0 ) ; -- concatenating the Strings PUT ( ";" ) ; -- on some compilers PUT ( C , 0 ) ; PUT ( "f" & Plot_Str ) ; end Put_Char ; procedure Put_Bold ( Line : in Integer ; Column : in Integer ; Plot_Str : in String ) is begin Put_Char( Line, Column, Ascii.Esc & "[1m" & Plot_Str & Ascii.Esc & "[0m" ) ; end Put_Bold ; procedure Clear_Screen is begin PUT ( Ascii.Esc & "[2J" ) ; -- Clear the screen and home cursor end Clear_Screen ; end HW8_Screen_IO ;