hedgewars/uAI.pas
changeset 509 fd58135a4407
parent 508 f5473c50adbd
child 522 ca089787f59d
equal deleted inserted replaced
508:f5473c50adbd 509:fd58135a4407
    23 procedure ProcessBot;
    23 procedure ProcessBot;
    24 procedure FreeActionsList;
    24 procedure FreeActionsList;
    25 
    25 
    26 implementation
    26 implementation
    27 uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc,
    27 uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc,
    28      uAmmos, uConsole, uCollisions{$IFDEF UNIX}, cthreads{$ENDIF};
    28      uAmmos, uConsole, uCollisions, SysUtils{$IFDEF UNIX}, cthreads{$ENDIF};
    29 
    29 
    30 var BestActions: TActions;
    30 var BestActions: TActions;
    31     ThinkThread: THandle = 0;
    31     CanUseAmmo: array [TAmmoType] of boolean;
    32     StopThinking: boolean;
    32     StopThinking: boolean;
    33     CanUseAmmo: array [TAmmoType] of boolean;
    33     ThinkThread: THandle;
    34 
    34     hasThread: LongInt = 0;
       
    35     
    35 procedure FreeActionsList;
    36 procedure FreeActionsList;
    36 begin
    37 begin
    37 {$IFDEF DEBUGFILE}AddFileLog('FreeActionsList called');{$ENDIF}
    38 {$IFDEF DEBUGFILE}AddFileLog('FreeActionsList called');{$ENDIF}
    38 if ThinkThread <> 0 then
    39 if hasThread <> 0 then
    39    begin
    40    begin
    40    {$IFDEF DEBUGFILE}AddFileLog('Waiting AI thread to finish');{$ENDIF}
    41    {$IFDEF DEBUGFILE}AddFileLog('Waiting AI thread to finish');{$ENDIF}
    41    StopThinking:= true;
    42    StopThinking:= true;
    42    WaitForThreadTerminate(ThinkThread, 5000);
    43    repeat
    43    ThinkThread:= 0
    44      SDL_Delay(10)
       
    45    until hasThread = 0
    44    end;
    46    end;
    45 
    47 
    46 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
    48 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
    47      if Gear <> nil then
    49      if Gear <> nil then
    48         if BotLevel <> 0 then
    50         if BotLevel <> 0 then
    62     a, aa: TAmmoType;
    64     a, aa: TAmmoType;
    63 begin
    65 begin
    64 BotLevel:= PHedgehog(Me^.Hedgehog)^.BotLevel;
    66 BotLevel:= PHedgehog(Me^.Hedgehog)^.BotLevel;
    65 
    67 
    66 for i:= 0 to Pred(Targets.Count) do
    68 for i:= 0 to Pred(Targets.Count) do
    67     if (Targets.ar[i].Score >= 0) then
    69     if (Targets.ar[i].Score >= 0) and (not StopThinking) then
    68        begin
    70        begin
    69        with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
    71        with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
    70             a:= Ammo^[CurSlot, CurAmmo].AmmoType;
    72             a:= Ammo^[CurSlot, CurAmmo].AmmoType;
    71        aa:= a;
    73        aa:= a;
    72        repeat
    74        repeat
   101                  AddAction(BestActions, aia_AwareExpl, ExplR, 10, ExplX, ExplY);
   103                  AddAction(BestActions, aia_AwareExpl, ExplR, 10, ExplX, ExplY);
   102               end
   104               end
   103            end;
   105            end;
   104         if a = High(TAmmoType) then a:= Low(TAmmoType)
   106         if a = High(TAmmoType) then a:= Low(TAmmoType)
   105                                else inc(a)
   107                                else inc(a)
   106        until (a = aa) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].AttacksNum > 0)
   108        until (a = aa) or
       
   109              (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].AttacksNum > 0) or
       
   110              StopThinking
   107        end
   111        end
   108 end;
   112 end;
   109 
   113 
   110 procedure Walk(Me: PGear);
   114 procedure Walk(Me: PGear);
   111 const FallPixForBranching = cHHRadius * 2 + 8;
   115 const FallPixForBranching = cHHRadius * 2 + 8;
   239 
   243 
   240 function Think(Me: Pointer): ptrint;
   244 function Think(Me: Pointer): ptrint;
   241 var BackMe, WalkMe: TGear;
   245 var BackMe, WalkMe: TGear;
   242     StartTicks: Longword;
   246     StartTicks: Longword;
   243 begin
   247 begin
       
   248 InterlockedIncrement(hasThread);
   244 StartTicks:= GameTicks;
   249 StartTicks:= GameTicks;
   245 BestActions.Count:= 0;
       
   246 BestActions.Pos:= 0;
       
   247 BestActions.Score:= Low(integer);
       
   248 BackMe:= PGear(Me)^;
   250 BackMe:= PGear(Me)^;
   249 WalkMe:= BackMe;
   251 
   250 if (PGear(Me)^.State and gstAttacked) = 0 then
   252 if (PGear(Me)^.State and gstAttacked) = 0 then
   251    if Targets.Count > 0 then
   253    if Targets.Count > 0 then
   252       begin
   254       begin
       
   255       WalkMe:= BackMe;
   253       Walk(@WalkMe);
   256       Walk(@WalkMe);
   254       if (StartTicks > GameTicks - 1500) and not StopThinking then SDL_Delay(2000);
   257       if (StartTicks > GameTicks - 1500) and not StopThinking then SDL_Delay(2000);
   255       if BestActions.Score < -1023 then
   258       if BestActions.Score < -1023 then
   256          begin
   259          begin
   257          BestActions.Count:= 0;
   260          BestActions.Count:= 0;
   258          AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   261          AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   259          end;
   262          end;
   260       end else
   263       end else
   261 else begin
   264 else begin
   262       Walk(@WalkMe);
       
   263       while (not StopThinking) and (BestActions.Count = 0) do
   265       while (not StopThinking) and (BestActions.Count = 0) do
   264             begin
   266             begin
   265             SDL_Delay(100);
       
   266             FillBonuses(true);
   267             FillBonuses(true);
   267             WalkMe:= BackMe;
   268             WalkMe:= BackMe;
   268             Walk(@WalkMe)
   269             Walk(@WalkMe);
       
   270             if not StopThinking then SDL_Delay(100)
   269             end
   271             end
   270       end;
   272       end;
   271 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking;
   273 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking;
   272 Think:= 0
   274 Think:= 0;
       
   275 InterlockedDecrement(hasThread)
   273 end;
   276 end;
   274 
   277 
   275 procedure StartThink(Me: PGear);
   278 procedure StartThink(Me: PGear);
   276 var a: TAmmoType;
   279 var a: TAmmoType;
   277 begin
   280 begin
   279    or isInMultiShoot then exit;
   282    or isInMultiShoot then exit;
   280 
   283 
   281 DeleteCI(Me); // don't let collision info in Land to confuse AI
   284 DeleteCI(Me); // don't let collision info in Land to confuse AI
   282 Me^.State:= Me^.State or gstHHThinking;
   285 Me^.State:= Me^.State or gstHHThinking;
   283 Me^.Message:= 0;
   286 Me^.Message:= 0;
       
   287 
       
   288 BestActions.Count:= 0;
       
   289 BestActions.Pos:= 0;
       
   290 BestActions.Score:= Low(integer);
       
   291 
   284 StopThinking:= false;
   292 StopThinking:= false;
   285 ThinkingHH:= Me;
   293 ThinkingHH:= Me;
       
   294 
   286 FillTargets;
   295 FillTargets;
   287 if Targets.Count = 0 then
   296 if Targets.Count = 0 then
   288    begin
   297    begin
   289    OutError('AI: no targets!?', false);
   298    OutError('AI: no targets!?', false);
   290    exit
   299    exit
   296 BeginThread(@Think, Me, ThinkThread)
   305 BeginThread(@Think, Me, ThinkThread)
   297 end;
   306 end;
   298 
   307 
   299 procedure ProcessBot;
   308 procedure ProcessBot;
   300 const StartTicks: Longword = 0;
   309 const StartTicks: Longword = 0;
       
   310       cStopThinkTime = 40;
   301 begin
   311 begin
   302 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   312 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   303      if (Gear <> nil)
   313      if (Gear <> nil)
   304         and ((Gear^.State and gstHHDriven) <> 0)
   314         and ((Gear^.State and gstHHDriven) <> 0)
   305         and (TurnTimeLeft < cHedgehogTurnTime - 50) then
   315         and (TurnTimeLeft < cHedgehogTurnTime - 50) then
   306         if ((Gear^.State and gstHHThinking) = 0) then
   316         if ((Gear^.State and gstHHThinking) = 0) then
   307            if (BestActions.Pos >= BestActions.Count) then
   317            if (BestActions.Pos >= BestActions.Count)
       
   318               and (TurnTimeLeft > cStopThinkTime) then
   308               begin
   319               begin
   309               StartThink(Gear);
   320               StartThink(Gear);
   310               StartTicks:= GameTicks
   321               StartTicks:= GameTicks
   311               end else ProcessAction(BestActions, Gear)
   322               end else ProcessAction(BestActions, Gear)
   312         else if (GameTicks - StartTicks) > cMaxAIThinkTime then StopThinking:= true
   323         else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
   313 end;
   324                 or (TurnTimeLeft <= cStopThinkTime) then StopThinking:= true
   314 
   325 end;
   315 
   326 
   316 end.
   327 end.