hedgewars/uAI.pas
changeset 66 9643d75baf1e
parent 64 9df467527ae5
child 70 82d93eeecebe
--- a/hedgewars/uAI.pas	Tue Jun 20 20:08:17 2006 +0000
+++ b/hedgewars/uAI.pas	Tue Jun 20 21:18:49 2006 +0000
@@ -40,75 +40,139 @@
 implementation
 uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc;
 
-var Targets: TTargets;
-    Actions, BestActions: TActions;
+var BestActions: TActions;
+    ThinkThread: PSDL_Thread = nil;
+    StopThinking: boolean;
 
 procedure FreeActionsList;
 begin
+if ThinkThread <> nil then
+   begin
+   StopThinking:= true;
+   SDL_WaitThread(ThinkThread, nil);
+   ThinkThread:= nil
+   end;
 BestActions.Count:= 0;
-BestActions.Pos:= 0;
+BestActions.Pos:= 0
 end;
 
-procedure TestAmmos(Me: PGear);
-var MyPoint: TPoint;
-    Time: Longword;
+procedure TestAmmos(var Actions: TActions; Me: PGear);
+var Time: Longword;
     Angle, Power, Score: integer;
     i: integer;
+    a, aa: TAmmoType;
 begin
-Mypoint.x:= round(Me.X);
-Mypoint.y:= round(Me.Y);
 for i:= 0 to Pred(Targets.Count) do
-  begin
-  Score:= TestBazooka(MyPoint, Targets.ar[i].Point, Time, Angle, Power);
-  if Actions.Score + Score + Targets.ar[i].Score > BestActions.Score then
-   begin
-   BestActions:= Actions;
-   inc(BestActions.Score, Score + Targets.ar[i].Score);
-   AddAction(BestActions, aia_Weapon, Longword(amBazooka), 500);
-   if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200)
-   else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200);
-   Angle:= integer(Me.Angle) - Abs(Angle);
-   if Angle > 0 then
-      begin
-      AddAction(BestActions, aia_Up, aim_push, 500);
-      AddAction(BestActions, aia_Up, aim_release, Angle)
-      end else if Angle < 0 then
-      begin
-      AddAction(BestActions, aia_Down, aim_push, 500);
-      AddAction(BestActions, aia_Down, aim_release, -Angle)
-      end;
-   AddAction(BestActions, aia_attack, aim_push, 300);
-   AddAction(BestActions, aia_attack, aim_release, Power);
-   end
-  end
+    if Targets.ar[i].Score >= 0 then
+       begin
+       a:= Low(TAmmoType);
+       aa:= a;
+       repeat
+        if Assigned(AmmoTests[a]) then
+           begin
+           Score:= AmmoTests[a](Me, Targets.ar[i].Point, Time, Angle, Power);
+           if Actions.Score + Score + Targets.ar[i].Score > BestActions.Score then
+              begin
+              BestActions:= Actions;
+              inc(BestActions.Score, Score + Targets.ar[i].Score);
+              AddAction(BestActions, aia_Weapon, Longword(a), 500);
+              if Time <> 0 then AddAction(BestActions, aia_Timer, Time div 1000, 400);
+              if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200)
+              else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200);
+              Angle:= integer(Me.Angle) - Abs(Angle);
+              if Angle > 0 then
+                 begin
+                 AddAction(BestActions, aia_Up, aim_push, 500);
+                 AddAction(BestActions, aia_Up, aim_release, Angle)
+                 end else if Angle < 0 then
+                 begin
+                 AddAction(BestActions, aia_Down, aim_push, 500);
+                 AddAction(BestActions, aia_Down, aim_release, -Angle)
+                 end;
+              AddAction(BestActions, aia_attack, aim_push, 300);
+              AddAction(BestActions, aia_attack, aim_release, Power);
+              end
+           end;
+        if a = High(TAmmoType) then a:= Low(TAmmoType)
+                               else inc(a)
+       until isInMultiShoot or (a = aa) or (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].AttacksNum > 0)
+       end
 end;
 
 procedure Walk(Me: PGear);
+var Actions: TActions;
+    BackMe: TGear;
+    Dir, t, avoidt, steps: integer;
 begin
-TestAmmos(Me)
-end;
-
-procedure Think(Me: PGear);
-begin
-FillTargets(Targets);
 Actions.Score:= 0;
 Actions.Count:= 0;
 Actions.Pos:= 0;
+BackMe:= Me^;
+if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me);
+avoidt:= CheckBonuses(Me);
+for Dir:= aia_Left to aia_Right do
+    begin
+    Me.Message:= Dir;
+    steps:= 0;
+    while HHGo(Me) do
+       begin
+       inc(steps);
+       Actions.Count:= 0;
+       AddAction(Actions, Dir, aim_push, 50);
+       AddAction(Actions, aia_WaitX, round(Me.X), 0);
+       AddAction(Actions, Dir, aim_release, 0);
+       t:= CheckBonuses(Me);
+       if t < avoidt then break
+       else if (t > 0) or (t > avoidt) then
+            begin
+            BestActions:= Actions;
+            exit
+            end;
+       if ((Me.State and gstAttacked) = 0)
+       and ((steps mod 4) = 0) then TestAmmos(Actions, Me);
+       if StopThinking then exit;
+       end;
+    Me^:= BackMe
+    end
+end;
+
+procedure Think(Me: PGear); cdecl;
+var BackMe: TGear;
+    StartTicks: Longword;
+begin
+{$IFDEF DEBUGFILE}AddFileLog('Enter Think Thread');{$ENDIF}
+StartTicks:= GameTicks;
+ThinkingHH:= Me;
+FillTargets;
+FillBonuses;
 BestActions.Score:= Low(integer);
 if Targets.Count > 0 then
-   Walk(Me)
+   begin
+   BackMe:= Me^;
+   Walk(@BackMe);
+   end;
+if StartTicks > GameTicks - 1000 then SDL_Delay(500);
+Me.State:= Me.State and not gstHHThinking;
+{$IFDEF DEBUGFILE}AddFileLog('Exit Think Thread');{$ENDIF}
+ThinkThread:= nil
+end;
+
+procedure StartThink(Me: PGear);
+begin
+Me.State:= Me.State or gstHHThinking;
+StopThinking:= false;
+ThinkThread:= SDL_CreateThread(@Think, Me)
 end;
 
 procedure ProcessBot;
-var Me: PGear;
 begin
 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
-     if (Gear <> nil)and((Gear.State and gstHHDriven) <> 0) and (TurnTimeLeft < 29990) then
-        begin
-        Me:= CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear;
-        if BestActions.Count = BestActions.Pos then Think(Me);
-        ProcessAction(BestActions, Me)
-        end
+     if (Gear <> nil)
+        and ((Gear.State and gstHHDriven) <> 0)
+        and (TurnTimeLeft < 29990)
+        and ((Gear.State and gstHHThinking) = 0) then
+           if (BestActions.Pos = BestActions.Count) then StartThink(Gear)
+                                                    else ProcessAction(BestActions, Gear)
 end;
 
 end.