hedgewars/uAIAmmoTests.pas
changeset 543 465e2ec8f05f
parent 534 92fb2b0d5117
child 554 4f83b3de17c7
equal deleted inserted replaced
542:ec26095f1bed 543:465e2ec8f05f
    17  *)
    17  *)
    18 
    18 
    19 unit uAIAmmoTests;
    19 unit uAIAmmoTests;
    20 interface
    20 interface
    21 uses SDLh, uGears, uConsts, uFloat;
    21 uses SDLh, uGears, uConsts, uFloat;
    22 
    22 const amtest_OnTurn = $00000001;
    23 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    23 
    24 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    24 type TAttackParams = record
    25 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    25                      Time: Longword;
    26 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    26                      Angle, Power: LongInt;
    27 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    27                      ExplX, ExplY, ExplR: LongInt;
    28 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    28                      AttackPutX, AttackPutY: LongInt;
    29 
    29                      end;
    30 type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    30 
    31 const AmmoTests: array[TAmmoType] of TAmmoTestProc =
    31 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    32 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    33 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    34 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    35 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    36 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    37 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    38 
       
    39 type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
    40      TAmmoTest = record
       
    41                  proc: TAmmoTestProc;
       
    42                  flags: Longword;
       
    43                  end;
       
    44 
       
    45 const AmmoTests: array[TAmmoType] of TAmmoTest =
    32                  (
    46                  (
    33 {amGrenade}       @TestGrenade,
    47                   (proc: @TestGrenade;     flags: 0), // amGrenade
    34 {amClusterBomb}   nil,
    48                   (proc: nil;              flags: 0), // amClusterBomb
    35 {amBazooka}       @TestBazooka,
    49                   (proc: @TestBazooka;     flags: 0), // amBazooka
    36 {amUFO}           nil,
    50                   (proc: nil;              flags: 0), // amUFO
    37 {amShotgun}       @TestShotgun,
    51                   (proc: @TestShotgun;     flags: 0), // amShotgun
    38 {amPickHammer}    nil,
    52                   (proc: nil;              flags: 0), // amPickHammer
    39 {amSkip}          nil,
    53                   (proc: nil;              flags: 0), // amSkip
    40 {amRope}          nil,
    54                   (proc: nil;              flags: 0), // amRope
    41 {amMine}          nil,
    55                   (proc: nil;              flags: 0), // amMine
    42 {amDEagle}        @TestDesertEagle,
    56                   (proc: @TestDesertEagle; flags: 0), // amDEagle
    43 {amDynamite}      nil,
    57                   (proc: nil;              flags: 0), // amDynamite
    44 {amFirePunch}     @TestFirePunch,
    58                   (proc: @TestFirePunch;   flags: 0), // amFirePunch
    45 {amBaseballBat}   @TestBaseballBat,
    59                   (proc: @TestBaseballBat; flags: 0), // amBaseballBat
    46 {amParachute}     nil,
    60                   (proc: nil;              flags: 0), // amParachute
    47 {amAirAttack}     nil,
    61                   (proc: @TestAirAttack;   flags: amtest_OnTurn), // amAirAttack
    48 {amMineStrike}    nil,
    62                   (proc: nil;              flags: 0), // amMineStrike
    49 {amBlowTorch}     nil,
    63                   (proc: nil;              flags: 0), // amBlowTorch
    50 {amGirder}        nil,
    64                   (proc: nil;              flags: 0), // amGirder
    51 {amTeleport}      nil,
    65                   (proc: nil;              flags: amtest_OnTurn), // amTeleport
    52 {amSwitch}        nil
    66                   (proc: nil;              flags: 0)  // amSwitch
    53                   );
    67                   );
    54 
    68 
    55 const BadTurn = Low(LongInt) div 4;
    69 const BadTurn = Low(LongInt) div 4;
    56 
       
    57 
    70 
    58 implementation
    71 implementation
    59 uses uMisc, uAIMisc, uLand;
    72 uses uMisc, uAIMisc, uLand;
    60 
    73 
    61 function Metric(x1, y1, x2, y2: LongInt): LongInt;
    74 function Metric(x1, y1, x2, y2: LongInt): LongInt;
    62 begin
    75 begin
    63 Metric:= abs(x1 - x2) + abs(y1 - y2)
    76 Metric:= abs(x1 - x2) + abs(y1 - y2)
    64 end;
    77 end;
    65 
    78 
    66 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
    79 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    67 var Vx, Vy, r: hwFloat;
    80 var Vx, Vy, r: hwFloat;
    68     rTime: LongInt;
    81     rTime: LongInt;
    69     Score, EX, EY: LongInt;
    82     Score, EX, EY: LongInt;
    70     Result: LongInt;
    83     Result: LongInt;
    71 
    84 
    92     if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
   105     if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
    93     CheckTrace:= Result
   106     CheckTrace:= Result
    94     end;
   107     end;
    95 
   108 
    96 begin
   109 begin
    97 Time:= 0;
   110 ap.Time:= 0;
    98 rTime:= 350;
   111 rTime:= 350;
    99 ExplR:= 0;
   112 ap.ExplR:= 0;
   100 Result:= BadTurn;
   113 Result:= BadTurn;
   101 repeat
   114 repeat
   102   rTime:= rTime + 300 + Level * 50 + random(300);
   115   rTime:= rTime + 300 + Level * 50 + random(300);
   103   Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(rTime);
   116   Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(rTime);
   104   Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
   117   Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
   106   if not (r > _1) then
   119   if not (r > _1) then
   107      begin
   120      begin
   108      Score:= CheckTrace;
   121      Score:= CheckTrace;
   109      if Result <= Score then
   122      if Result <= Score then
   110         begin
   123         begin
   111         Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   124         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   112         Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
   125         ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
   113         ExplR:= 100;
   126         ap.ExplR:= 100;
   114         ExplX:= EX;
   127         ap.ExplX:= EX;
   115         ExplY:= EY;
   128         ap.ExplY:= EY;
   116         Result:= Score
   129         Result:= Score
   117         end;
   130         end;
   118      end
   131      end
   119 until (rTime > 4250);
   132 until (rTime > 4250);
   120 TestBazooka:= Result
   133 TestBazooka:= Result
   121 end;
   134 end;
   122 
   135 
   123 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
   136 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   124 const tDelta = 24;
   137 const tDelta = 24;
   125 var Vx, Vy, r: hwFloat;
   138 var Vx, Vy, r: hwFloat;
   126     Score, EX, EY, Result: LongInt;
   139     Score, EX, EY, Result: LongInt;
   127     TestTime: Longword;
   140     TestTime: Longword;
   128 
   141 
   147     end;
   160     end;
   148 
   161 
   149 begin
   162 begin
   150 Result:= BadTurn;
   163 Result:= BadTurn;
   151 TestTime:= 0;
   164 TestTime:= 0;
   152 ExplR:= 0;
   165 ap.ExplR:= 0;
   153 repeat
   166 repeat
   154   inc(TestTime, 1000);
   167   inc(TestTime, 1000);
   155   Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
   168   Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
   156   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   169   Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   157   r:= Distance(Vx, Vy);
   170   r:= Distance(Vx, Vy);
   158   if not (r > _1) then
   171   if not (r > _1) then
   159      begin
   172      begin
   160      Score:= CheckTrace;
   173      Score:= CheckTrace;
   161      if Result < Score then
   174      if Result < Score then
   162         begin
   175         begin
   163         Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   176         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   164         Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
   177         ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
   165         Time:= TestTime;
   178         ap.Time:= TestTime;
   166         ExplR:= 100;
   179         ap.ExplR:= 100;
   167         ExplX:= EX;
   180         ap.ExplX:= EX;
   168         ExplY:= EY;
   181         ap.ExplY:= EY;
   169         Result:= Score
   182         Result:= Score
   170         end;
   183         end;
   171      end
   184      end
   172 until (TestTime = 4000);
   185 until (TestTime = 4000);
   173 TestGrenade:= Result
   186 TestGrenade:= Result
   174 end;
   187 end;
   175 
   188 
   176 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
   189 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   177 var Vx, Vy, x, y: hwFloat;
   190 var Vx, Vy, x, y: hwFloat;
   178     rx, ry, Result: LongInt;
   191     rx, ry, Result: LongInt;
   179 begin
   192 begin
   180 ExplR:= 0;
   193 ap.ExplR:= 0;
   181 Time:= 0;
   194 ap.Time:= 0;
   182 Power:= 1;
   195 ap.Power:= 1;
   183 if Metric(hwRound(Me^.X), hwRound(Me^.Y), Targ.X, Targ.Y) < 80 then
   196 if Metric(hwRound(Me^.X), hwRound(Me^.Y), Targ.X, Targ.Y) < 80 then
   184    exit(BadTurn);
   197    exit(BadTurn);
   185 Vx:= (int2hwFloat(Targ.X) - Me^.X) * _1div1024;
   198 Vx:= (int2hwFloat(Targ.X) - Me^.X) * _1div1024;
   186 Vy:= (int2hwFloat(Targ.Y) - Me^.Y) * _1div1024;
   199 Vy:= (int2hwFloat(Targ.Y) - Me^.Y) * _1div1024;
   187 x:= Me^.X;
   200 x:= Me^.X;
   188 y:= Me^.Y;
   201 y:= Me^.Y;
   189 Angle:= DxDy2AttackAngle(Vx, -Vy);
   202 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   190 repeat
   203 repeat
   191   x:= x + vX;
   204   x:= x + vX;
   192   y:= y + vY;
   205   y:= y + vY;
   193   rx:= hwRound(x);
   206   rx:= hwRound(x);
   194   ry:= hwRound(y);
   207   ry:= hwRound(y);
   203      end
   216      end
   204 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x < _0) or (y < _0) or (x > _2048) or (y > _1024);
   217 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x < _0) or (y < _0) or (x > _2048) or (y > _1024);
   205 TestShotgun:= BadTurn
   218 TestShotgun:= BadTurn
   206 end;
   219 end;
   207 
   220 
   208 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
   221 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   209 var Vx, Vy, x, y, t: hwFloat;
   222 var Vx, Vy, x, y, t: hwFloat;
   210     d: Longword;
   223     d: Longword;
   211     Result: LongInt;
   224     Result: LongInt;
   212 begin
   225 begin
   213 ExplR:= 0;
   226 ap.ExplR:= 0;
   214 Time:= 0;
   227 ap.Time:= 0;
   215 Power:= 1;
   228 ap.Power:= 1;
   216 if Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 80 then
   229 if Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 80 then
   217    exit(BadTurn);
   230    exit(BadTurn);
   218 t:= _0_5 / Distance(int2hwFloat(Targ.X) - Me^.X, int2hwFloat(Targ.Y) - Me^.Y);
   231 t:= _0_5 / Distance(int2hwFloat(Targ.X) - Me^.X, int2hwFloat(Targ.Y) - Me^.Y);
   219 Vx:= (int2hwFloat(Targ.X) - Me^.X) * t;
   232 Vx:= (int2hwFloat(Targ.X) - Me^.X) * t;
   220 Vy:= (int2hwFloat(Targ.Y) - Me^.Y) * t;
   233 Vy:= (int2hwFloat(Targ.Y) - Me^.Y) * t;
   221 x:= Me^.X;
   234 x:= Me^.X;
   222 y:= Me^.Y;
   235 y:= Me^.Y;
   223 Angle:= DxDy2AttackAngle(Vx, -Vy);
   236 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   224 d:= 0;
   237 d:= 0;
   225 repeat
   238 repeat
   226   x:= x + vX;
   239   x:= x + vX;
   227   y:= y + vY;
   240   y:= y + vY;
   228   if ((hwRound(x) and $FFFFF800) = 0)and((hwRound(y) and $FFFFFC00) = 0)
   241   if ((hwRound(x) and $FFFFF800) = 0)and((hwRound(y) and $FFFFFC00) = 0)
   229      and (Land[hwRound(y), hwRound(x)] <> 0) then inc(d);
   242      and (Land[hwRound(y), hwRound(x)] <> 0) then inc(d);
   230 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x < _0) or (y < _0) or (x > _2048) or (y > _1024) or (d > 200);
   243 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4) or (x < _0) or (y < _0) or (x > _2048) or (y > _1024) or (d > 200);
   231 if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then Result:= max(0, (4 - d div 50) * 7 * 1024)
   244 if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then Result:= max(0, (4 - d div 50) * 7 * 1024)
   232                                                            else Result:= Low(LongInt);
   245                                                            else Result:= BadTurn;
   233 TestDesertEagle:= Result
   246 TestDesertEagle:= Result
   234 end;
   247 end;
   235 
   248 
   236 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
   249 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   237 var Result: LongInt;
   250 var Result: LongInt;
   238 begin
   251 begin
   239 ExplR:= 0;
   252 ap.ExplR:= 0;
   240 if (Level > 2) and not (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 25) then
   253 if (Level > 2) or (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 25) then
   241    exit(BadTurn);
   254    exit(BadTurn);
   242 
   255 
   243 Time:= 0;
   256 ap.Time:= 0;
   244 Power:= 1;
   257 ap.Power:= 1;
   245 if (Targ.X) - hwRound(Me^.X) >= 0 then Angle:=   cMaxAngle div 4
   258 if (Targ.X) - hwRound(Me^.X) >= 0 then ap.Angle:=   cMaxAngle div 4
   246                                   else Angle:= - cMaxAngle div 4;
   259                                   else ap.Angle:= - cMaxAngle div 4;
   247 Result:= RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), hwRound(Me^.Y), 15, 30);
   260 Result:= RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X), hwRound(Me^.Y), 15, 30);
   248 if Result <= 0 then Result:= BadTurn else inc(Result);
   261 if Result <= 0 then Result:= BadTurn else inc(Result);
   249 TestBaseballBat:= Result
   262 TestBaseballBat:= Result
   250 end;
   263 end;
   251 
   264 
   252 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var Time: Longword; var Angle, Power: LongInt; var ExplX, ExplY, ExplR: LongInt): LongInt;
   265 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   253 var i, Result: LongInt;
   266 var i, Result: LongInt;
   254 begin
   267 begin
   255 ExplR:= 0;
   268 ap.ExplR:= 0;
   256 Time:= 0;
   269 ap.Time:= 0;
   257 Power:= 1;
   270 ap.Power:= 1;
   258 Angle:= 0;
   271 ap.Angle:= 0;
   259 if (Abs(hwRound(Me^.X) - Targ.X) > 25) or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then
   272 if (Abs(hwRound(Me^.X) - Targ.X) > 25) or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then
   260    exit(BadTurn);
   273    exit(BadTurn);
   261 
   274 
   262 Result:= 0;
   275 Result:= 0;
   263 for i:= 0 to 4 do
   276 for i:= 0 to 4 do
   265                                     hwRound(Me^.Y) - 20 * i - 5, 10, 30);
   278                                     hwRound(Me^.Y) - 20 * i - 5, 10, 30);
   266 if Result <= 0 then Result:= BadTurn else inc(Result);
   279 if Result <= 0 then Result:= BadTurn else inc(Result);
   267 TestFirePunch:= Result
   280 TestFirePunch:= Result
   268 end;
   281 end;
   269 
   282 
       
   283 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
       
   284 var X, Y, dY: hwFloat;
       
   285     b: array[0..9] of boolean;
       
   286     dmg: array[0..9] of LongInt;
       
   287     fexit: boolean;
       
   288     i, t, Result: LongInt;
       
   289 begin
       
   290 ap.ExplR:= 0;
       
   291 ap.Time:= 0;
       
   292 ap.AttackPutX:= Targ.X;
       
   293 ap.AttackPutY:= Targ.Y;
       
   294 
       
   295 X:= int2hwFloat(Targ.X - 135);
       
   296 X:= X - cBombsSpeed * hwSqrt(int2hwFloat((Targ.Y + 128) * 2) / cGravity);
       
   297 Y:= -_128;
       
   298 dY:= _0;
       
   299 
       
   300 for i:= 0 to 9 do
       
   301     begin
       
   302     b[i]:= true;
       
   303     dmg[i]:= 0
       
   304     end;
       
   305 Result:= 0;
       
   306 
       
   307 repeat
       
   308   X:= X + cBombsSpeed;
       
   309   Y:= Y + dY;
       
   310   dY:= dY + cGravity;
       
   311   fexit:= true;
       
   312 
       
   313   for i:= 0 to 9 do
       
   314     if b[i] then
       
   315        begin
       
   316        fexit:= false;
       
   317        if TestColl(hwRound(X) + i * 30, hwRound(Y), 4) then
       
   318           begin
       
   319           b[i]:= false;
       
   320           dmg[i]:= RateExplosion(Me, hwRound(X) + i * 30, hwRound(Y), 58)
       
   321           // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets)
       
   322           end
       
   323        end;
       
   324 until fexit or (Y > _1024);
       
   325 
       
   326 for i:= 0 to 5 do inc(Result, dmg[i]);
       
   327 t:= Result;
       
   328 ap.AttackPutX:= Targ.X - 60;
       
   329 
       
   330 for i:= 0 to 3 do
       
   331     begin
       
   332     dec(t, dmg[i]);
       
   333     inc(t, dmg[i + 6]);
       
   334     if t > Result then
       
   335        begin
       
   336        Result:= t;
       
   337        ap.AttackPutX:= Targ.X - 30 + i * 30
       
   338        end
       
   339     end;
       
   340 
       
   341 if Result <= 0 then Result:= BadTurn;
       
   342 TestAirAttack:= Result
       
   343 end;
       
   344 
   270 end.
   345 end.