{* * @(#) airsimul.pas - Air Defense Forces activity simulation program * (Task 3 at the Special Military Training course). * (c) 1997 Ivan Maidanski http://ivmai.chat.ru * Freeware program source. All rights reserved. ** * Language: Turbo Pascal * Tested with: Turbo Pascal v6.0 * Last modified: 1997-12-08 13:40:00 GMT+03:00 *} program AirDefenseSimulator; uses SimPas; { special simulation module used } const OnStart= 100; Obzor= 1; Start1= 2; Start2= 3; Zona= 4; Manevr= 5; BombObj= 6; BombAIA= 7; BombRLS= 8; BombZRK1= 9; BombZRK2= 10; Finish1= 11; Finish2= 12; UkazZRK1= 13; UkazZRK2= 14; UkazAIA= 15; Perehvat= 16; Perehvat1= 17; Perehvat2= 18; Uhod= 19; SvobZRK1= 20; SvobZRK2= 21; SvobAIA= 22; Gotov= 23; type EnemyPlanePntr=^EnemyPlaneType; EnemyPlaneType= record N1,N2: Integer; HMin,HMax,VMin,VMax: Real; RBomb: Real; RestTime: Real; Importance: Real; P_Detect: Real; P_AIA,P_ZRK1,P_ZRK2: Real; P_Kill: Real; Cnt1,Cnt2: Integer; Next: EnemyPlanePntr; end; DataPntr=^DataType; DataType= record PlaneType: EnemyPlanePntr; BaseIndex: Integer; StartX,StartY: Real; StartTime,EndTime: Real; VX,VY,H: Real; InZone,Detected,Scheduled: Boolean; Next: DataPntr; end; EnemyBaseType= record X,Y: Real; Lambda: Real; P_Obj,P_RLS,P_AIA,P_ZRK1,P_ZRK2: Real; end; ObjType= record X,Y: Real; P_Hit: Real; HitCnt: Integer; BombCnt: Integer; end; RLSType= record X,Y: Real; P_Hit: Real; HitCnt: Integer; ObserveTime: Real; DMin,D1,D2,DMax: Real; BombCnt: Integer; end; ZRKType= record X,Y: Real; P_Hit: Real; HitCnt: Integer; MissileCnt,ChannelCnt: Integer; V,RBurst,RMin,RMax,HMin,HMax: Real; ReadyTime: Real; BombCnt: Integer; FreeMissiles,FreeChannels: Integer; end; AIAType= record X,Y: Real; P_Hit: Real; HitCnt: Integer; JetCnt,ChannelCnt: Integer; RMax,HMin,H0,HMax,V,KLow,KHigh: Real; RFight: Real; ReadyTime,RestTime: Real; BombCnt: Integer; FreeJets,FreeChannels: Integer; end; var LifeTime: Real; RepeatCnt: Integer; Obj: ObjType; RLS: RLSType; ZRK1,ZRK2: ZRKType; AIA: AIAType; EnemyBase1,EnemyBase2: EnemyBaseType; EnemyPlaneTypes: EnemyPlanePntr; TotalKilled,NToObj,NBombObj: Integer; CurPlanes: DataPntr; procedure ReadCoords(var X,Y: Real); begin Write(' X= '); ReadLn(X); Write(' Y= '); ReadLn(Y); end; procedure ReadProbability(var P: Real; S: String); begin repeat Write(' P_',S,'= '); ReadLn(P); until (P>=0) and (P<=1); end; procedure ReadCount(var N: Integer; S: String); begin repeat Write(' ',S,'_Count= '); ReadLn(N); until N>=1; end; procedure ReadRange(var R: Real; Min: Real; S: String); begin repeat Write(' ',S,'= '); ReadLn(R); until R>Min; end; procedure ReadObjectBasics(var X,Y,P_Hit: Real; var HitCnt: Integer); begin ReadCoords(X,Y); ReadProbability(P_Hit,'Hit'); ReadCount(HitCnt,'Hit'); end; procedure SafeFinish; begin Route:=Node^.Next; while Route<>Node do begin Route^.Addr:=nil; Route:=Route^.Next; end; Finish; end; function SearchMinEvent(Target: Integer): DataPntr; begin SearchMinEvent:=nil; Route:=Node^.Next; while (Route<>Node) and ((Route^.Numb<>Target) or (Route^.Addr=nil)) do Route:=Route^.Next; if Route^.Numb=Target then SearchMinEvent:=Route^.Addr; end; function GetPlaneX(Plane: DataType; Time: Real): Real; begin with Plane do GetPlaneX:=StartX+(Time-StartTime)*VX; end; function GetPlaneY(Plane: DataType; Time: Real): Real; begin with Plane do GetPlaneY:=StartY+(Time-StartTime)*VY; end; procedure ObjectInit; begin WriteLn('Object:'); with Obj do ReadObjectBasics(X,Y,P_Hit,HitCnt); WriteLn; end; procedure ObjectRepair; begin Obj.BombCnt:=0; end; procedure ObjectCheckBombs; begin Route:=Node; repeat if Route^.Numb=BombObj then Inc(NBombObj); Route:=Route^.Next; until Route=Node; end; procedure ObjectDestroyed; begin WriteLn('Object destroyed!!!'); ObjectCheckBombs; SafeFinish; end; function AIACheckDeactivated: Boolean; begin AIACheckDeactivated:=(AIA.BombCnt>=AIA.HitCnt) or ((AIA.FreeJets<=0) and (AIA.FreeChannels>=AIA.ChannelCnt)); end; function ZRKCheckDeactivated(ZRK : ZRKType): Boolean; begin ZRKCheckDeactivated:=(ZRK.BombCnt>=ZRK.HitCnt) or ((ZRK.FreeMissiles<=0) and (ZRK.FreeChannels>=ZRK.ChannelCnt)); end; function CheckNotDeactivated: Boolean; begin CheckNotDeactivated:=True; if AIACheckDeactivated and ZRKCheckDeactivated(ZRK1) and ZRKCheckDeactivated(ZRK2) then begin ObjectCheckBombs; SafeFinish; CheckNotDeactivated:=False; end; end; function GetPlaneTime(Plane: DataType; X,Y,R: Real): Real; var V: Real; begin GetPlaneTime:=-1; X:=X-Plane.StartX; Y:=Y-Plane.StartY; R:=X*X+Y*Y-R*R; if R>0 then begin with Plane do V:=VX*VX+VY*VY; if V>0 then begin R:=R/V; V:=(Plane.VX*X+Plane.VY*Y)/V; R:=V*V-R; if R>=0 then begin R:=Sqrt(R); if V>=R then V:=V-R else V:=V+R; with Plane do if (V>=0) and ((EndTime<0) or (V0 then begin B:=B/A; V:=V/A; V:=B*B-V; if V>=0 then begin V:=Sqrt(V); B:=Plane.StartTime+B-R; if B-V>=Time then B:=B-V else B:=B+V; if B0 then begin B:=Plane.StartTime+V/(2*B)-R; if BTime then begin BurstDelay:=GetCatchTime(Plane,LaunchTime, ZRK.X,ZRK.Y,ZRK.V,ZRK.RBurst)-LaunchTime; with ZRK do if (BurstDelay*BurstDelay*V*VRMax*RMax+HMax*HMax) or (LaunchTime+BurstDelay>=Plane.EndTime) then LaunchTime:=LaunchTime-Sqrt(RMax*RMax+HMax*HMax)/V; end; if LaunchTime>Time then ZRKOptimalLaunchDelay:=LaunchTime-Time else ZRKOptimalLaunchDelay:=0; end; function ZRKGetCapacity(ZRK: ZRKType; Plane: DataType; P_Kill: Real; Time: Real): Real; begin ZRKGetCapacity:=0; if (ZRK.BombCnt0) and (ZRK.FreeChannels>0) and (Plane.H>=ZRK1.HMin) and (Plane.H<=ZRK1.HMax) and (GetPlaneTime(Plane,ZRK.X,ZRK.Y,ZRK.RMax)>=0) and (GetCatchTime(Plane,Time+ZRK.ReadyTime, ZRK.X,ZRK.Y,ZRK.V,ZRK.RBurst)>=Time+ZRK.ReadyTime) then ZRKGetCapacity:=P_Kill*Ln(Plane.EndTime-Time)* Plane.PlaneType^.Importance; end; procedure ZRK1Order(Plane: DataPntr; Time: Real); begin if ZRK1.BombCntnil then begin Prepare(Perehvat1,0,Plane); WriteLn('ready to launch.'); end else WriteLn('not ready due to enemy plane''s maneuver...'); end else if Plane<>nil then Plane^.Scheduled:=False; if (ZRK1.BombCnt>=ZRK1.HitCnt) or (Plane=nil) then begin Inc(ZRK1.FreeChannels); Inc(ZRK1.FreeMissiles); end; end; procedure ZRK2Order(Plane: DataPntr; Time: Real); begin if ZRK2.BombCntnil then begin Prepare(Perehvat2, ZRKOptimalLaunchDelay(ZRK2,Plane^,Time),Plane); WriteLn('ready to launch.'); end else WriteLn('not ready due to enemy plane''s maneuver...'); end else if Plane<>nil then Plane^.Scheduled:=False; if (ZRK2.BombCnt>=ZRK2.HitCnt) or (Plane=nil) then begin Inc(ZRK2.FreeChannels); Inc(ZRK2.FreeMissiles); end; end; procedure ZRK1Launch(Plane: DataPntr; Time: Real); var BurstTime: Real; begin BurstTime:=-1; if ZRK1.BombCntnil) and (Plane^.H>=ZRK1.HMin) and (Plane^.H<=ZRK1.HMax) then BurstTime:=GetCatchTime(Plane^,Time, ZRK1.X,ZRK1.Y,ZRK1.V,ZRK1.RBurst); if BurstTime>Time then begin Prepare(SvobZRK1,BurstTime-Time,Plane); Write('launches '); if ZRK1.FreeMissiles<=0 then Write('last '); WriteLn('missile.'); end else WriteLn('cannot launch missile ', '(enemy plane''s maneuver)...'); end; if BurstTime<=Time then begin Inc(ZRK1.FreeChannels); Inc(ZRK1.FreeMissiles); if Plane<>nil then Plane^.Scheduled:=False; end; end; procedure ZRK2Launch(Plane: DataPntr; Time: Real); var BurstTime: Real; begin BurstTime:=-1; if ZRK2.BombCntnil) and (Plane^.H>=ZRK2.HMin) and (Plane^.H<=ZRK2.HMax) then BurstTime:=GetCatchTime(Plane^,Time, ZRK2.X,ZRK2.Y,ZRK2.V,ZRK2.RBurst); if BurstTime>Time then begin Prepare(SvobZRK2,BurstTime-Time,Plane); Write('launches '); if ZRK2.FreeMissiles<=0 then Write('last '); WriteLn('missile.'); end else WriteLn('cannot launch missile ', '(enemy plane''s maneuver)...'); end; if BurstTime<=Time then begin Inc(ZRK2.FreeChannels); Inc(ZRK2.FreeMissiles); if Plane<>nil then Plane^.Scheduled:=False; end; end; procedure ZRK1CatchPlane(Plane: DataPntr; Time: Real); var Flag: Boolean; begin Inc(ZRK1.FreeChannels); Write(Time:10:0,'. Missile (from ZRK1) '); if (Plane<>nil) and (Plane^.H>=ZRK1.HMin) and (Plane^.H<=ZRK1.HMax) then begin WriteLn('fired!'); if RNDnil then Plane^.Scheduled:=False; WriteLn('lost target and self destroyed.'); end; Flag:=CheckNotDeactivated; end; procedure ZRK2CatchPlane(Plane: DataPntr; Time: Real); var Flag: Boolean; begin Inc(ZRK2.FreeChannels); Write(Time:10:0,'. Missile (from ZRK2) '); if (Plane<>nil) and (Plane^.H>=ZRK2.HMin) and (Plane^.H<=ZRK2.HMax) then begin WriteLn('fired!'); if RNDnil then Plane^.Scheduled:=False; WriteLn('lost target and self destroyed.'); end; Flag:=CheckNotDeactivated; end; procedure AIAInit; begin WriteLn('AIA:'); with AIA do begin ReadObjectBasics(X,Y,P_Hit,HitCnt); ReadCount(JetCnt,'Jet'); ReadCount(ChannelCnt,'Jet_Channel'); ReadRange(RMax,0,'RMax'); ReadRange(HMin,0,'HMin'); ReadRange(H0,HMin,'H0'); ReadRange(HMax,H0,'HMax'); ReadRange(KHigh,0,'K_High'); ReadRange(KLow,KHigh,'K_Low'); ReadRange(V,0,'Speed'); ReadRange(RFight,0,'Fight_Radius'); ReadRange(ReadyTime,0,'Ready_Delay'); ReadRange(RestTime,0,'Restore_Delay'); end; WriteLn; end; procedure AIARepair; begin with AIA do begin BombCnt:=0; FreeJets:=JetCnt; FreeChannels:=ChannelCnt; end; end; function AIAGetRadius(H: Real): Real; begin AIAGetRadius:=0; if H>=AIA.HMin then if H0) and (AIA.FreeChannels>0) and (GetPlaneTime(Plane,AIA.X,AIA.Y,AIAGetRadius(Plane.H))>=0) and (GetCatchTime(Plane,Time+AIA.ReadyTime, AIA.X,AIA.Y,AIA.V,AIA.RFight)>=Time+AIA.ReadyTime) then AIAGetCapacity:=Plane.PlaneType^.P_AIA*Ln(Plane.EndTime-Time)* Plane.PlaneType^.Importance; end; procedure AIAOrder(Plane: DataPntr; Time: Real); var CatchTime: Real; begin CatchTime:=-1; if AIA.BombCntnil then CatchTime:=GetCatchTime(Plane^,Time, AIA.X,AIA.Y,AIA.V,AIA.RFight); if CatchTime>Time then begin Prepare(Perehvat,CatchTime-Time,Plane); WriteLn('starts!'); end else WriteLn('cannot start due to enemy plane''s maneuver...'); end; if CatchTime<=Time then begin Inc(AIA.FreeJets); Inc(AIA.FreeChannels); if Plane<>nil then Plane^.Scheduled:=False; end; end; procedure AIAJetFight(Plane: DataPntr; Time: Real); begin Inc(AIA.FreeChannels); Write(Time:10:0,'. AIA jet '); if (Plane<>nil) and (Plane^.H>=AIA.HMin) and (Plane^.H<=AIA.HMax) then begin WriteLn('starts fighting with enemy plane.'); if RNDnil then Plane^.Scheduled:=False; Prepare(SvobAIA,AIA.RestTime,nil); WriteLn('lost target and goes back!'); end; end; procedure AIAJetGoBack(Plane: DataPntr; Time: Real); var Flag: Boolean; begin Write(Time:10:0,'. AIA '); if Plane<>nil then begin Prepare(SvobAIA,AIAGetReturnDelay(Plane^,Time)+AIA.RestTime,nil); WriteLn('jet goes back.'); end else begin WriteLn('jet killed!!!'); Flag:=CheckNotDeactivated; end; end; procedure AIAJetReturn(Time: Real); begin Inc(AIA.FreeJets); if AIA.BombCnt=RLS.DMin) and (D<=RLS.DMax) then begin P:=Plane.PlaneType^.P_Detect; if D>RLS.D2 then P:=P*(RLS.DMax-D)/(RLS.DMax-RLS.D2) else if Dnil do begin if Plane^.InZone and not Plane^.Detected and RLSPlaneDetected(Plane^,Time) then begin Plane^.Detected:=True; WriteLn(Time:10:0,'. Enemy plane detected!'); end; Plane:=Plane^.Next; end; end; procedure RLSNewOrder(Time :Real); var Plane,Target: DataPntr; Means: Integer; Value,Best: Real; begin repeat Plane:=CurPlanes; Best:=0; while Plane<>nil do begin if Plane^.Detected and not Plane^.Scheduled then begin Value:=AIAGetCapacity(Plane^,Time); if Value>Best then begin Target:=Plane; Means:=0; Best:=Value; end; Value:=ZRKGetCapacity(ZRK1,Plane^, Plane^.PlaneType^.P_ZRK1,Time); if Value>Best then begin Target:=Plane; Means:=1; Best:=Value; end; Value:=ZRKGetCapacity(ZRK2,Plane^, Plane^.PlaneType^.P_ZRK2,Time); if Value>Best then begin Target:=Plane; Means:=2; Best:=Value; end; end; Plane:=Plane^.Next; end; if Best>0 then begin Target^.Scheduled:=True; Write(Time:10:0,'. '); if Means=0 then begin Dec(AIA.FreeChannels); Dec(AIA.FreeJets); Prepare(UkazAIA,AIA.ReadyTime,Target); Write('AIA'); end else if Means=1 then begin Dec(ZRK1.FreeChannels); Dec(ZRK1.FreeMissiles); Prepare(UkazZRK1,ZRK1.ReadyTime,Target); Write('ZRK1'); end else begin Dec(ZRK2.FreeChannels); Dec(ZRK2.FreeMissiles); Prepare(UkazZRK2,ZRK2.ReadyTime,Target); Write('ZRK2'); end; WriteLn(' ordered to destroy enemy plane.'); end; until Best=0; end; procedure RLSObserveCycle(Time: Real); begin RLSDetectAllPlanes(Time); RLSNewOrder(Time); Prepare(Obzor,RLS.ObserveTime,nil); end; procedure RLSDestroyed; begin WriteLn('RLS destroyed!!!'); ObjectCheckBombs; SafeFinish; end; procedure EnemyBaseInit(var Base: EnemyBaseType); begin with Base do begin ReadCoords(X,Y); ReadRange(Lambda,0,'Lambda'); ReadProbability(P_Obj,'Object'); ReadProbability(P_RLS,'RLS'); ReadProbability(P_AIA,'AIA'); ReadProbability(P_ZRK1,'ZRK1'); ReadProbability(P_ZRK2,'ZRK2'); end; WriteLn; end; procedure EnemyPlaneTypesInit; var I,N: Integer; P: EnemyPlanePntr; begin EnemyPlaneTypes:=nil; WriteLn('Enemy Plane Types:'); ReadCount(N,'Plane_Type'); WriteLn; for I:=1 to N do begin New(P); WriteLn('Enemy Plane Type ',I,':'); with P^ do begin ReadCount(N1,'Base1'); ReadCount(N2,'Base2'); ReadRange(HMin,0,'HMin'); ReadRange(HMax,HMin,'HMax'); ReadRange(VMin,0,'VMin'); ReadRange(VMax,VMin,'VMax'); ReadRange(RBomb,1,'Bomb_Radius'); ReadRange(RestTime,0,'Restore_Delay'); ReadRange(Importance,0,'Importance'); ReadProbability(P_Detect,'Detect'); ReadProbability(P_AIA,'KillByAIA'); ReadProbability(P_ZRK1,'KillByZRK1'); ReadProbability(P_ZRK2,'KillByZRK2'); ReadProbability(P_Kill,'KillJet'); Next:=EnemyPlaneTypes; end; WriteLn; EnemyPlaneTypes:=P; end; end; procedure EnemyInit; begin WriteLn('Enemy Base1:'); EnemyBaseInit(EnemyBase1); WriteLn('Enemy Base2:'); EnemyBaseInit(EnemyBase2); EnemyPlaneTypesInit; end; procedure EnemyPrepair; var P: EnemyPlanePntr; begin CurPlanes:=nil; P:=EnemyPlaneTypes; while P<>nil do begin P^.Cnt1:=P^.N1; P^.Cnt2:=P^.N2; P:=P^.Next; end; Prepare(Start1,NegExp(EnemyBase1.Lambda),nil); Prepare(Start2,NegExp(EnemyBase2.Lambda),nil); end; procedure EnemyNewPlane(BaseN: Integer; BaseX,BaseY: Real; Time: Real; P: EnemyPlanePntr; Speed,Height: Real); var Plane: DataPntr; begin New(Plane); with Plane^ do begin PlaneType:=P; BaseIndex:=BaseN; StartTime:=Time; EndTime:=Time; StartX:=BaseX; StartY:=BaseY; VX:=Speed; VY:=0; H:=Height; InZone:=False; Detected:=False; Scheduled:=False; Next:=CurPlanes; end; CurPlanes:=Plane; end; function EnemySelectTarget(var X,Y: Real; P_Obj,P_RLS,P_AIA,P_ZRK1,P_ZRK2: Real): Integer; var P: Real; begin if AIA.BombCnt>=AIA.HitCnt then P_AIA:=0; if ZRK1.BombCnt>=ZRK1.HitCnt then P_ZRK1:=0; if ZRK2.BombCnt>=ZRK2.HitCnt then P_ZRK2:=0; P:=Uniform(0,P_Obj+P_RLS+P_AIA+P_ZRK1+P_ZRK2)-P_Obj-P_RLS; if P<=0 then if P+P_RLS<=0 then begin X:=Obj.X; Y:=Obj.Y; Inc(NToObj); Write('Object'); EnemySelectTarget:=BombObj; end else begin X:=RLS.X; Y:=RLS.Y; Write('RLS'); EnemySelectTarget:=BombRLS; end else if P0 then begin VX:=VX*Speed/D; VY:=VY*Speed/D; end; EndTime:=-1; EndTime:=GetPlaneTime(Plane,TX,TY,PlaneType^.RBomb); EnemyChangePlane:=EndTime; end; end; procedure EnemyStartPlane(BaseIndex: Integer; P: EnemyPlanePntr; Time: Real); var TX,TY: Real; Target: Integer; ZoneTime,BombTime: Real; begin Write(Time:10:0,'. { Enemy plane starts to '); if BaseIndex=1 then with EnemyBase1 do Target:=EnemySelectTarget(TX,TY,P_OBj,P_RLS,P_AIA,P_ZRK1,P_ZRK2) else with EnemyBase2 do Target:=EnemySelectTarget(TX,TY,P_OBj,P_RLS,P_AIA,P_ZRK1,P_ZRK2); WriteLn(' from airbase ',BaseIndex,' }'); if BaseIndex=1 then EnemyNewPlane(1,EnemyBase1.X,EnemyBase1.Y,Time,P, Uniform(P^.VMin,P^.VMax),Uniform(P^.HMin,P^.HMax)) else EnemyNewPlane(2,EnemyBase2.X,EnemyBase2.Y,Time,P, Uniform(P^.VMin,P^.VMax),Uniform(P^.HMin,P^.HMax)); BombTime:=EnemyChangePlane(CurPlanes^,Time,TX,TY); with RLS do ZoneTime:=GetPlaneTime(CurPlanes^,X,Y,DMax); if (ZoneTime>=Time) and (ZoneTime=Time) and (ZoneTimenil do begin N:=N+P^.Cnt1; P:=P^.Next; end; P:=EnemyPlaneTypes; if N>0 then begin N:=Trunc(RND*N); while N>=P^.Cnt1 do begin N:=N-P^.Cnt1; P:=P^.Next; end; Dec(P^.Cnt1); EnemyStartPlane(1,P,Time); end; Prepare(Start1,NegExp(EnemyBase1.Lambda),nil); end; procedure EnemyStart2(Time: Real); var P: EnemyPlanePntr; N: Integer; begin P:=EnemyPlaneTypes; N:=0; while P<>nil do begin N:=N+P^.Cnt2; P:=P^.Next; end; P:=EnemyPlaneTypes; if N>0 then begin N:=Trunc(RND*N); while N>=P^.Cnt2 do begin N:=N-P^.Cnt2; P:=P^.Next; end; Dec(P^.Cnt2); EnemyStartPlane(2,P,Time); end; Prepare(Start2,NegExp(EnemyBase2.Lambda),nil); end; procedure EnemyEntersZone(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin Plane^.InZone:=True; WriteLn(Time:10:0,'. { Enemy plane enters air defense zone }'); end; end; procedure EnemyMakesManeuver(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin Plane^.H:=Uniform(Plane^.PlaneType^.HMin,Plane^.PlaneType^.HMax); WriteLn(Time:10:0,'. { Enemy plane makes maneuver }'); if Plane^.Detected then begin Write(Time:10:0,'. Enemy '); if Plane^.Scheduled then Write('(scheduled) '); WriteLn('plane lost by RLS!!!'); Plane^.Detected:=False; end; end; end; procedure EnemyRemoveEvents(Plane: DataPntr); begin Route:=Node^.Next; while Route<>Node do begin if Route^.Addr=Plane then Route^.Addr:=nil; Route:=Route^.Next; end; end; procedure EnemyRescheduleAllPlanes(Target: Integer; Time: Real); var Plane: DataPntr; begin Plane:=SearchMinEvent(Target); while Plane<>nil do begin EnemyRemoveEvents(Plane); EnemyReschedulePlane(Plane,Time); Plane:=SearchMinEvent(Target); end; end; procedure EnemyHitsObject(Time: Real); begin WriteLn(Time:10:0,'. Enemy plane hits Object!!!'); Inc(Obj.BombCnt); if Obj.BombCnt>=Obj.HitCnt then ObjectDestroyed; end; procedure EnemyBombsObject(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin WriteLn(Time:10:0,'. Enemy plane bombs Object!'); Inc(NBombObj); if RND=RLS.HitCnt then RLSDestroyed; end; procedure EnemyBombsRLS(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin WriteLn(Time:10:0,'. Enemy plane bombs RLS!'); if RND=AIA.HitCnt then begin WriteLn('AIA destroyed!!!'); if CheckNotDeactivated then EnemyRescheduleAllPlanes(BombAIA,Time); end; end; procedure EnemyBombsAIA(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin WriteLn(Time:10:0,'. Enemy plane bombs AIA!'); if RND=ZRK1.HitCnt then begin WriteLn('ZRK1 destroyed!!!'); if CheckNotDeactivated then EnemyRescheduleAllPlanes(BombZRK1,Time); end; end; procedure EnemyBombsZRK1(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin WriteLn(Time:10:0,'. Enemy plane bombs ZRK1.'); if RND=ZRK2.HitCnt then begin WriteLn('ZRK2 destroyed!!!'); if CheckNotDeactivated then EnemyRescheduleAllPlanes(BombZRK2,Time); end; end; procedure EnemyBombsZRK2(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin WriteLn(Time:10:0,'. Enemy plane bombs ZRK2.'); if RNDnil do with P^ do begin N:=N+Cnt1+Cnt2; P:=Next; end; EnemyReadyPlaneCount:=N; end; procedure EnemyDestroyed; begin WriteLn('Enemy destroyed!!!!!'); SafeFinish; end; procedure EnemyRemovePlane(Plane: DataPntr); var Q: DataPntr; begin if Plane<>CurPlanes then begin Q:=CurPlanes; while Plane<>Q^.Next do Q:=Q^.Next; Q^.Next:=Plane^.Next; end else CurPlanes:=Plane^.Next; Dispose(Plane); end; procedure EnemyPlaneKilled(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin EnemyRemoveEvents(Plane); EnemyRemovePlane(Plane); Inc(TotalKilled); WriteLn(Time:10:0,'. Enemy plane killed.'); if (CurPlanes=nil) and (EnemyReadyPlaneCount=0) then EnemyDestroyed; end; end; procedure EnemyPlaneReturn1(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin Inc(Plane^.PlaneType^.Cnt1); EnemyRemovePlane(Plane); WriteLn(Time:10:0, '. { Enemy plane ready to start at airbase 1 }'); end; end; procedure EnemyPlaneReturn2(Plane: DataPntr; Time: Real); begin if Plane<>nil then begin Inc(Plane^.PlaneType^.Cnt2); EnemyRemovePlane(Plane); WriteLn(Time:10:0, '. { Enemy plane ready to start at airbase 2 }'); end; end; procedure EnemyCleanUp; var Plane: DataPntr; begin while CurPlanes<>nil do begin Plane:=CurPlanes; CurPlanes:=Plane^.Next; Dispose(Plane); end; end; procedure EnemyDone; var P: EnemyPlanePntr; begin while EnemyPlaneTypes<>nil do begin P:=EnemyPlaneTypes; EnemyPlaneTypes:=P^.Next; Dispose(P); end; end; begin ReadCount(RepeatCnt,'Repeat'); WriteLn; ObjectInit; RLSInit; ZRKsInit; AIAInit; EnemyInit; LifeTime:=0; TotalKilled:=0; NToObj:=0; NBombObj:=0; repeat Start(OnStart,0,nil,1E9); WriteLn('Loop ',Repeater,'...'); while Simulate do case ActNumb of OnStart: begin ObjectRepair; RLSRepair; ZRKsRepair; AIARepair; EnemyPrepair; end; Obzor: RLSObserveCycle(ActTime); Start1: EnemyStart1(ActTime); Start2: EnemyStart2(ActTime); Zona: EnemyEntersZone(ActAddr,ActTime); Manevr: EnemyMakesManeuver(ActAddr,ActTime); BombObj: EnemyBombsObject(ActAddr,ActTime); BombAIA: EnemyBombsAIA(ActAddr,ActTime); BombRLS: EnemyBombsRLS(ActAddr,ActTime); BombZRK1: EnemyBombsZRK1(ActAddr,ActTime); BombZRK2: EnemyBombsZRK2(ActAddr,ActTime); Finish1: EnemyPlaneReturn1(ActAddr,ActTime); Finish2: EnemyPlaneReturn2(ActAddr,ActTime); UkazZRK1: ZRK1Order(ActAddr,ActTime); UkazZRK2: ZRK2Order(ActAddr,ActTime); UkazAIA: AIAOrder(ActAddr,ActTime); Perehvat: AIAJetFight(ActAddr,ActTime); Perehvat1: ZRK1Launch(ActAddr,ActTime); Perehvat2: ZRK2Launch(ActAddr,ActTime); Uhod: AIAJetGoBack(ActAddr,ActTime); SvobZRK1: ZRK1CatchPlane(ActAddr,ActTime); SvobZRK2: ZRK2CatchPlane(ActAddr,ActTime); SvobAIA: AIAJetReturn(ActTime); Gotov: EnemyPlaneKilled(ActAddr,ActTime); end; EnemyCleanUp; LifeTime:=LifeTime+ActTime; WriteLn; until Repeater=RepeatCnt; EnemyDone; WriteLn('Average Enemy Planes Killed: ', TotalKilled/RepeatCnt:1:4); Write('Probability of Reaching Object: '); if NToObj>0 then WriteLn(NBombObj/NToObj:1:4) else WriteLn('0'); WriteLn('Average Air Defense Life Time: ',LifeTime/RepeatCnt:1:0); end.