Teach AI to use RC plane (straight line only, no bombs)
authorWuzzy <Wuzzy2@mail.ru>
Mon, 08 Jun 2020 21:13:31 +0200
changeset 15634 be8fe5e0789e
parent 15633 d347785fd61c
child 15635 39a353e8ef3d
Teach AI to use RC plane (straight line only, no bombs)
ChangeLog.txt
hedgewars/uAIAmmoTests.pas
--- a/ChangeLog.txt	Mon Jun 08 20:41:24 2020 +0200
+++ b/ChangeLog.txt	Mon Jun 08 21:13:31 2020 +0200
@@ -14,6 +14,7 @@
  +   - drop mines from a cliff
  +   - use drill strike and piano strike
  +   - use mine strike (0 seconds only)
+ +   - use RC plane (very basic, no bombs)
  * Racer: Resize waypoints in custom-sized drawn maps
  * Mutant: Fix impossible to become mutant after mutant is gone
  * A Classic Fairytale: Mission 1: Fix possibility of getting stuck in “Leap of Faith” section
--- a/hedgewars/uAIAmmoTests.pas	Mon Jun 08 20:41:24 2020 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Mon Jun 08 21:13:31 2020 +0200
@@ -44,6 +44,7 @@
 function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
+function TestRCPlane(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
@@ -102,7 +103,7 @@
             (proc: nil;              flags: 0), // amNapalm
             (proc: @TestDrillRocket; flags: 0), // amDrill
             (proc: nil;              flags: 0), // amBallgun
-            (proc: nil;              flags: 0), // amRCPlane
+            (proc: @TestRCPlane;     flags: 0), // amRCPlane
             (proc: nil;              flags: 0), // amLowGravity
             (proc: nil;              flags: 0), // amExtraDamage
             (proc: nil;              flags: 0), // amInvulnerable
@@ -415,6 +416,83 @@
     TestDrillRocket:= valueResult
 end;
 
+function TestRCPlane(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
+const
+    MIN_RANGE =  200;
+var Vx, Vy, meX, meY, x, y: real;
+    rx, ry, valueResult: LongInt;
+    range, maxRange: integer;
+begin
+// This is a very simple test to let a RC plane fly in a straight line, without dropping any bombs
+// TODO: Teach AI how to steer
+// TODO: Teach AI how to drop bombs
+// TODO: Teach AI how to predict fire behavior
+Flags:= Flags; // avoid compiler hint
+if Level = 5 then
+    exit(BadTurn)
+else if Level = 4 then
+    maxRange:= 2200
+else if Level = 3 then
+    maxRange:= 2900
+else if Level = 2 then
+    maxRange:= 3500
+else
+    maxRange:= 3900;
+TestRCPlane:= BadTurn;
+ap.ExplR:= 0;
+ap.Time:= 0;
+ap.Power:= 1;
+meX:= hwFloat2Float(Me^.X);
+meY:= hwFloat2Float(Me^.Y);
+x:= meX;
+y:= meY;
+range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y);
+if ( range < MIN_RANGE ) or ( range > maxRange) then
+    exit(BadTurn);
+
+Vx:= (Targ.Point.X - x) * 1 / 1024;
+Vy:= (Targ.Point.Y - y) * 1 / 1024;
+ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
+repeat
+    x:= x + vX;
+    y:= y + vY;
+    rx:= trunc(x);
+    ry:= trunc(y);
+    if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 8)) or
+        ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 8)) then
+        begin
+        x:= x + vX * 8;
+        y:= y + vY * 8;
+
+        // Intentionally low rating to discourage use
+        if Level = 1 then
+            valueResult:= RateExplosion(Me, rx, ry, 26, afTrackFall or afErasesLand)
+        else
+            valueResult:= RateExplosion(Me, rx, ry, 26);
+
+        // Check range again in case the plane collided before target
+        range:= Metric(trunc(meX), trunc(meY), rx, ry);
+        if ( range < MIN_RANGE ) or ( range > maxRange) then
+            exit(BadTurn);
+
+        // If impact location is close, above us and wind blows in our direction,
+        // there's a risk of fire flying towards us, so fail in this case.
+        if (Level < 3) and (range <= 600) and (meY >= ry) and
+            (((ap.Angle < 0) and (windSpeed > 0)) or ((ap.Angle > 0) and (windSpeed < 0))) then
+            exit(BadTurn);
+
+        if (valueResult <= 0) then
+            valueResult:= BadTurn;
+        exit(valueResult)
+        end
+until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4)
+    or (x < 0)
+    or (y < 0)
+    or (trunc(x) > LAND_WIDTH)
+    or (trunc(y) > LAND_HEIGHT);
+
+TestRCPlane:= BadTurn
+end;
 
 function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 var Vx, Vy, r: real;