trying to make AI aware of mine/explosive break point. also remove redundant test.
authornemo
Fri, 03 May 2013 21:36:01 -0400
changeset 8952 a6ee1e7310fb
parent 8951 95dd846caf5d
child 8953 d0e5c1002fe1
trying to make AI aware of mine/explosive break point. also remove redundant test.
hedgewars/GSHandlers.inc
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
--- a/hedgewars/GSHandlers.inc	Fri May 03 07:52:57 2013 -0400
+++ b/hedgewars/GSHandlers.inc	Fri May 03 21:36:01 2013 -0400
@@ -1425,13 +1425,13 @@
         doStepFallingGear(Gear);
     if (Gear^.Health = 0) then
         begin
-        if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+        if (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
             inc(Gear^.Damage, hwRound(Gear^.dY * _70))
-        else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
+        else if (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
             inc(Gear^.Damage, hwRound(Gear^.dX * _70))
-        else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
+        else if  (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
             inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
-        else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
+        else if (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
             inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
 
         if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
@@ -1585,7 +1585,7 @@
         begin
         DeleteCI(Gear);
         AllInactive := false;
-        if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+        if (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
             begin
             Gear^.State := Gear^.State or gsttmpFlag;
             inc(Gear^.Damage, hwRound(Gear^.dY * _70));
@@ -1596,13 +1596,13 @@
                     particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
                 end
             end
-        else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
+        else if (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
                 inc(Gear^.Damage, hwRound(Gear^.dX * _70))
 
-        else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
+        else if (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
                 inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
 
-        else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
+        else if (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
                 inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
 
         doStepFallingGear(Gear);
--- a/hedgewars/uAIAmmoTests.pas	Fri May 03 07:52:57 2013 -0400
+++ b/hedgewars/uAIAmmoTests.pas	Fri May 03 21:36:01 2013 -0400
@@ -686,7 +686,7 @@
 if Level > 4 then exit(BadTurn);
 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
 Level:= Level; // avoid compiler hint
-ap.ExplR:= 0;
+ap.ExplR:= 1;
 ap.Time:= 0;
 ap.Power:= 1;
 
@@ -716,14 +716,8 @@
     or (d > 48);
 
 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5 then
-    begin
-    fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00125 * 20, vY * 0.00125 * 20);
-    if fallDmg < 0 then
-        valueResult:= 204800
-    else valueResult:= Max(0, (4 - d div 12) * trunc((7 + fallDmg) * dmgMod) * 1024)
-    end
-else
-    valueResult:= BadTurn;
+     valueResult:= RateShove(Me, Targ.X, Targ.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall)
+else valueResult:= BadTurn;
 TestDesertEagle:= valueResult
 end;
 
@@ -766,15 +760,8 @@
     or (d > 22);
 
 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then
-    begin
-    fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg);
-    if fallDmg < 0 then
-        TestSniperRifle:= BadTurn
-    else
-        TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024)
-    end
-else
-    TestSniperRifle:= BadTurn
+     TestSniperRifle:= RateShove(Me, Targ.X, Targ.Y, 1, trunc(dmg), 20, vX*0.166, vY*0.166, afTrackFall)
+else TestSniperRifle:= BadTurn;
 end;
 
 
--- a/hedgewars/uAIMisc.pas	Fri May 03 07:52:57 2013 -0400
+++ b/hedgewars/uAIMisc.pas	Fri May 03 21:36:01 2013 -0400
@@ -33,6 +33,7 @@
 type TTarget = record
     Point: TPoint;
     Score: LongInt;
+    Density: real;
     skip, matters, dead: boolean;
     Kind: TGearType;
     end;
@@ -66,7 +67,7 @@
 function  TestColl(x, y, r: LongInt): boolean; inline;
 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
-function  TraceShoveFall(x, y, dX, dY: Real): LongInt;
+function  TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt;
 
 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
@@ -144,6 +145,7 @@
             Point.X:= hwRound(iter^.X);
             Point.Y:= hwRound(iter^.Y);
             if (iter^.Kind = gtHedgehog) then
+                begin
                 if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then
                     begin
                     Score:= iter^.Damage - iter^.Health;
@@ -153,9 +155,19 @@
                     begin
                     Score:= iter^.Health - iter^.Damage;
                     inc(e)
-                    end
-            else if iter^.Kind = gtExplosives then Score:= iter^.Health - iter^.Damage
-            else if iter^.Kind = gtMine then Score:= max(0,35-iter^.Damage)
+                    end;
+                Density:= 1;
+                end
+            else if iter^.Kind = gtExplosives then
+                begin
+                Score:= iter^.Health - iter^.Damage;
+                Density:= 2
+                end
+            else if iter^.Kind = gtMine then 
+                begin
+                Score:= max(0,35-iter^.Damage);
+                Density:= 1/3
+                end
             end;
         inc(Targets.Count)
         end;
@@ -351,38 +363,60 @@
 
 
 
-function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord): LongInt;
+function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Kind: TGearType): LongInt;
 var skipLandCheck: boolean;
     rCorner: real;
-    dmg: LongInt;
+    dmg, radius: LongInt;
 begin
     skipLandCheck:= true;
     if x - eX < 0 then dX:= -dX;
     if y - eY < 0 then dY:= -dY;
     // ok. attempt approximate search for an unbroken trajectory into water.  if it continues far enough, assume out of map
+    if Kind = gtHedgehog then 
+        radius:= cHHRadius
+    else if Kind = gtExplosives then
+        radius:= 16
+    else if Kind = gtMine then
+        radius:= 2;
     rCorner:= r * 0.75;
     while true do
-    begin
+        begin
         x:= x + dX;
         y:= y + dY;
         dY:= dY + cGravityf;
         skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
-        if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
-        begin
-            if 0.4 < dY then
+        if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), radius) then
             begin
+            if (Kind = gtHedgehog) and (0.4 < dY) then
+                begin
                 dmg := 1 + trunc((abs(dY) - 0.4) * 70);
-                if dmg >= 1 then
-                    exit(dmg);
-            end;
+                if dmg >= 1 then exit(dmg)
+                end
+// so. the problem w/ explosives is it only uses dX or dY depending on impact, and we don't know which we hit.  Maybe we didn't even hit, given TestColl check corners.
+            else 
+                begin
+                if ((dY > 0.2) and (Land[trunc(y)+radius, trunc(x)] > lfAllObjMask)) or 
+                   ((dY < -0.2) and (Land[trunc(y)-radius, trunc(x)] > lfAllObjMask)) then
+                    begin
+                    dmg := 1 + trunc(abs(dY) * 70);
+                    if dmg >= 1 then exit(dmg)
+                    end
+// so we don't know at present if a barrel is already rolling.  Would need to add that to target info I guess
+                else if ((Kind = gtMine) or (abs(dX) > 0.15) or ((abs(dY) > 0.15) and  (abs(dX) > 0.02))) and
+                        (((dX > 0.2) and (Land[trunc(y), trunc(x)+radius] > lfAllObjMask)) or 
+                         ((dX < -0.2) and (Land[trunc(y), trunc(x)-radius] > lfAllObjMask))) then
+                    begin
+                    dmg := 1 + trunc(abs(dX) * 70);
+                    if dmg >= 1 then exit(dmg)
+                    end
+                end;
             exit(0)
-        end;
-        if (y > cWaterLine) or (x > 4096) or (x < 0) then
-            exit(-1);
-    end;
+            end;
+        if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1)
+        end
 end;
 
-function TraceShoveFall(x, y, dX, dY: Real): LongInt;
+function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt;
 var dmg: LongInt;
 begin
 //v:= random($FFFFFFFF);
@@ -467,12 +501,12 @@
                 pY:= Point.y;
                 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
                     begin
-                    dX:= 0.005 * dmg + 0.01;
+                    dX:= 0.005 * dmg + 0.01 * Density;
                     dY:= dX;
                     if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
                        (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
-                         fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
-                    else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod)
+                         fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod)
+                    else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod)
                     end;
                 if Kind = gtHedgehog then
                     begin
@@ -546,7 +580,7 @@
             pY:= Point.y;
             if (Flags and afSetSkip <> 0) then skip:= true;
             if (Flags and afTrackFall <> 0) and (Score > 0) then
-                fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY) * dmgMod);
+                fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY, Kind) * dmgMod);
             if Kind = gtHedgehog then
                 begin
                 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
@@ -634,14 +668,14 @@
                 begin
                 pX:= Point.x;
                 pY:= Point.y;
-                dX:= gdX * dmg;
-                dY:= gdY * dmg;
+                dX:= gdX * dmg * Density;
+                dY:= gdY * dmg * Density;
                 if dX < 0 then dX:= dX - 0.01
                 else dX:= dX + 0.01;
                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
-                     fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
-                else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod);
+                     fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod)
+                else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod);
                 if Kind = gtHedgehog then
                     begin
                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI