Teach AI how to use MineStrike (0 secs only)
authorWuzzy <Wuzzy2@mail.ru>
Sun, 07 Jun 2020 00:44:13 +0200
changeset 15604 22d0a3d6e2be
parent 15603 ac44dae6425e
child 15605 969bc30928da
Teach AI how to use MineStrike (0 secs only)
ChangeLog.txt
hedgewars/uAIAmmoTests.pas
--- a/ChangeLog.txt	Sat Jun 06 23:40:29 2020 +0200
+++ b/ChangeLog.txt	Sun Jun 07 00:44:13 2020 +0200
@@ -10,8 +10,10 @@
  + Themes: Add fade-in and fade-out effects
  + Themes: Make Sudden Death flakes in Underwater theme rise
  + New taunt chat commands: /bubble, /happy
- + Teach computer players how to drop mines
- + Teach computer players how to use drill strike
+ + Teach computer players how to ...
+ +   - drop mines from a cliff
+ +   - use drill strike
+ +   - use mine strike (0 seconds only)
  * 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	Sat Jun 06 23:40:29 2020 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Sun Jun 07 00:44:13 2020 +0200
@@ -54,6 +54,7 @@
 function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestDrillStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
+function TestMineStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
@@ -85,7 +86,7 @@
             (proc: @TestBaseballBat; flags: amtest_NoTarget), // amBaseballBat
             (proc: nil;              flags: 0), // amParachute
             (proc: @TestAirAttack;   flags: amtest_Rare), // amAirAttack
-            (proc: nil;              flags: 0), // amMineStrike
+            (proc: @TestMineStrike;  flags: amtest_Rare), // amMineStrike
             (proc: nil;              flags: 0), // amBlowTorch
             (proc: nil;              flags: 0), // amGirder
             (proc: nil;              flags: 0), // amTeleport
@@ -1444,6 +1445,85 @@
 TestDrillStrike:= valueResult;
 end;
 
+function TestMineStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
+const cShift = 4;
+var minesSpeed, X, Y, dY: real;
+    b: array[0..9] of boolean;
+    dmg: array[0..9] of LongInt;
+    fexit: boolean;
+    i, t, valueResult: LongInt;
+begin
+Flags:= Flags; // avoid compiler hint
+ap.ExplR:= 0;
+ap.Time:= 0;
+
+// AI currently only supports cMinesTime = 0 because it's the most
+// predictable.
+// Other cMinesTime values are risky because of bouncy mines;
+// so they are unsupported.
+// TODO: Implement mine strike for other values of MineTime
+// TODO: Teach AI to avoid hitting their own with mines
+if (Level > 3) or (cGravityf = 0) or (cMinesTime <> 0) then
+    exit(BadTurn);
+
+ap.Angle:= 0;
+ap.AttackPutX:= Targ.Point.X;
+ap.AttackPutY:= Targ.Point.Y;
+
+minesSpeed:= hwFloat2Float(cBombsSpeed);
+X:= Targ.Point.X - 135 - cShift; // hh center - cShift
+X:= X - minesSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
+Y:= -128;
+dY:= 0;
+
+for i:= 0 to 9 do
+    begin
+    b[i]:= true;
+    dmg[i]:= 0
+    end;
+valueResult:= 0;
+
+repeat
+    X:= X + minesSpeed;
+    Y:= Y + dY;
+    dY:= dY + cGravityf;
+    fexit:= true;
+
+    for i:= 0 to 9 do
+        if b[i] then
+            begin
+            fexit:= false;
+            if TestColl(trunc(X) + LongWord(i * 30), trunc(Y), 4) then
+                begin
+                b[i]:= false;
+                dmg[i]:= RateExplosion(Me, trunc(X) + LongWord(i * 30), trunc(Y), 96)
+                end
+            end;
+until fexit or (Y > cWaterLine);
+
+for i:= 0 to 5 do
+    if dmg[i] <> BadTurn then
+        inc(valueResult, dmg[i]);
+t:= valueResult;
+ap.AttackPutX:= Targ.Point.X - 60;
+
+for i:= 0 to 3 do
+    if dmg[i] <> BadTurn then
+        begin
+        dec(t, dmg[i]);
+        inc(t, dmg[i + 6]);
+        if t > valueResult then
+            begin
+            valueResult:= t;
+            ap.AttackPutX:= Targ.Point.X - 30 - cShift + i * 30
+            end
+        end;
+
+if valueResult <= 0 then
+    valueResult:= BadTurn;
+TestMineStrike:= valueResult;
+end;
+
 function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
 var
     i, failNum: longword;