AI: Don't sacrifice final hog with kami or piano
authorWuzzy <Wuzzy2@mail.ru>
Wed, 07 Oct 2020 23:06:34 +0200
changeset 15762 0a172cfe8840
parent 15761 94f4d0a96143
child 15763 8997e212be4c
AI: Don't sacrifice final hog with kami or piano
hedgewars/uAI.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uGearsUtils.pas
--- a/hedgewars/uAI.pas	Thu Sep 10 09:30:41 2020 +0200
+++ b/hedgewars/uAI.pas	Wed Oct 07 23:06:34 2020 +0200
@@ -109,6 +109,7 @@
 aiLaserSighting:= (cLaserSighting) or (HHHasAmmo(Me^.Hedgehog^, amLaserSight) > 0);
 aiGravity:= cGravity;
 aiGravityf:= cGravityf;
+aiHogsInTeam:= CountHogsInTeam(Me, true);
 hasLowGrav:= HHHasAmmo(Me^.Hedgehog^, amLowGravity) > 0;
 useThisActions:= false;
 Me^.AIHints:= Me^.AIHints and (not aihAmmosChanged);
--- a/hedgewars/uAIAmmoTests.pas	Thu Sep 10 09:30:41 2020 +0200
+++ b/hedgewars/uAIAmmoTests.pas	Wed Oct 07 23:06:34 2020 +0200
@@ -35,6 +35,7 @@
     aiGravity: hwFloat;
     aiGravityf: real;
     aiLaserSighting: boolean;
+    aiHogsInTeam: LongInt;
 
 type TAttackParams = record
         Time, Bounce, AttacksNum: Longword;
@@ -1337,6 +1338,10 @@
     else
         exit(BadTurn);
 
+    // Don't sacrifice last hog
+    if aiHogsInTeam <= 1 then
+        exit(BadTurn);
+
     valueResult:= 0;
     v:= 0;
 
@@ -1972,6 +1977,10 @@
 if (Level > 2) then
     exit(BadTurn);
 
+// Don't sacrifice last hog
+if aiHogsInTeam <= 1 then
+    exit(BadTurn);
+
 ap.Angle:= 0;
 ap.AttackPutX:= Targ.Point.X;
 ap.AttackPutY:= Targ.Point.Y;
--- a/hedgewars/uGearsUtils.pas	Thu Sep 10 09:30:41 2020 +0200
+++ b/hedgewars/uGearsUtils.pas	Wed Oct 07 23:06:34 2020 +0200
@@ -56,6 +56,7 @@
 function  SpawnBoxOfSmth: PGear;
 procedure PlayBoxSpawnTaunt(Gear: PGear);
 procedure ShotgunShot(Gear: PGear);
+function  CountHogsInTeam(HHGear: PGear; countHidden: boolean): LongInt;
 function  CanUseTardis(HHGear: PGear): boolean;
 
 procedure SetAllToActive;
@@ -1322,10 +1323,33 @@
     DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius)
 end;
 
+// Return number of living hogs in HHGear's team
+// * HHGear: hog gear for which to count team hogs
+// * countHidden: if true, also count hidden hogs (e.g. time-travel)
+function CountHogsInTeam(HHGear: PGear; countHidden: boolean): LongInt;
+var i, j, cnt: LongInt;
+    HH: PHedgehog;
+begin
+    if HHGear = nil then
+        exit(0);
+    HH:= HHGear^.Hedgehog;
+    cnt:= 0;
+    for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
+        for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
+            if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
+            and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
+            and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
+                inc(cnt)
+            else if countHidden and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].GearHidden <> nil) then
+                inc(cnt);
+    CountHogsInTeam:= cnt;
+end;
+
+
 // Returns true if the given hog gear can use the tardis
 function CanUseTardis(HHGear: PGear): boolean;
 var usable: boolean;
-    i, j, cnt: LongInt;
+    cnt: LongInt;
     HH: PHedgehog;
 begin
 (*
@@ -1339,13 +1363,7 @@
     if HHGear <> nil then
     if (HHGear = nil) or (HH^.King) or (SuddenDeathActive) then
         usable:= false;
-    cnt:= 0;
-    for j:= 0 to Pred(HH^.Team^.Clan^.TeamsNumber) do
-        for i:= 0 to Pred(HH^.Team^.Clan^.Teams[j]^.HedgehogsNumber) do
-            if (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear <> nil)
-            and ((HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.State and gstDrowning) = 0)
-            and (HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Health > HH^.Team^.Clan^.Teams[j]^.Hedgehogs[i].Gear^.Damage) then
-                inc(cnt);
+    cnt:= CountHogsInTeam(HHGear, false);
     if (cnt < 2) then
         usable:= false;
     CanUseTardis:= usable;