hedgewars/uAI.pas
branchsdl2transition
changeset 11362 ed5a6478e710
parent 11360 7a7611adf715
parent 11046 47a8c19ecb60
child 11367 a91c4c4fd85c
equal deleted inserted replaced
11361:31570b766315 11362:ed5a6478e710
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    12  * GNU General Public License for more details.
    13  *
    13  *
    14  * You should have received a copy of the GNU General Public License
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
    16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17  *)
    17  *)
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uAI;
    21 unit uAI;
   106 procedure TestAmmos(var Actions: TActions; Me: PGear; rareChecks: boolean);
   106 procedure TestAmmos(var Actions: TActions; Me: PGear; rareChecks: boolean);
   107 var BotLevel: Byte;
   107 var BotLevel: Byte;
   108     ap: TAttackParams;
   108     ap: TAttackParams;
   109     Score, i, t, n, dAngle: LongInt;
   109     Score, i, t, n, dAngle: LongInt;
   110     a, aa: TAmmoType;
   110     a, aa: TAmmoType;
       
   111     useThisActions: boolean;
   111 begin
   112 begin
   112 BotLevel:= Me^.Hedgehog^.BotLevel;
   113 BotLevel:= Me^.Hedgehog^.BotLevel;
   113 windSpeed:= hwFloat2Float(cWindSpeed);
   114 windSpeed:= hwFloat2Float(cWindSpeed);
       
   115 useThisActions:= false;
   114 
   116 
   115 for i:= 0 to Pred(Targets.Count) do
   117 for i:= 0 to Pred(Targets.Count) do
   116     if (Targets.ar[i].Score >= 0) and (not StopThinking) then
   118     if (Targets.ar[i].Score >= 0) and (not StopThinking) then
   117         begin
   119         begin
   118         with Me^.Hedgehog^ do
   120         with Me^.Hedgehog^ do
   126             then
   128             then
   127             begin
   129             begin
   128 {$HINTS OFF}
   130 {$HINTS OFF}
   129             Score:= AmmoTests[a].proc(Me, Targets.ar[i], BotLevel, ap);
   131             Score:= AmmoTests[a].proc(Me, Targets.ar[i], BotLevel, ap);
   130 {$HINTS ON}
   132 {$HINTS ON}
   131             if Actions.Score + Score > BestActions.Score then
   133             if (Score > BadTurn) and (Actions.Score + Score > BestActions.Score) then
   132                 if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel - 1) * 2048) then
   134                 if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel - 1) * 2048) then
   133                     begin
   135                     begin
   134                     BestActions:= Actions;
   136                     if useThisActions then
   135                     inc(BestActions.Score, Score);
   137                         begin
   136                     BestActions.isWalkingToABetterPlace:= false;
   138                         BestActions.Count:= Actions.Count
       
   139                         end
       
   140                     else
       
   141                         begin
       
   142                         BestActions:= Actions;
       
   143                         BestActions.isWalkingToABetterPlace:= false;
       
   144                         useThisActions:= true
       
   145                         end;
       
   146 
       
   147                     BestActions.Score:= Actions.Score + Score;
       
   148 
       
   149                     // if not between shots, activate invulnerability/vampirism if available
       
   150                     if CurrentHedgehog^.MultiShootAttacks = 0 then
       
   151                         begin
       
   152                         if HHHasAmmo(Me^.Hedgehog^, amInvulnerable) > 0 then
       
   153                             begin
       
   154                             AddAction(BestActions, aia_Weapon, Longword(amInvulnerable), 80, 0, 0);
       
   155                             AddAction(BestActions, aia_attack, aim_push, 10, 0, 0);
       
   156                             AddAction(BestActions, aia_attack, aim_release, 10, 0, 0);
       
   157                             end;
       
   158 
       
   159                         if HHHasAmmo(Me^.Hedgehog^, amExtraDamage) > 0 then
       
   160                             begin
       
   161                             AddAction(BestActions, aia_Weapon, Longword(amExtraDamage), 80, 0, 0);
       
   162                             AddAction(BestActions, aia_attack, aim_push, 10, 0, 0);
       
   163                             AddAction(BestActions, aia_attack, aim_release, 10, 0, 0);
       
   164                             end;
       
   165                         end;
   137 
   166 
   138                     AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
   167                     AddAction(BestActions, aia_Weapon, Longword(a), 300 + random(400), 0, 0);
   139 
   168 
   140                     if (ap.Angle > 0) then
   169                     if (ap.Angle > 0) then
   141                         AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
   170                         AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
   249 // switch to 'skip' if we cannot move because of mouse cursor being shown
   278 // switch to 'skip' if we cannot move because of mouse cursor being shown
   250 if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   279 if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   251     AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
   280     AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
   252 
   281 
   253 if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0))
   282 if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0))
   254     and (GameFlags and gfArtillery = 0) then
   283     and (GameFlags and gfArtillery = 0) and (cGravityf <> 0) then
   255     begin
   284     begin
   256     tmp:= random(2) + 1;
   285     tmp:= random(2) + 1;
   257     Push(0, Actions, Me^, tmp);
   286     Push(0, Actions, Me^, tmp);
   258     Push(0, Actions, Me^, tmp xor 3);
   287     Push(0, Actions, Me^, tmp xor 3);
   259 
   288 
   357 
   386 
   358                 end;
   387                 end;
   359 
   388 
   360             if GoInfo.FallPix >= FallPixForBranching then
   389             if GoInfo.FallPix >= FallPixForBranching then
   361                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   390                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
       
   391 
       
   392             if (StartTicks > GameTicks - 1500) and (not StopThinking) then
       
   393                 SDL_Delay(1000);
       
   394 
   362             end {while};
   395             end {while};
   363 
   396 
   364         if BestRate > BaseRate then
   397         if BestRate > BaseRate then
   365             exit
   398             exit
   366         end {while}
   399         end {while}
   368 end;
   401 end;
   369 
   402 
   370 function Think(Me: PGear): LongInt; cdecl; export;
   403 function Think(Me: PGear): LongInt; cdecl; export;
   371 var BackMe, WalkMe: TGear;
   404 var BackMe, WalkMe: TGear;
   372     switchCount: LongInt;
   405     switchCount: LongInt;
   373     StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
   406     currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
   374     switchImmediatelyAvailable: boolean;
   407     switchImmediatelyAvailable: boolean;
   375     Actions: TActions;
   408     Actions: TActions;
   376 begin
   409 begin
   377 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   410 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   378 StartTicks:= GameTicks;
   411 StartTicks:= GameTicks;
       
   412 
   379 currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
   413 currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
   380 itHedgehog:= currHedgehogIndex;
   414 itHedgehog:= currHedgehogIndex;
   381 switchesNum:= 0;
   415 switchesNum:= 0;
   382 
   416 
   383 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
   417 switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
   384 if Me^.Hedgehog^.BotLevel <> 5 then
   418 if Me^.Hedgehog^.BotLevel <> 5 then
   385     switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch)
   419     switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch)
   386 else switchCount:= 0;
   420 else switchCount:= 0;
   387 
   421 
   388 if ((Me^.State and gstAttacked) = 0) or isInMultiShoot then
   422 if ((Me^.State and gstAttacked) = 0) or isInMultiShoot or bonuses.activity then
   389     if Targets.Count > 0 then
   423     if Targets.Count > 0 then
   390         begin
   424         begin
   391         // iterate over current team hedgehogs
   425         // iterate over current team hedgehogs
   392         repeat
   426         repeat
   393             WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^;
   427             WalkMe:= CurrentTeam^.Hedgehogs[itHedgehog].Gear^;
   395             Actions.Count:= 0;
   429             Actions.Count:= 0;
   396             Actions.Pos:= 0;
   430             Actions.Pos:= 0;
   397             Actions.Score:= 0;
   431             Actions.Score:= 0;
   398             if switchesNum > 0 then
   432             if switchesNum > 0 then
   399                 begin
   433                 begin
   400                 if not switchImmediatelyAvailable  then
   434                 if (not switchImmediatelyAvailable)  then
   401                     begin
   435                     begin
   402                     // when AI has to use switcher, make it cost smth unless they have a lot of switches
   436                     // when AI has to use switcher, make it cost smth unless they have a lot of switches
   403                     if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
   437                     if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
   404                     AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);
   438                     AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);
   405                     AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
   439                     AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
   419         until (not (switchImmediatelyAvailable or (switchCount > 0)))
   453         until (not (switchImmediatelyAvailable or (switchCount > 0)))
   420             or StopThinking
   454             or StopThinking
   421             or (itHedgehog = currHedgehogIndex)
   455             or (itHedgehog = currHedgehogIndex)
   422             or BestActions.isWalkingToABetterPlace;
   456             or BestActions.isWalkingToABetterPlace;
   423 
   457 
   424         if (StartTicks > GameTicks - 1500) and (not StopThinking) then
   458             if (StartTicks > GameTicks - 1500) and (not StopThinking) then
   425             SDL_Delay(1000);
   459                 SDL_Delay(700);
   426 
   460 
   427         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
   461         if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then
   428             begin
   462             begin
   429             BestActions.Count:= 0;
   463             BestActions.Count:= 0;
   430             AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   464 
       
   465             FillBonuses(false);
       
   466 
       
   467             if not bonuses.activity then
       
   468                 AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
   431             end;
   469             end;
   432 
   470 
   433         end else SDL_Delay(100)
   471         end else SDL_Delay(100)
   434 else
   472 else
   435     begin
   473     begin
   436     BackMe:= Me^;
   474     BackMe:= Me^;
   437     i:= 12;
   475     i:= 4;
   438     while (not StopThinking) and (BestActions.Count = 0) and (i > 0) do
   476     while (not StopThinking) and (BestActions.Count = 0) and (i > 0) do
   439         begin
   477         begin
       
   478 
   440 (*
   479 (*
   441         // 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
   480         // 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
   442         if SuddenDeathDmg and ((hwRound(BackMe.Y)+cWaterRise*2) > cWaterLine) then
   481         if SuddenDeathDmg and ((hwRound(BackMe.Y)+cWaterRise*2) > cWaterLine) then
   443             AddBonus(hwRound(BackMe.X), hwRound(BackMe.Y), 250, -40);
   482             AddBonus(hwRound(BackMe.X), hwRound(BackMe.Y), 250, -40);
   444 *)
   483 *)
       
   484 
   445         FillBonuses(true);
   485         FillBonuses(true);
   446         WalkMe:= BackMe;
   486         WalkMe:= BackMe;
   447         Actions.Count:= 0;
   487         Actions.Count:= 0;
   448         Actions.Pos:= 0;
   488         Actions.Pos:= 0;
   449         Actions.Score:= 0;
   489         Actions.Score:= 0;
   450         Walk(@WalkMe, Actions);
   490         Walk(@WalkMe, Actions);
   451         dec(i);
   491         if not bonuses.activity then dec(i);
   452         if not StopThinking then
   492         if not StopThinking then
   453             SDL_Delay(100)
   493             SDL_Delay(100)
   454         end
   494         end
   455     end;
   495     end;
   456 
   496