hedgewars/uAI.pas
changeset 369 2aed85310727
parent 351 29bc9c36ad5f
child 370 c75410fe3133
equal deleted inserted replaced
368:fe71e55d2d7b 369:2aed85310727
    22 {$INCLUDE options.inc}
    22 {$INCLUDE options.inc}
    23 procedure ProcessBot(FrameNo: Longword);
    23 procedure ProcessBot(FrameNo: Longword);
    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      uAIThinkStack, uAmmos;
    28      uAIThinkStack, uAmmos;
    29 
    29 
    30 var BestActions: TActions;
    30 var BestActions: TActions;
    31     CanUseAmmo: array [TAmmoType] of boolean;
    31     CanUseAmmo: array [TAmmoType] of boolean;
    32     AIThinkStart: Longword;
    32     AIThinkStart: Longword;
    33     isThinking: boolean = false;
    33     isThinking: boolean = false;
    34 
    34 
    35 }procedure FreeActionsList;
    35 procedure FreeActionsList;
    36 begin
    36 begin
    37 {isThinking:= false;
    37 isThinking:= false;
    38 BestActions.Count:= 0;
    38 BestActions.Count:= 0;
    39 BestActions.Pos:= 0
    39 BestActions.Pos:= 0
    40 }end;
    40 end;
    41 {
    41 
    42 procedure TestAmmos(var Actions: TActions; Me: PGear);
    42 procedure TestAmmos(var Actions: TActions; Me: PGear);
    43 var Time, BotLevel: Longword;
    43 var Time, BotLevel: Longword;
    44     Angle, Power, Score, ExplX, ExplY, ExplR: integer;
    44     Angle, Power, Score, ExplX, ExplY, ExplR: integer;
    45     i: integer;
    45     i: integer;
    46     a, aa: TAmmoType;
    46     a, aa: TAmmoType;
    47 begin
    47 begin
    48 BotLevel:= PHedgehog(Me.Hedgehog).BotLevel;
    48 BotLevel:= PHedgehog(Me^.Hedgehog)^.BotLevel;
    49 
    49 
    50 for i:= 0 to Pred(Targets.Count) do
    50 for i:= 0 to Pred(Targets.Count) do
    51     if (Targets.ar[i].Score >= 0) then
    51     if (Targets.ar[i].Score >= 0) then
    52        begin
    52        begin
    53        with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
    53        with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
    54             a:= Ammo[CurSlot, CurAmmo].AmmoType;
    54             a:= Ammo^[CurSlot, CurAmmo].AmmoType;
    55        aa:= a;
    55        aa:= a;
    56        repeat
    56        repeat
    57         if CanUseAmmo[a] then
    57         if CanUseAmmo[a] then
    58            begin
    58            begin
    59            Score:= AmmoTests[a](Me, Targets.ar[i].Point, BotLevel, Time, Angle, Power, ExplX, ExplY, ExplR);
    59            Score:= AmmoTests[a](Me, Targets.ar[i].Point, BotLevel, Time, Angle, Power, ExplX, ExplY, ExplR);
    60            if Actions.Score + Score > BestActions.Score then
    60            if Actions.Score + Score > BestActions.Score then
    61               begin
    61               begin
    62               BestActions:= Actions;
    62               BestActions:= Actions;
    63               inc(BestActions.Score, Score);
    63               inc(BestActions.Score, Score);
    64 
    64 
    65               AddAction(BestActions, aia_Weapon, Longword(a), 500);
    65               AddAction(BestActions, aia_Weapon, Longword(a), 500, 0, 0);
    66               if Time <> 0 then AddAction(BestActions, aia_Timer, Time div 1000, 400);
    66               if Time <> 0 then AddAction(BestActions, aia_Timer, Time div 1000, 400, 0, 0);
    67               if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200)
    67               if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
    68               else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200);
    68               else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
    69               if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
    69               if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
    70                  begin
    70                  begin
    71                  Angle:= integer(Me.Angle) - Abs(Angle);
    71                  Angle:= integer(Me^.Angle) - Abs(Angle);
    72                  if Angle > 0 then
    72                  if Angle > 0 then
    73                     begin
    73                     begin
    74                     AddAction(BestActions, aia_Up, aim_push, 500);
    74                     AddAction(BestActions, aia_Up, aim_push, 500, 0, 0);
    75                     AddAction(BestActions, aia_Up, aim_release, Angle)
    75                     AddAction(BestActions, aia_Up, aim_release, Angle, 0, 0)
    76                     end else if Angle < 0 then
    76                     end else if Angle < 0 then
    77                     begin
    77                     begin
    78                     AddAction(BestActions, aia_Down, aim_push, 500);
    78                     AddAction(BestActions, aia_Down, aim_push, 500, 0, 0);
    79                     AddAction(BestActions, aia_Down, aim_release, -Angle)
    79                     AddAction(BestActions, aia_Down, aim_release, -Angle, 0, 0)
    80                     end
    80                     end
    81                  end;
    81                  end;
    82               AddAction(BestActions, aia_attack, aim_push, 800);
    82               AddAction(BestActions, aia_attack, aim_push, 800, 0, 0);
    83               AddAction(BestActions, aia_attack, aim_release, Power);
    83               AddAction(BestActions, aia_attack, aim_release, Power, 0, 0);
    84               if ExplR > 0 then
    84               if ExplR > 0 then
    85                  AddAction(BestActions, aia_AwareExpl, ExplR, 10, ExplX, ExplY);
    85                  AddAction(BestActions, aia_AwareExpl, ExplR, 10, ExplX, ExplY);
    86               end
    86               end
    87            end;
    87            end;
    88         if a = High(TAmmoType) then a:= Low(TAmmoType)
    88         if a = High(TAmmoType) then a:= Low(TAmmoType)
    89                                else inc(a)
    89                                else inc(a)
    90        until (a = aa) or (PHedgehog(Me.Hedgehog).AttacksNum > 0)
    90        until (a = aa) or (PHedgehog(Me^.Hedgehog)^.AttacksNum > 0)
    91        end
    91        end
    92 end;
    92 end;
    93 
    93 
    94 procedure Walk(Me: PGear);
    94 procedure Walk(Me: PGear);
    95 const FallPixForBranching = cHHRadius * 2 + 8;
    95 const FallPixForBranching = cHHRadius * 2 + 8;
    99     BaseRate, Rate: integer;
    99     BaseRate, Rate: integer;
   100     GoInfo: TGoInfo;
   100     GoInfo: TGoInfo;
   101     CanGo: boolean;
   101     CanGo: boolean;
   102     AltMe: TGear;
   102     AltMe: TGear;
   103 begin
   103 begin
   104 BotLevel:= PHedgehog(Me.Hedgehog).BotLevel;
   104 BotLevel:= PHedgehog(Me^.Hedgehog)^.BotLevel;
   105 
   105 
   106 if (Me.State and gstAttacked) = 0 then maxticks:= max(0, TurnTimeLeft - 5000 - 4000 * BotLevel)
   106 if (Me^.State and gstAttacked) = 0 then maxticks:= max(0, TurnTimeLeft - 5000 - 4000 * BotLevel)
   107                                   else maxticks:= TurnTimeLeft;
   107                                   else maxticks:= TurnTimeLeft;
   108 
   108 
   109 BaseRate:= RatePlace(Me);
   109 BaseRate:= RatePlace(Me);
   110 
   110 
   111 repeat
   111 repeat
   113        begin
   113        begin
   114        isThinking:= false;
   114        isThinking:= false;
   115        exit
   115        exit
   116        end;
   116        end;
   117 
   117 
   118     AddAction(Actions, Me.Message, aim_push, 10);
   118     AddAction(Actions, Me^.Message, aim_push, 10, 0, 0);
   119     if (Me.Message and gm_Left) <> 0 then AddAction(Actions, aia_WaitXL, round(Me.X), 0)
   119     if (Me^.Message and gm_Left) <> 0 then AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
   120                                      else AddAction(Actions, aia_WaitXR, round(Me.X), 0);
   120                                      else AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
   121     AddAction(Actions, Me.Message, aim_release, 0);
   121     AddAction(Actions, Me^.Message, aim_release, 0, 0, 0);
   122     steps:= 0;
   122     steps:= 0;
   123     if ((Me.State and gstAttacked) = 0) then TestAmmos(Actions, Me);
   123     if ((Me^.State and gstAttacked) = 0) then TestAmmos(Actions, Me);
   124 
   124 
   125     while not PosInThinkStack(Me) do
   125     while not PosInThinkStack(Me) do
   126        begin
   126        begin
   127        CanGo:= HHGo(Me, @AltMe, GoInfo);
   127        CanGo:= HHGo(Me, @AltMe, GoInfo);
   128        inc(ticks, GoInfo.Ticks);
   128        inc(ticks, GoInfo.Ticks);
   130 
   130 
   131        if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
   131        if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
   132           if Push(ticks, Actions, AltMe, Me^.Message) then
   132           if Push(ticks, Actions, AltMe, Me^.Message) then
   133              with ThinkStack.States[Pred(ThinkStack.Count)] do
   133              with ThinkStack.States[Pred(ThinkStack.Count)] do
   134                   begin
   134                   begin
   135                   AddAction(MadeActions, aia_HJump, 0, 305);
   135                   AddAction(MadeActions, aia_HJump, 0, 305, 0, 0);
   136                   AddAction(MadeActions, aia_HJump, 0, 350);
   136                   AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
   137                   if (Me.dX < 0) then AddAction(MadeActions, aia_WaitXL, round(AltMe.X), 0)
   137                   if (Me^.dX < 0) then AddAction(MadeActions, aia_WaitXL, hwRound(AltMe.X), 0, 0, 0)
   138                                  else AddAction(MadeActions, aia_WaitXR, round(AltMe.X), 0);
   138                                  else AddAction(MadeActions, aia_WaitXR, hwRound(AltMe.X), 0, 0, 0);
   139                   end;
   139                   end;
   140        if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
   140        if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
   141           if Push(ticks, Actions, AltMe, Me^.Message) then
   141           if Push(ticks, Actions, AltMe, Me^.Message) then
   142              with ThinkStack.States[Pred(ThinkStack.Count)] do
   142              with ThinkStack.States[Pred(ThinkStack.Count)] do
   143                   begin
   143                   begin
   144                   AddAction(MadeActions, aia_LJump, 0, 305);
   144                   AddAction(MadeActions, aia_LJump, 0, 305, 0, 0);
   145                   if (Me.dX < 0) then AddAction(MadeActions, aia_WaitXL, round(AltMe.X), 0)
   145                   if (Me^.dX < 0) then AddAction(MadeActions, aia_WaitXL, hwRound(AltMe.X), 0, 0, 0)
   146                                  else AddAction(MadeActions, aia_WaitXR, round(AltMe.X), 0);
   146                                  else AddAction(MadeActions, aia_WaitXR, hwRound(AltMe.X), 0, 0, 0);
   147                   end;
   147                   end;
   148 
   148 
   149        if not CanGo then break;
   149        if not CanGo then break;
   150        inc(steps);
   150        inc(steps);
   151        Actions.actions[Actions.Count - 2].Param:= round(Me.X);
   151        Actions.actions[Actions.Count - 2].Param:= hwRound(Me^.X);
   152        Rate:= RatePlace(Me);
   152        Rate:= RatePlace(Me);
   153        if Rate > BaseRate then
   153        if Rate > BaseRate then
   154           begin
   154           begin
   155           BestActions:= Actions;
   155           BestActions:= Actions;
   156           BestActions.Score:= 1;
   156           BestActions.Score:= 1;
   159           end
   159           end
   160        else if Rate < BaseRate then break;
   160        else if Rate < BaseRate then break;
   161        if GoInfo.FallPix >= FallPixForBranching then
   161        if GoInfo.FallPix >= FallPixForBranching then
   162           Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   162           Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   163 
   163 
   164        if ((Me.State and gstAttacked) = 0)
   164        if ((Me^.State and gstAttacked) = 0)
   165            and ((steps mod 4) = 0) then
   165            and ((steps mod 4) = 0) then
   166            begin
   166            begin
   167            if SDL_GetTicks - AIThinkStart > 3 then
   167            if SDL_GetTicks - AIThinkStart > 3 then
   168               begin
   168               begin
   169               dec(Actions.Count, 3);
   169               dec(Actions.Count, 3);
   180 var BackMe, WalkMe: TGear;
   180 var BackMe, WalkMe: TGear;
   181 begin
   181 begin
   182 AIThinkStart:= SDL_GetTicks;
   182 AIThinkStart:= SDL_GetTicks;
   183 BackMe:= Me^;
   183 BackMe:= Me^;
   184 WalkMe:= BackMe;
   184 WalkMe:= BackMe;
   185 if (Me.State and gstAttacked) = 0 then
   185 if (Me^.State and gstAttacked) = 0 then
   186    if Targets.Count > 0 then
   186    if Targets.Count > 0 then
   187       begin
   187       begin
   188       Walk(@WalkMe);
   188       Walk(@WalkMe);
   189       if not isThinking then
   189       if not isThinking then
   190          begin
   190          begin
   191          if BestActions.Score < -1023 then
   191          if BestActions.Score < -1023 then
   192             begin
   192             begin
   193             BestActions.Count:= 0;
   193             BestActions.Count:= 0;
   194             AddAction(BestActions, aia_Skip, 0, 250);
   194             AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   195             end;
   195             end;
   196          Me.State:= Me.State and not gstHHThinking
   196          Me^.State:= Me^.State and not gstHHThinking
   197          end
   197          end
   198       end else
   198       end else
   199 else begin
   199 else begin
   200       FillBonuses(true);
   200       FillBonuses(true);
   201       Walk(@WalkMe);
   201       Walk(@WalkMe);
   202       AddAction(BestActions, aia_Wait, GameTicks + 100, 100);
   202       AddAction(BestActions, aia_Wait, GameTicks + 100, 100, 0, 0);
   203       end
   203       end
   204 end;
   204 end;
   205 
   205 
   206 procedure StartThink(Me: PGear);
   206 procedure StartThink(Me: PGear);
   207 var a: TAmmoType;
   207 var a: TAmmoType;
   208     tmp: integer;
   208     tmp: integer;
   209 begin
   209 begin
   210 if ((Me.State and gstAttacking) <> 0) or isInMultiShoot then exit;
   210 if ((Me^.State and gstAttacking) <> 0) or isInMultiShoot then exit;
   211 ThinkingHH:= Me;
   211 ThinkingHH:= Me;
   212 isThinking:= true;
   212 isThinking:= true;
   213 
   213 
   214 ClearThinkStack;
   214 ClearThinkStack;
   215 
   215 
   216 Me.State:= Me.State or gstHHThinking;
   216 Me^.State:= Me^.State or gstHHThinking;
   217 Me.Message:= 0;
   217 Me^.Message:= 0;
   218 FillTargets;
   218 FillTargets;
   219 if Targets.Count = 0 then
   219 if Targets.Count = 0 then
   220    begin
   220    begin
   221    OutError('AI: no targets!?');
   221    OutError('AI: no targets!?', false);
   222    exit
   222    exit
   223    end;
   223    end;
   224 
   224 
   225 FillBonuses((Me.State and gstAttacked) <> 0);
   225 FillBonuses((Me^.State and gstAttacked) <> 0);
   226 
   226 
   227 for a:= Low(TAmmoType) to High(TAmmoType) do
   227 for a:= Low(TAmmoType) to High(TAmmoType) do
   228     CanUseAmmo[a]:= Assigned(AmmoTests[a]) and HHHasAmmo(PHedgehog(Me.Hedgehog), a);
   228     CanUseAmmo[a]:= Assigned(AmmoTests[a]) and HHHasAmmo(PHedgehog(Me^.Hedgehog), a);
   229 
   229 
   230 BestActions.Count:= 0;
   230 BestActions.Count:= 0;
   231 BestActions.Pos:= 0;
   231 BestActions.Pos:= 0;
   232 BestActions.Score:= 0;
   232 BestActions.Score:= 0;
   233 tmp:= random(2) + 1;
   233 tmp:= random(2) + 1;
   234 Push(0, BestActions, Me^, tmp);
   234 Push(0, BestActions, Me^, tmp);
   235 Push(0, BestActions, Me^, tmp xor 3);
   235 Push(0, BestActions, Me^, tmp xor 3);
   236 BestActions.Score:= Low(integer);
   236 BestActions.Score:= Low(integer);
   237 
   237 
   238 Think(Me)
   238 Think(Me)
   239 end; }
   239 end; 
   240 
   240 
   241 procedure ProcessBot(FrameNo: Longword);
   241 procedure ProcessBot(FrameNo: Longword);
   242 //const LastFrameNo: Longword = 0;
   242 const LastFrameNo: Longword = 0;
   243 begin
   243 begin
   244 {with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do
   244 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
   245      if (Gear <> nil)
   245      if (Gear <> nil)
   246         and ((Gear.State and gstHHDriven) <> 0)
   246         and ((Gear^.State and gstHHDriven) <> 0)
   247         and (TurnTimeLeft < cHedgehogTurnTime - 50) then
   247         and (TurnTimeLeft < cHedgehogTurnTime - 50) then
   248         if not isThinking then
   248         if not isThinking then
   249            if (BestActions.Pos >= BestActions.Count) then StartThink(Gear)
   249            if (BestActions.Pos >= BestActions.Count) then StartThink(Gear)
   250                                                      else ProcessAction(BestActions, Gear)
   250                                                      else ProcessAction(BestActions, Gear)
   251         else if FrameNo <> LastFrameNo then
   251         else if FrameNo <> LastFrameNo then
   252                 begin
   252                 begin
   253                 LastFrameNo:= FrameNo;
   253                 LastFrameNo:= FrameNo;
   254                 Think(Gear)
   254                 Think(Gear)
   255                 end;
   255                 end;
   256 }end;
   256 end;
   257 
   257 
   258 end.
   258 end.