Improve TestWhip
authorunc0rr
Thu, 31 May 2012 18:02:30 +0400
changeset 7154 56e329edf4b8
parent 7151 ec15d9e1a7e3
child 7157 04f2155e392c
Improve TestWhip
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
hedgewars/uGears.pas
--- a/hedgewars/uAIAmmoTests.pas	Thu May 31 15:14:39 2012 +0400
+++ b/hedgewars/uAIAmmoTests.pas	Thu May 31 18:02:30 2012 +0400
@@ -659,7 +659,7 @@
 end;
 
 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var val1: LongInt;
+var val1, val2, i, t: LongInt;
     x, y: real;
 begin
 Level:= Level; // avoid compiler hint
@@ -670,24 +670,25 @@
 ap.Angle:= hwSign(Me^.dX);
 x:= hwFloat2Float(Me^.X);
 y:= hwFloat2Float(Me^.Y);
-if (Abs(trunc(x) - Targ.X) < 25)
-    and (Abs(trunc(y) - 50 - Targ.Y) < 50) then
+{
+// this block is for digging with firepunch when blocked close to walls (notice TestColl check)
+if (Abs(trunc(x) - Targ.X) > 25)
+    or (Abs(trunc(y) + 50 - Targ.Y) > 50) then
     begin
-// TODO - find out WTH this works.
     if TestColl(trunc(x), trunc(y) - 16, 6) and 
        (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), 
-                      trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9,  1) = 0) then
+                      trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9,  1) >= 0) then
         val1:= Succ(BadTurn)
     else
         val1:= BadTurn;
     exit(val1);
     end;
-(*
-For some silly reason, having this enabled w/ the AI 
+    }
+// and this is actual try to attack
 val1:= 0;
 for i:= 0 to 4 do
     begin
-    t:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1);
+    t:= RateShove(Me, trunc(x) + 10 * hwSignf(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1);
     if (val1 < 0) or (t < 0) then val1:= BadTurn
     else if t > 0 then val1:= t;
     end;
@@ -695,7 +696,7 @@
 val2:= 0;
 for i:= 0 to 4 do
     begin
-    t:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, -hwSign(Me^.dX)*0.45, -0.9, 1);
+    t:= RateShove(Me, trunc(x) + 10 * hwSignf(Targ.X - x), trunc(y) - 20 * i - 5, 10, 30, 40, -hwSign(Me^.dX)*0.45, -0.9, 1);
     if (val2 < 0) or (t < 0) then val2:= BadTurn
     else if t > 0 then val2:= t;
     end;
@@ -706,35 +707,57 @@
     ap.Angle:= -hwSign(Me^.dX);
     TestFirePunch:= val2
     end
-else TestFirePunch:= BadTurn;*)
+else TestFirePunch:= BadTurn;
 end;
 
+// TODO: TestWhip, TestFirepunch and TestBaseballBat could be called only once at each position 
+// (now they're called for each possible target in each position)
 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var i, valueResult: LongInt;
+var valueResult, v1, v2: LongInt;
     x, y: real;
 begin
 Level:= Level; // avoid compiler hint
 ap.ExplR:= 0;
 ap.Time:= 0;
 ap.Power:= 1;
-ap.Angle:= 0;
 x:= hwFloat2Float(Me^.X);
 y:= hwFloat2Float(Me^.Y);
-if (Abs(trunc(x) - Targ.X) > 25)
-or (Abs(trunc(y) - 50 - Targ.Y) > 50) then
+
+if(abs(Targ.X - x) > 50) or (abs(Targ.Y - y) > 30) then // we're way too far from our target
+    exit(BadTurn);
+    
+// check left direction
+{first RateShove checks fartherest of two whip's AmmoShove attacks 
+to encourage distant attacks (damaged hog is excluded from view of second 
+RateShove call)}
+v1:= RateShove(Me, trunc(x) - 15, trunc(y)
+        , 30, 30, 40
+        , -1, -0.8, 1 or fSetSkip);
+v1:= v1 +
+    RateShove(Me, trunc(x), trunc(y)
+        , 30, 30, 40
+        , -1, -0.8, 1);
+// now try opposite direction
+v2:= RateShove(Me, trunc(x) + 15, trunc(y)
+        , 30, 30, 40
+        , 1, -0.8, 1 or fSetSkip);
+v2:= v2 +
+    RateShove(Me, trunc(x), trunc(y)
+        , 30, 30, 40
+        , 1, -0.8, 1);
+
+if (v2 > v1) 
+    or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
     begin
-    if TestColl(trunc(x), trunc(y) - 16, 6)
-    and (RateShove(Me, trunc(x) + LongWord(10 * hwSign(Me^.dX)), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8,  1) = 0) then
-        valueResult:= Succ(BadTurn)
-    else
-        valueResult:= BadTurn;
-    exit(valueResult);
+    ap.Angle:= 1;
+    valueResult:= v2
+    end
+else 
+    begin
+    ap.Angle:= -1;
+    valueResult:= v1
     end;
-
-valueResult:= 0;
-for i:= 0 to 4 do
-    valueResult:= valueResult + RateShove(Me, trunc(x) + LongWord(10 * hwSignf(Targ.X - x)),
-                                    trunc(y) - LongWord(20 * i) - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1);
+   
 if valueResult <= 0 then
     valueResult:= BadTurn
 else
--- a/hedgewars/uAIMisc.pas	Thu May 31 15:14:39 2012 +0400
+++ b/hedgewars/uAIMisc.pas	Thu May 31 18:02:30 2012 +0400
@@ -23,10 +23,11 @@
 uses SDLh, uConsts, uFloat, uTypes;
 
 const MAXBONUS = 1024;
-
+      fSetSkip = 4;
 type TTarget = record
     Point: TPoint;
     Score: LongInt;
+    skip: boolean;
     end;
 TTargets = record
     Count: Longword;
@@ -100,6 +101,7 @@
                     begin
                     with Targets.ar[Targets.Count], Hedgehogs[i] do
                         begin
+                        skip:= false;
                         Point.X:= hwRound(Gear^.X);
                         Point.Y:= hwRound(Gear^.Y);
                         if Clan <> CurrentTeam^.Clan then
@@ -396,6 +398,9 @@
 rate:= 0;
 for i:= 0 to Pred(Targets.Count) do
     with Targets.ar[i] do
+      if skip then 
+        if (Flags and fSetSkip = 0) then skip:= false else {still skip}
+      else  
         begin
         dmg:= 0;
         if abs(Point.x - x) + abs(Point.y - y) < r then
@@ -405,8 +410,9 @@
             end;
         if dmg > 0 then
             begin
+            if (Flags and fSetSkip <> 0) then skip:= true;
             if (Flags and 1 <> 0) then 
-                fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y-2, dX, dY) * dmgMod);
+                fallDmg:= trunc(TraceShoveFall(Me, Point.x, Point.y - 2, dX, dY) * dmgMod);
             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
                 if Score > 0 then
                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
--- a/hedgewars/uGears.pas	Thu May 31 15:14:39 2012 +0400
+++ b/hedgewars/uGears.pas	Thu May 31 18:02:30 2012 +0400
@@ -779,6 +779,7 @@
             Gear^.Active:= true;
             Gear^.State:= Gear^.State or gstMoving;
 
+            // move the gear upwards a bit to throw it over tiny obstacles at start
             if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
                 begin
                 if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX))