hedgewars/uAI.pas
changeset 6580 6155187bf599
parent 6462 0758fbec9b9f
child 6700 e04da46ee43c
--- a/hedgewars/uAI.pas	Mon Jan 16 10:22:21 2012 +0100
+++ b/hedgewars/uAI.pas	Tue Jan 17 09:01:31 2012 -0500
@@ -30,8 +30,8 @@
 
 implementation
 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions,
-     uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
-     uVariables, uCommands, uUtils, uDebug;
+    uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
+    uVariables, uCommands, uUtils, uDebug;
 
 var BestActions: TActions;
     CanUseAmmo: array [TAmmoType] of boolean;
@@ -47,18 +47,18 @@
 begin
 AddFileLog('FreeActionsList called');
 if hasThread <> 0 then
-   begin
-   AddFileLog('Waiting AI thread to finish');
-   StopThinking:= true;
-   repeat
-     SDL_Delay(10)
-   until hasThread = 0
-   end;
+    begin
+    AddFileLog('Waiting AI thread to finish');
+    StopThinking:= true;
+    repeat
+        SDL_Delay(10)
+    until hasThread = 0
+    end;
 
 with CurrentHedgehog^ do
-     if Gear <> nil then
+    if Gear <> nil then
         if BotLevel <> 0 then
-           StopMessages(Gear^.Message);
+            StopMessages(Gear^.Message);
 
 BestActions.Count:= 0;
 BestActions.Pos:= 0
@@ -117,66 +117,71 @@
 
 for i:= 0 to Pred(Targets.Count) do
     if (Targets.ar[i].Score >= 0) and (not StopThinking) then
-       begin
-       with CurrentHedgehog^ do
+        begin
+        with CurrentHedgehog^ do
             a:= CurAmmoType;
-       aa:= a;
+        aa:= a;
 {$IFDEF USE_SDLTHREADS}
-       SDL_delay(0);    //ThreadSwitch was only a hint
+        SDL_delay(0);    //ThreadSwitch was only a hint
 {$ELSE}
-       ThreadSwitch();
+        ThreadSwitch();
 {$ENDIF}       
-       repeat
+        repeat
         if (CanUseAmmo[a]) and
-           ((not isMoved) or ((AmmoTests[a].flags and amtest_OnTurn) = 0)) then
-           begin
+            ((not isMoved) or ((AmmoTests[a].flags and amtest_OnTurn) = 0)) then
+            begin
 {$HINTS OFF}
-           Score:= AmmoTests[a].proc(Me, Targets.ar[i].Point, BotLevel, ap);
+            Score:= AmmoTests[a].proc(Me, Targets.ar[i].Point, BotLevel, ap);
 {$HINTS ON}
-           if Actions.Score + Score > BestActions.Score then
-            if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel) * 2048) then
-              begin
-              BestActions:= Actions;
-              inc(BestActions.Score, Score);
-              BestActions.isWalkingToABetterPlace:= false;
+            if Actions.Score + Score > BestActions.Score then
+                if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel) * 2048) then
+                    begin
+                    BestActions:= Actions;
+                    inc(BestActions.Score, Score);
+                    BestActions.isWalkingToABetterPlace:= false;
 
-              if (ap.Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
-              else if (ap.Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
+                if (ap.Angle > 0) then
+                    AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
+            else if (ap.Angle < 0) then
+                AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
 
-              AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
-              if (ap.Time <> 0) then AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
-              if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
-                 begin
-                 ap.Angle:= LongInt(Me^.Angle) - Abs(ap.Angle);
-                 if ap.Angle > 0 then
-                    begin
-                    AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
-                    AddAction(BestActions, aia_Up, aim_release, ap.Angle, 0, 0)
-                    end else if ap.Angle < 0 then
+                AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
+                
+                if (ap.Time <> 0) then
+                    AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
+                if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
                     begin
-                    AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
-                    AddAction(BestActions, aia_Down, aim_release, -ap.Angle, 0, 0)
-                    end
-                 end;
-              if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
-                 begin
-                 AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
-                 end;
-              if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
-                 begin
-                 AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
-                 AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
-                 end;
-              if ap.ExplR > 0 then
-                 AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
-              end
-           end;
-        if a = High(TAmmoType) then a:= Low(TAmmoType)
-                               else inc(a)
-       until (a = aa) or
-             (CurrentHedgehog^.MultiShootAttacks > 0) or // shooting same weapon
-             StopThinking
-       end
+                    ap.Angle:= LongInt(Me^.Angle) - Abs(ap.Angle);
+                    if ap.Angle > 0 then
+                        begin
+                        AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
+                        AddAction(BestActions, aia_Up, aim_release, ap.Angle, 0, 0)
+                        end
+                    else if ap.Angle < 0 then
+                        begin
+                        AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
+                        AddAction(BestActions, aia_Down, aim_release, -ap.Angle, 0, 0)
+                        end
+                    end;
+                if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
+                    begin
+                    AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
+                    end;
+                if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
+                    begin
+                    AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
+                    AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
+                    end;
+                if ap.ExplR > 0 then
+                    AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
+                end
+            end;
+        if a = High(TAmmoType) then
+            a:= Low(TAmmoType)
+        else inc(a)
+        until (a = aa) or (CurrentHedgehog^.MultiShootAttacks > 0) or // shooting same weapon
+        StopThinking
+        end
 end;
 
 procedure Walk(Me: PGear; var Actions: TActions);
@@ -202,10 +207,14 @@
 Push(0, Actions, Me^, tmp);
 Push(0, Actions, Me^, tmp xor 3);
 
-if (Me^.State and gstAttacked) = 0 then maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel))
-                                   else maxticks:= TurnTimeLeft;
+if (Me^.State and gstAttacked) = 0 then
+    maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel))
+else
+    maxticks:= TurnTimeLeft;
 
-if (Me^.State and gstAttacked) = 0 then TestAmmos(Actions, Me, false);
+if (Me^.State and gstAttacked) = 0 then
+    TestAmmos(Actions, Me, false);
+    
 BestRate:= RatePlace(Me);
 BaseRate:= Max(BestRate, 0);
 
@@ -217,54 +226,67 @@
     Pop(ticks, Actions, Me^);
 
     AddAction(Actions, Me^.Message, aim_push, 250, 0, 0);
-    if (Me^.Message and gmLeft) <> 0 then AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
-                                      else AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
+    if (Me^.Message and gmLeft) <> 0 then
+        AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
+    else
+        AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
+    
     steps:= 0;
 
     while (not StopThinking) do
-       begin
+        begin
 {$HINTS OFF}
-       CanGo:= HHGo(Me, @AltMe, GoInfo);
+        CanGo:= HHGo(Me, @AltMe, GoInfo);
 {$HINTS ON}
-       inc(ticks, GoInfo.Ticks);
-       if ticks > maxticks then break;
+        inc(ticks, GoInfo.Ticks);
+        if ticks > maxticks then
+            break;
 
-       if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
-          if Push(ticks, Actions, AltMe, Me^.Message) then
-             with Stack.States[Pred(Stack.Count)] do
-                  begin
-                  if Me^.dX.isNegative then AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0)
-                                       else AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0);
-                  AddAction(MadeActions, aia_HJump, 0, 305 + random(50), 0, 0);
-                  AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
-                  if Me^.dX.isNegative then AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
-                                       else AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
-                  end;
-       if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
-          if Push(ticks, Actions, AltMe, Me^.Message) then
-             with Stack.States[Pred(Stack.Count)] do
-                  AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
+        if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
+            if Push(ticks, Actions, AltMe, Me^.Message) then
+                with Stack.States[Pred(Stack.Count)] do
+                    begin
+                    if Me^.dX.isNegative then
+                        AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0)
+                    else
+                        AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0);
+                        
+                    AddAction(MadeActions, aia_HJump, 0, 305 + random(50), 0, 0);
+                    AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
+                    
+                    if Me^.dX.isNegative then
+                        AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
+                    else
+                        AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
+                    end;
+        if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
+            if Push(ticks, Actions, AltMe, Me^.Message) then
+                with Stack.States[Pred(Stack.Count)] do
+                    AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
 
-       if not CanGo then break;
-       inc(steps);
-       Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
-       Rate:= RatePlace(Me);
-       if Rate > BestRate then
-          begin
-          BestActions:= Actions;
-          BestActions.isWalkingToABetterPlace:= true;
-          BestRate:= Rate;
-          Me^.State:= Me^.State or gstAttacked // 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 TestAmmos(Actions, Me, true);
-       if GoInfo.FallPix >= FallPixForBranching then
-          Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
-       end;
+        if not CanGo then
+            break;
+        inc(steps);
+         Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
+         Rate:= RatePlace(Me);
+         if Rate > BestRate then
+            begin
+            BestActions:= Actions;
+            BestActions.isWalkingToABetterPlace:= true;
+            BestRate:= Rate;
+            Me^.State:= Me^.State or gstAttacked // 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
+            TestAmmos(Actions, Me, true);
+        if GoInfo.FallPix >= FallPixForBranching then
+            Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
+        end;
 
-    if BestRate > BaseRate then exit
-    end
+    if BestRate > BaseRate then
+        exit
+        end
 end;
 
 function Think(Me: Pointer): ptrint;
@@ -283,8 +305,8 @@
 switchAvailable:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch);
 
 if (PGear(Me)^.State and gstAttacked) = 0 then
-   if Targets.Count > 0 then
-      begin
+    if Targets.Count > 0 then
+        begin
         // iterate over current team hedgehogs
         repeat
             WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^;
@@ -318,7 +340,8 @@
             or (itHedgehog = currHedgehogIndex)
             or BestActions.isWalkingToABetterPlace;
 
-        if (StartTicks > GameTicks - 1500) and (not StopThinking) then SDL_Delay(1000);
+        if (StartTicks > GameTicks - 1500) and (not StopThinking) then
+            SDL_Delay(1000);
 
         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
             begin
@@ -326,8 +349,9 @@
             AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
             end;
 
-      end else
-else begin
+        end else
+else
+    begin
     BackMe:= PGear(Me)^;
     while (not StopThinking) and (BestActions.Count = 0) do
         begin
@@ -337,7 +361,8 @@
         Actions.Pos:= 0;
         Actions.Score:= 0;
         Walk(@WalkMe, Actions);
-        if not StopThinking then SDL_Delay(100)
+        if not StopThinking then
+            SDL_Delay(100)
         end
     end;
 
@@ -349,7 +374,8 @@
 procedure StartThink(Me: PGear);
 begin
 if ((Me^.State and (gstAttacking or gstHHJumping or gstMoving)) <> 0)
-   or isInMultiShoot then exit;
+or isInMultiShoot then
+    exit;
 
 //DeleteCI(Me); // this might break demo
 Me^.State:= Me^.State or gstHHThinking;
@@ -365,10 +391,10 @@
 
 FillTargets;
 if Targets.Count = 0 then
-   begin
-   OutError('AI: no targets!?', false);
-   exit
-   end;
+    begin
+    OutError('AI: no targets!?', false);
+    exit
+    end;
 
 FillBonuses((Me^.State and gstAttacked) <> 0);
 AddFileLog('Enter Think Thread');
@@ -385,24 +411,28 @@
       cStopThinkTime = 40;
 begin
 with CurrentHedgehog^ do
-     if (Gear <> nil)
-        and ((Gear^.State and gstHHDriven) <> 0)
-        and (TurnTimeLeft < cHedgehogTurnTime - 50) then
+    if (Gear <> nil)
+    and ((Gear^.State and gstHHDriven) <> 0)
+    and (TurnTimeLeft < cHedgehogTurnTime - 50) then
         if ((Gear^.State and gstHHThinking) = 0) then
-           if (BestActions.Pos >= BestActions.Count)
-              and (TurnTimeLeft > cStopThinkTime) then
-              begin
-              if Gear^.Message <> 0 then
-                 begin
-                 StopMessages(Gear^.Message);
-                 TryDo((Gear^.Message and gmAllStoppable) = 0, 'Engine bug: AI may break demos playing', true);
-                 end;
-              if Gear^.Message <> 0 then exit;
-              StartThink(Gear);
-              StartTicks:= GameTicks
-              end else ProcessAction(BestActions, Gear)
+            if (BestActions.Pos >= BestActions.Count)
+            and (TurnTimeLeft > cStopThinkTime) then
+                begin
+                if Gear^.Message <> 0 then
+                    begin
+                    StopMessages(Gear^.Message);
+                    TryDo((Gear^.Message and gmAllStoppable) = 0, 'Engine bug: AI may break demos playing', true);
+                    end;
+                if Gear^.Message <> 0 then
+                    exit;
+                StartThink(Gear);
+                StartTicks:= GameTicks
+                
+                end else
+                    ProcessAction(BestActions, Gear)
         else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
-                or (TurnTimeLeft <= cStopThinkTime) then StopThinking:= true
+        or (TurnTimeLeft <= cStopThinkTime) then
+            StopThinking:= true
 end;
 
 procedure initModule;