hedgewars/uAI.pas
branchwebgl
changeset 8026 4a4f21070479
parent 7790 040fc517fece
child 8096 453917e94e55
equal deleted inserted replaced
8023:7de85783b823 8026:4a4f21070479
    31 implementation
    31 implementation
    32 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions,
    32 uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions,
    33     uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
    33     uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
    34     uVariables, uCommands, uUtils, uDebug, uAILandMarks;
    34     uVariables, uCommands, uUtils, uDebug, uAILandMarks;
    35 
    35 
       
    36 {$IFDEF AI_MAINTHREAD}
       
    37 const
       
    38     mainThreadMaxThinkTime:Integer = 1500;
       
    39 {$ENDIF}
       
    40 
    36 var BestActions: TActions;
    41 var BestActions: TActions;
    37     CanUseAmmo: array [TAmmoType] of boolean;
    42     CanUseAmmo: array [TAmmoType] of boolean;
    38     StopThinking: boolean;
    43     StopThinking: boolean;
    39 {$IFDEF USE_SDLTHREADS} 
    44 {$IFDEF USE_SDLTHREADS} 
    40     ThinkThread: PSDL_Thread = nil;
    45     ThinkThread: PSDL_Thread = nil;
    41 {$ELSE}
    46 {$ELSE}
    42     ThinkThread: TThreadID;
    47     ThinkThread: TThreadID;
    43 {$ENDIF}
    48 {$ENDIF}
    44     hasThread: LongInt;
    49     hasThread: LongInt;
    45     StartTicks: Longword;
    50     StartTicks: LongInt;
    46 
    51 
    47 procedure FreeActionsList;
    52 procedure FreeActionsList;
    48 begin
    53 begin
    49     AddFileLog('FreeActionsList called');
    54     AddFileLog('FreeActionsList called');
    50     if hasThread <> 0 then
    55     if hasThread <> 0 then
   328                         AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
   333                         AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
   329                 break
   334                 break
   330                 end;
   335                 end;
   331 
   336 
   332             // 'not CanGO' means we can't go straight, possible jumps are checked above
   337             // 'not CanGO' means we can't go straight, possible jumps are checked above
   333             if not CanGo then
   338             if (not CanGo) then
   334                 break;
   339                 break;
   335             
   340             
   336              inc(steps);
   341              inc(steps);
   337              Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
   342              Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
   338              Rate:= RatePlace(Me);
   343              Rate:= RatePlace(Me);
   355                 TestAmmos(Actions, Me, ticks shr 12 = oldticks shr 12);
   360                 TestAmmos(Actions, Me, ticks shr 12 = oldticks shr 12);
   356                 end;
   361                 end;
   357                 
   362                 
   358             if GoInfo.FallPix >= FallPixForBranching then
   363             if GoInfo.FallPix >= FallPixForBranching then
   359                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   364                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
       
   365 
       
   366 {$IFDEF AI_MAINTHREAD}
       
   367             if StartTicks < (SDL_GetTicks() - mainThreadMaxThinkTime) then
       
   368                 StopThinking := true;
       
   369 {$ELSE}
       
   370             if (StartTicks > GameTicks - 1500) and (not StopThinking) then
       
   371                 SDL_Delay(1000);
       
   372 {$ENDIF}
       
   373 
   360             end {while};
   374             end {while};
   361 
   375 
   362         if BestRate > BaseRate then
   376         if BestRate > BaseRate then
   363             exit
   377             exit
   364         end {while}
   378         end {while}
   366 end;
   380 end;
   367 
   381 
   368 function Think(Me: Pointer): ptrint;
   382 function Think(Me: Pointer): ptrint;
   369 var BackMe, WalkMe: TGear;
   383 var BackMe, WalkMe: TGear;
   370     switchCount: LongInt;
   384     switchCount: LongInt;
   371     StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
   385     currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
   372     switchImmediatelyAvailable: boolean;
   386     switchImmediatelyAvailable: boolean;
   373     Actions: TActions;
   387     Actions: TActions;
   374 begin
   388 begin
   375 InterlockedIncrement(hasThread);
   389 InterlockedIncrement(hasThread);
       
   390 
       
   391 {$IFDEF AI_MAINTHREAD}
       
   392 StartTicks:= SDL_GetTicks();
       
   393 {$ELSE}
   376 StartTicks:= GameTicks;
   394 StartTicks:= GameTicks;
       
   395 {$ENDIF}
       
   396 
   377 currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
   397 currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
   378 itHedgehog:= currHedgehogIndex;
   398 itHedgehog:= currHedgehogIndex;
   379 switchesNum:= 0;
   399 switchesNum:= 0;
   380 
   400 
   381 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
   401 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
   382 if PGear(Me)^.Hedgehog^.BotLevel <> 5 then
   402 if PGear(Me)^.Hedgehog^.BotLevel <> 5 then
   383     switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch)
   403     switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch)
   384 else switchCount:= 0;
   404 else switchCount:= 0;
   385 
   405 
   386 if (PGear(Me)^.State and gstAttacked) = 0 then
   406 if (PGear(Me)^.State and gstAttacking) = 0 then
   387     if Targets.Count > 0 then
   407     if Targets.Count > 0 then
   388         begin
   408         begin
   389         // iterate over current team hedgehogs
   409         // iterate over current team hedgehogs
   390         repeat
   410         repeat
   391             WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^;
   411             WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^;
   393             Actions.Count:= 0;
   413             Actions.Count:= 0;
   394             Actions.Pos:= 0;
   414             Actions.Pos:= 0;
   395             Actions.Score:= 0;
   415             Actions.Score:= 0;
   396             if switchesNum > 0 then
   416             if switchesNum > 0 then
   397                 begin
   417                 begin
   398                 if not switchImmediatelyAvailable  then
   418                 if (not switchImmediatelyAvailable)  then
   399                     begin
   419                     begin
   400                     // when AI has to use switcher, make it cost smth unless they have a lot of switches
   420                     // when AI has to use switcher, make it cost smth unless they have a lot of switches
   401                     if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
   421                     if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
   402                     AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);                    
   422                     AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);                    
   403                     AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
   423                     AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
   418         until (not (switchImmediatelyAvailable or (switchCount > 0)))
   438         until (not (switchImmediatelyAvailable or (switchCount > 0)))
   419             or StopThinking 
   439             or StopThinking 
   420             or (itHedgehog = currHedgehogIndex)
   440             or (itHedgehog = currHedgehogIndex)
   421             or BestActions.isWalkingToABetterPlace;
   441             or BestActions.isWalkingToABetterPlace;
   422 
   442 
   423         if (StartTicks > GameTicks - 1500) and (not StopThinking) then
   443             {$IFDEF AI_MAINTHREAD}
   424             SDL_Delay(1000);
   444                 if StartTicks < (SDL_GetTicks() - mainThreadMaxThinkTime) then
       
   445                     StopThinking := true;
       
   446             {$ELSE}
       
   447                 if (StartTicks > GameTicks - 1500) and (not StopThinking) then
       
   448                     SDL_Delay(1000);
       
   449             {$ENDIF}
   425 
   450 
   426         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
   451         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
   427             begin
   452             begin
   428             BestActions.Count:= 0;
   453             BestActions.Count:= 0;
   429             AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   454             AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   431 
   456 
   432         end else
   457         end else
   433 else
   458 else
   434     begin
   459     begin
   435     BackMe:= PGear(Me)^;
   460     BackMe:= PGear(Me)^;
       
   461     
       
   462 //{$IFNDEF AI_MAINTHREAD}
   436     while (not StopThinking) and (BestActions.Count = 0) do
   463     while (not StopThinking) and (BestActions.Count = 0) do
   437         begin
   464         begin
       
   465 
   438 (*
   466 (*
   439         // Maybe this would get a bit of movement out of them? Hopefully not *toward* water. Need to check how often he'd choose that strategy
   467         // Maybe this would get a bit of movement out of them? Hopefully not *toward* water. Need to check how often he'd choose that strategy
   440         if SuddenDeathDmg and ((hwRound(BackMe.Y)+cWaterRise*2) > cWaterLine) then
   468         if SuddenDeathDmg and ((hwRound(BackMe.Y)+cWaterRise*2) > cWaterLine) then
   441             AddBonus(hwRound(BackMe.X), hwRound(BackMe.Y), 250, -40);
   469             AddBonus(hwRound(BackMe.X), hwRound(BackMe.Y), 250, -40);
   442 *)
   470 *)
       
   471 
   443         FillBonuses(true);
   472         FillBonuses(true);
   444         WalkMe:= BackMe;
   473         WalkMe:= BackMe;
   445         Actions.Count:= 0;
   474         Actions.Count:= 0;
   446         Actions.Pos:= 0;
   475         Actions.Pos:= 0;
   447         Actions.Score:= 0;
   476         Actions.Score:= 0;
   448         Walk(@WalkMe, Actions);
   477         Walk(@WalkMe, Actions);
   449         if not StopThinking then
   478 {$IFNDEF AI_MAINTHREAD}
       
   479         if (not StopThinking) then
   450             SDL_Delay(100)
   480             SDL_Delay(100)
       
   481 {$ENDIF}
   451         end
   482         end
       
   483 //{$ENDIF}
   452     end;
   484     end;
   453 
   485 
   454 PGear(Me)^.State:= PGear(Me)^.State and (not gstHHThinking);
   486 PGear(Me)^.State:= PGear(Me)^.State and (not gstHHThinking);
   455 Think:= 0;
   487 Think:= 0;
   456 InterlockedDecrement(hasThread)
   488 InterlockedDecrement(hasThread)
   482     exit
   514     exit
   483     end;
   515     end;
   484 
   516 
   485 FillBonuses((Me^.State and gstAttacked) <> 0);
   517 FillBonuses((Me^.State and gstAttacked) <> 0);
   486 AddFileLog('Enter Think Thread');
   518 AddFileLog('Enter Think Thread');
       
   519 
       
   520 {$IFDEF AI_MAINTHREAD}
       
   521 Think(Me);
       
   522 {$ELSE}
   487 {$IFDEF USE_SDLTHREADS}
   523 {$IFDEF USE_SDLTHREADS}
   488 ThinkThread := SDL_CreateThread(@Think{$IFDEF SDL13}, nil{$ENDIF}, Me);
   524 ThinkThread := SDL_CreateThread(@Think{$IFDEF SDL13}, nil{$ENDIF}, Me);
   489 {$ELSE}
   525 {$ELSE}
   490 BeginThread(@Think, Me, ThinkThread);
   526 BeginThread(@Think, Me, ThinkThread);
   491 {$ENDIF}
   527 {$ENDIF}
   492 AddFileLog('Thread started');
   528 AddFileLog('Thread started');
       
   529 {$ENDIF}
   493 end;
   530 end;
   494 
   531 
   495 //var scoreShown: boolean = false;
   532 //var scoreShown: boolean = false;
   496 
   533 
   497 procedure ProcessBot;
   534 procedure ProcessBot;
   534 
   571 
   535 procedure initModule;
   572 procedure initModule;
   536 begin
   573 begin
   537     hasThread:= 0;
   574     hasThread:= 0;
   538     StartTicks:= 0;
   575     StartTicks:= 0;
       
   576 {$IFNDEF PAS2C}
   539     ThinkThread:= ThinkThread;
   577     ThinkThread:= ThinkThread;
       
   578 {$ENDIF}
   540 end;
   579 end;
   541 
   580 
   542 procedure freeModule;
   581 procedure freeModule;
   543 begin
   582 begin
   544     FreeActionsList();
   583     FreeActionsList();