hedgewars/uAIAmmoTests.pas
changeset 15612 39a353e8ef3d
parent 15611 be8fe5e0789e
child 15613 d9c62f196fe0
equal deleted inserted replaced
15611:be8fe5e0789e 15612:39a353e8ef3d
   559 until (rTime > 5050 - Level * 800);
   559 until (rTime > 5050 - Level * 800);
   560 TestSnowball:= valueResult
   560 TestSnowball:= valueResult
   561 end;
   561 end;
   562 
   562 
   563 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   563 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   564 var Vx, Vy, r: real;
   564 const timeLimit = 50;
   565     Score, EX, EY, valueResult: LongInt;
   565 var Vx, Vy, r, meX, meY: real;
   566     TestTime: LongInt;
   566     rTime: LongInt;
   567     targXWrap, x, y, dY, meX, meY: real;
   567     EX, EY: LongInt;
       
   568     valueResult: LongInt;
       
   569     targXWrap, x, y, dX, dY: real;
   568     t: LongInt;
   570     t: LongInt;
       
   571     value, range: LongInt;
   569 begin
   572 begin
   570 Flags:= Flags; // avoid compiler hint
   573 Flags:= Flags; // avoid compiler hint
   571 meX:= hwFloat2Float(Me^.X);
   574 meX:= hwFloat2Float(Me^.X);
   572 meY:= hwFloat2Float(Me^.Y);
   575 meY:= hwFloat2Float(Me^.Y);
   573 valueResult:= BadTurn;
   576 ap.Time:= 0;
   574 TestTime:= 0;
   577 rTime:= 350;
   575 ap.ExplR:= 0;
   578 ap.ExplR:= 0;
   576 if (WorldEdge = weWrap) then
   579 if (WorldEdge = weWrap) then
   577     if (Targ.Point.X < meX) then
   580     if (Targ.Point.X < meX) then
   578          targXWrap:= Targ.Point.X + (RightX-LeftX)
   581          targXWrap:= Targ.Point.X + (RightX-LeftX)
   579     else targXWrap:= Targ.Point.X - (RightX-LeftX);
   582     else targXWrap:= Targ.Point.X - (RightX-LeftX);
       
   583 valueResult:= BadTurn;
   580 repeat
   584 repeat
   581     inc(TestTime, 300);
   585     rTime:= rTime + 300 + Level * 50 + random(300);
   582     if (WorldEdge = weWrap) and (random(2)=0) then
   586     if (WorldEdge = weWrap) and (random(2)=0) then
   583          Vx:= (targXWrap - meX) / TestTime
   587          Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime
   584     else Vx:= (Targ.Point.X - meX) / TestTime;
   588     else
   585     Vy:= cGravityf * (TestTime div 2) - Targ.Point.Y - meY / TestTime;
   589          Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime;
       
   590     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
   586     r:= sqr(Vx) + sqr(Vy);
   591     r:= sqr(Vx) + sqr(Vy);
       
   592 
   587     if not (r > 1) then
   593     if not (r > 1) then
   588         begin
   594         begin
   589         x:= meX;
   595         x:= meX;
   590         y:= meY;
   596         y:= meY;
       
   597         dX:= Vx;
   591         dY:= -Vy;
   598         dY:= -Vy;
   592         t:= TestTime;
   599         t:= rTime;
   593         repeat
   600         repeat
   594             x:= CheckWrap(x);
   601             x:= CheckWrap(x);
   595             x:= x + Vx;
   602             x:= x + dX;
       
   603 
   596             y:= y + dY;
   604             y:= y + dY;
   597             dY:= dY + cGravityf;
   605             dY:= dY + cGravityf;
   598             dec(t)
   606             dec(t)
   599         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
   607         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   600                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
   608                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t < -timeLimit);
       
   609 
   601         EX:= trunc(x);
   610         EX:= trunc(x);
   602         EY:= trunc(y);
   611         EY:= trunc(y);
   603         if t < 50 then
   612 
   604             Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
   613         // Sanity check 1: Make sure we're not too close to impact location
       
   614         range:= Metric(trunc(meX), trunc(meY), EX, EY);
       
   615         if (range < 150) and (Level < 5) then
       
   616             exit(BadTurn);
       
   617 
       
   618         // Sanity check 2: If impact location is close, above us and wind blows
       
   619         // towards us, there's a risk of fire flying towards us, so fail in this case.
       
   620         if (Level < 3) and (range <= 600) and (trunc(meY) >= EX) and
       
   621             (((ap.Angle < 0) and (windSpeed > 0)) or ((ap.Angle > 0) and (windSpeed < 0))) then
       
   622             exit(BadTurn);
       
   623 
       
   624         if t >= -timeLimit then
       
   625             value:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly
   605         else
   626         else
   606             Score:= BadTurn;
   627             value:= BadTurn;
   607 
   628 
   608         if valueResult < Score then
   629         if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
       
   630             value := BadTurn;
       
   631 
       
   632         if (valueResult < value) or ((valueResult = value) and (Level < 3)) then
   609             begin
   633             begin
   610             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   634             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   611             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   635             ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1);
   612             ap.ExplR:= 100;
   636             ap.ExplR:= 100;
   613             ap.ExplX:= EX;
   637             ap.ExplX:= EX;
   614             ap.ExplY:= EY;
   638             ap.ExplY:= EY;
   615             valueResult:= Score
   639             valueResult:= value
   616             end;
   640             end;
   617         end
   641         end
   618 until (TestTime > 5050 - Level * 800);
   642 until rTime > 5050 - Level * 800;
   619 TestMolotov:= valueResult
   643 TestMolotov:= valueResult
   620 end;
   644 end;
   621 
   645 
   622 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   646 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   623 const tDelta = 24;
   647 const tDelta = 24;