ai improvements are release branch safe 0.9.25
authornemo
Mon, 14 Jan 2019 12:34:47 -0500
branch0.9.25
changeset 14585 8736f3a0ff7f
parent 14556 5e4df5413e1e
child 14586 e54e41554529
child 14588 e27f1d1c1da9
ai improvements are release branch safe
hedgewars/uAI.pas
hedgewars/uAIActions.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
--- a/hedgewars/uAI.pas	Fri Jan 11 08:45:11 2019 -0500
+++ b/hedgewars/uAI.pas	Mon Jan 14 12:34:47 2019 -0500
@@ -66,7 +66,6 @@
 
 const cBranchStackSize = 12;
 type TStackEntry = record
-                   WastedTicks: Longword;
                    MadeActions: TActions;
                    Hedgehog: TGear;
                    end;
@@ -76,14 +75,13 @@
            States: array[0..Pred(cBranchStackSize)] of TStackEntry;
            end;
 
-function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean;
+function Push(const Actions: TActions; const Me: TGear; Dir: integer): boolean;
 var bRes: boolean;
 begin
     bRes:= (Stack.Count < cBranchStackSize) and (Actions.Count < MAXACTIONS - 5);
     if bRes then
         with Stack.States[Stack.Count] do
             begin
-            WastedTicks:= Ticks;
             MadeActions:= Actions;
             Hedgehog:= Me;
             Hedgehog.Message:= Dir;
@@ -92,12 +90,11 @@
     Push:= bRes
 end;
 
-procedure Pop(var Ticks: Longword; var Actions: TActions; var Me: TGear);
+procedure Pop(var Actions: TActions; var Me: TGear);
 begin
     dec(Stack.Count);
     with Stack.States[Stack.Count] do
         begin
-        Ticks:= WastedTicks;
         Actions:= MadeActions;
         Me:= Hedgehog
         end
@@ -253,15 +250,16 @@
 procedure Walk(Me: PGear; var Actions: TActions);
 const FallPixForBranching = cHHRadius;
 var
-    ticks, maxticks, oldticks, steps, tmp: Longword;
+    maxticks, oldticks, steps, tmp: Longword;
     BaseRate, BestRate, Rate: LongInt;
     GoInfo: TGoInfo;
     CanGo: boolean;
     AltMe: TGear;
     BotLevel: Byte;
     a: TAmmoType;
+    isAfterAttack: boolean;
 begin
-ticks:= 0;
+Actions.ticks:= 0;
 oldticks:= 0; // avoid compiler hint
 Stack.Count:= 0;
 
@@ -272,12 +270,13 @@
 
 BotLevel:= Me^.Hedgehog^.BotLevel;
 
-if (Me^.State and gstAttacked) = 0 then
-    maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel))
+isAfterAttack:= ((Me^.State and gstAttacked) <> 0) and ((GameFlags and gfInfAttack) = 0);
+if isAfterAttack then
+    maxticks:= Max(0, TurnTimeLeft - 500)
 else
-    maxticks:= TurnTimeLeft;
+    maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel));
 
-if (Me^.State and gstAttacked) = 0 then
+if not isAfterAttack then
     TestAmmos(Actions, Me, false);
 
 BestRate:= RatePlace(Me);
@@ -291,12 +290,12 @@
     and (CurrentHedgehog^.Effects[heArtillery] = 0) and (cGravityf <> 0) then
     begin
     tmp:= random(2) + 1;
-    Push(0, Actions, Me^, tmp);
-    Push(0, Actions, Me^, tmp xor 3);
+    Push(Actions, Me^, tmp);
+    Push(Actions, Me^, tmp xor 3);
 
     while (Stack.Count > 0) and (not StopThinking) do
         begin
-        Pop(ticks, Actions, Me^);
+        Pop(Actions, Me^);
 
         AddAction(Actions, Me^.Message, aim_push, 250, 0, 0);
         if (Me^.Message and gmLeft) <> 0 then
@@ -311,10 +310,25 @@
     {$HINTS OFF}
             CanGo:= HHGo(Me, @AltMe, GoInfo);
     {$HINTS ON}
-            oldticks:= ticks;
-            inc(ticks, GoInfo.Ticks);
-            if ticks > maxticks then
+            oldticks:= Actions.ticks;
+            inc(Actions.ticks, GoInfo.Ticks);
+            if (Actions.ticks > maxticks) or (TurnTimeLeft < BestActions.ticks + 5000) then
+            begin
+                if (BotLevel < 5)
+                        and (not isAfterAttack)
+                        and (BestActions.Score > 0) // we have a good move
+                        and (TurnTimeLeft < BestActions.ticks + 5000) // we won't have a lot of time after attack
+                        and (HHHasAmmo(Me^.Hedgehog^, amExtraTime) > 0) // but can use extra time
+                then
+                begin
+                    BestActions.Count:= 0;
+                    AddAction(BestActions, aia_Weapon, Longword(amExtraTime), 80, 0, 0);
+                    AddAction(BestActions, aia_attack, aim_push, 10, 0, 0);
+                    AddAction(BestActions, aia_attack, aim_release, 10, 0, 0);
+                end;
+
                 break;
+            end;
 
             if (BotLevel < 5)
                 and (GoInfo.JumpType = jmpHJump)
@@ -323,7 +337,7 @@
                 begin
                 // check if we could go backwards and maybe ljump over a gap after this hjump
                 addMark(hwRound(Me^.X), hwRound(Me^.Y), markHJumped);
-                if Push(ticks, Actions, AltMe, Me^.Message xor 3) then
+                if Push(Actions, AltMe, Me^.Message xor 3) then
                     begin
                     with Stack.States[Pred(Stack.Count)] do
                         begin
@@ -336,7 +350,7 @@
                         AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
                         end;
                     // but first check walking forward
-                    Push(ticks, Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message)
+                    Push(Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message)
                     end;
                 end;
             if (BotLevel < 3)
@@ -346,7 +360,7 @@
                 begin
                 addMark(hwRound(Me^.X), hwRound(Me^.Y), markLJumped);
                 // at final check where we go after jump walking backward
-                if Push(ticks, Actions, AltMe, Me^.Message xor 3) then
+                if Push(Actions, AltMe, Me^.Message xor 3) then
                     with Stack.States[Pred(Stack.Count)] do
                         begin
                         if (Me^.Message and gmLeft) <> 0 then
@@ -358,12 +372,13 @@
                         end;
 
                 // push current position so we proceed from it after checking jump+forward walk opportunities
-                if CanGo then Push(ticks, Actions, Me^, Me^.Message);
+                if CanGo then Push(Actions, Me^, Me^.Message);
 
                 // first check where we go after jump walking forward
-                if Push(ticks, Actions, AltMe, Me^.Message) then
+                if Push(Actions, AltMe, Me^.Message) then
                     with Stack.States[Pred(Stack.Count)] do
                         AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
+
                 break
                 end;
 
@@ -379,27 +394,22 @@
                 BestActions:= Actions;
                 BestActions.isWalkingToABetterPlace:= true;
                 BestRate:= Rate;
-                Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo
+                isAfterAttack:= true // we have better place, go there and do not use ammo
                 end
             else if Rate < BestRate then
                 break;
 
-            if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then
+            if (not isAfterAttack) and ((steps mod 4) = 0) then
                 begin
                 if (steps > 4) and checkMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere) then
                     break;
                 addMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere);
 
-                TestAmmos(Actions, Me, ticks shr 12 = oldticks shr 12);
-
+                TestAmmos(Actions, Me, Actions.ticks shr 12 = oldticks shr 12);
                 end;
 
             if GoInfo.FallPix >= FallPixForBranching then
-                Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
-
-            if (StartTicks > GameTicks - 1500) and (not StopThinking) then
-                SDL_Delay(1000);
-
+                Push(Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
             end {while};
 
         if BestRate > BaseRate then
@@ -463,8 +473,8 @@
             or (itHedgehog = currHedgehogIndex)
             or BestActions.isWalkingToABetterPlace;
 
-            if (StartTicks > GameTicks - 1500) and (not StopThinking) then
-                SDL_Delay(700);
+        if (StartTicks > GameTicks - 1500) and (not StopThinking) then
+            SDL_Delay(700);
 
         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
             begin
@@ -544,7 +554,7 @@
     exit
     end;
 
-FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot));
+FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0));
 
 SDL_LockMutex(ThreadLock);
 ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me);
@@ -561,7 +571,7 @@
 with CurrentHedgehog^ do
     if (Gear <> nil)
     and ((Gear^.State and gstHHDriven) <> 0)
-    and (TurnTimeLeft < cHedgehogTurnTime - 50) then
+    and ((TurnTimeLeft < cHedgehogTurnTime - 50) or (TurnTimeLeft > cHedgehogTurnTime)) then
         if ((Gear^.State and gstHHThinking) = 0) then
             if (BestActions.Pos >= BestActions.Count)
             and (TurnTimeLeft > cStopThinkTime) then
--- a/hedgewars/uAIActions.pas	Fri Jan 11 08:45:11 2019 -0500
+++ b/hedgewars/uAIActions.pas	Mon Jan 14 12:34:47 2019 -0500
@@ -58,6 +58,7 @@
 
     TActions = record
         Count, Pos: Longword;
+        ticks: Longword;
         actions: array[0..Pred(MAXACTIONS)] of TAction;
         Score: LongInt;
         isWalkingToABetterPlace: boolean;
--- a/hedgewars/uAIAmmoTests.pas	Fri Jan 11 08:45:11 2019 -0500
+++ b/hedgewars/uAIAmmoTests.pas	Mon Jan 14 12:34:47 2019 -0500
@@ -1135,7 +1135,7 @@
     if d < 10 then
         begin
         dx:= 0;
-        dy:= 8;
+        dy:= step;
         ap.Angle:= 2048
         end
     else
@@ -1149,17 +1149,18 @@
 
     if dx >= 0 then cx:= 0.45 else cx:= -0.45;
 
-    for i:= 0 to 512 div step - 2 do
+    for i:= 1 to 512 div step - 2 do
         begin
+        x:= x + dx;
+        y:= y + dy;
+
         valueResult:= valueResult +
             RateShove(Me, trunc(x), trunc(y)
                 , 30, 30, 25
                 , cx, -0.9, trackFall or afSetSkip);
+        end;
 
-        x:= x + dx;
-        y:= y + dy;
-        end;
-    if dx = 0 then
+    if (d < 10) and (dx = 0) then
         begin
         x:= hwFloat2Float(Me^.X);
         y:= hwFloat2Float(Me^.Y);
@@ -1176,8 +1177,10 @@
                     , -cx, -0.9, trackFall or afSetSkip);
             end
         end;
+
     if v > valueResult then
-        begin
+    begin
+        cx:= -cx;
         ap.Angle:= -2048;
         valueResult:= v
         end;
--- a/hedgewars/uAIMisc.pas	Fri Jan 11 08:45:11 2019 -0500
+++ b/hedgewars/uAIMisc.pas	Mon Jan 14 12:34:47 2019 -0500
@@ -229,6 +229,7 @@
             , gtAirBomb
             , gtCluster
             , gtMelonPiece
+            , gtBee
             , gtMolotov: bonuses.activity:= true;
             gtCase:
                 if (Gear^.AIHints and aihDoesntMatter) = 0 then
@@ -246,6 +247,7 @@
                 else if (Gear^.State and gstAttacking) <> 0 then
                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, -50); // mine is on
                 end;
+            gtAirMine: if ((Gear^.State and gstFrozen) = 0) then AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), gear^.Angle+5, -30);
 
             gtExplosives:
                 begin