hedgewars/uAI.pas
changeset 7197 5a9775b97c7e
parent 7178 c61cfc9eb29d
child 7204 522f165cd2e7
equal deleted inserted replaced
7195:9e6e8e5a4c2e 7197:5a9775b97c7e
   109 
   109 
   110 
   110 
   111 procedure TestAmmos(var Actions: TActions; Me: PGear; isMoved: boolean);
   111 procedure TestAmmos(var Actions: TActions; Me: PGear; isMoved: boolean);
   112 var BotLevel: Byte;
   112 var BotLevel: Byte;
   113     ap: TAttackParams;
   113     ap: TAttackParams;
   114     Score, i: LongInt;
   114     Score, i, dAngle: LongInt;
   115     a, aa: TAmmoType;
   115     a, aa: TAmmoType;
   116 begin
   116 begin
   117 BotLevel:= Me^.Hedgehog^.BotLevel;
   117 BotLevel:= Me^.Hedgehog^.BotLevel;
   118 windSpeed:= hwFloat2Float(cWindSpeed);
   118 windSpeed:= hwFloat2Float(cWindSpeed);
   119 
   119 
   151                     else if (ap.Angle < 0) then
   151                     else if (ap.Angle < 0) then
   152                         AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
   152                         AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
   153                     
   153                     
   154                     if (ap.Time <> 0) then
   154                     if (ap.Time <> 0) then
   155                         AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
   155                         AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
       
   156                         
   156                     if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
   157                     if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
   157                         begin
   158                         begin
   158                         ap.Angle:= LongInt(Me^.Angle) - Abs(ap.Angle);
   159                         dAngle:= LongInt(Me^.Angle) - Abs(ap.Angle);
   159                         if ap.Angle > 0 then
   160                         if dAngle > 0 then
   160                             begin
   161                             begin
   161                             AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
   162                             AddAction(BestActions, aia_Up, aim_push, 300 + random(250), 0, 0);
   162                             AddAction(BestActions, aia_Up, aim_release, ap.Angle, 0, 0)
   163                             AddAction(BestActions, aia_Up, aim_release, dAngle, 0, 0)
   163                             end
   164                             end
   164                         else if ap.Angle < 0 then
   165                         else if dAngle < 0 then
   165                             begin
   166                             begin
   166                             AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
   167                             AddAction(BestActions, aia_Down, aim_push, 300 + random(250), 0, 0);
   167                             AddAction(BestActions, aia_Down, aim_release, -ap.Angle, 0, 0)
   168                             AddAction(BestActions, aia_Down, aim_release, -dAngle, 0, 0)
   168                             end
   169                             end
   169                         end;
   170                         end;
       
   171                         
   170                     if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   172                     if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   171                         begin
   173                         begin
   172                         AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
   174                         AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
   173                         end;
   175                         end;
   174                     if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
   176                         
       
   177                     if (Ammoz[a].Ammo.Propz and ammoprop_OscAim) <> 0 then
   175                         begin
   178                         begin
   176                         AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
   179                         AddAction(BestActions, aia_attack, aim_push, 350 + random(200), 0, 0);
   177                         AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
   180                         AddAction(BestActions, aia_attack, aim_release, 1, 0, 0);
   178                         end;
   181                         AddAction(BestActions, aia_waitAngle, ap.Angle, 250, 0, 0);
       
   182                         AddAction(BestActions, aia_attack, aim_push, 1, 0, 0);
       
   183                         AddAction(BestActions, aia_attack, aim_release, 1, 0, 0);
       
   184                         end else
       
   185                         if (Ammoz[a].Ammo.Propz and ammoprop_AttackingPut) = 0 then
       
   186                             begin
       
   187                             AddAction(BestActions, aia_attack, aim_push, 650 + random(300), 0, 0);
       
   188                             AddAction(BestActions, aia_attack, aim_release, ap.Power, 0, 0);
       
   189                             end;
       
   190                             
   179                     if ap.ExplR > 0 then
   191                     if ap.ExplR > 0 then
   180                         AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
   192                         AddAction(BestActions, aia_AwareExpl, ap.ExplR, 10, ap.ExplX, ap.ExplY);
   181                     end
   193                     end
   182             end;
   194             end;
   183         if a = High(TAmmoType) then
   195         if a = High(TAmmoType) then
   216     TestAmmos(Actions, Me, false);
   228     TestAmmos(Actions, Me, false);
   217     
   229     
   218 BestRate:= RatePlace(Me);
   230 BestRate:= RatePlace(Me);
   219 BaseRate:= Max(BestRate, 0);
   231 BaseRate:= Max(BestRate, 0);
   220 
   232 
       
   233 // switch to 'skip' if we can't move because of mouse cursor being shown
   221 if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   234 if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
   222     AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
   235     AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
   223 
       
   224 tmp:= random(2) + 1;
       
   225 Push(0, Actions, Me^, tmp);
       
   226 Push(0, Actions, Me^, tmp xor 3);
       
   227     
   236     
   228 while (Stack.Count > 0) and (not StopThinking) and (GameFlags and gfArtillery = 0) do
   237 if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0)) 
       
   238     and (GameFlags and gfArtillery = 0) then
   229     begin
   239     begin
   230     Pop(ticks, Actions, Me^);
   240     tmp:= random(2) + 1;
   231 
   241     Push(0, Actions, Me^, tmp);
   232     AddAction(Actions, Me^.Message, aim_push, 250, 0, 0);
   242     Push(0, Actions, Me^, tmp xor 3);
   233     if (Me^.Message and gmLeft) <> 0 then
       
   234         AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
       
   235     else
       
   236         AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
       
   237     
   243     
   238     steps:= 0;
   244     while (Stack.Count > 0) and (not StopThinking) do
   239 
       
   240     while (not StopThinking) do
       
   241         begin
   245         begin
   242 {$HINTS OFF}
   246         Pop(ticks, Actions, Me^);
   243         CanGo:= HHGo(Me, @AltMe, GoInfo);
   247 
   244 {$HINTS ON}
   248         AddAction(Actions, Me^.Message, aim_push, 250, 0, 0);
   245         inc(ticks, GoInfo.Ticks);
   249         if (Me^.Message and gmLeft) <> 0 then
   246         if ticks > maxticks then
   250             AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
   247             break;
   251         else
   248 
   252             AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
   249         if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
   253         
   250             if Push(ticks, Actions, AltMe, Me^.Message) then
   254         steps:= 0;
   251                 with Stack.States[Pred(Stack.Count)] do
   255 
   252                     begin
   256         while (not StopThinking) do
   253                     if Me^.dX.isNegative then
   257             begin
   254                         AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0)
   258     {$HINTS OFF}
   255                     else
   259             CanGo:= HHGo(Me, @AltMe, GoInfo);
   256                         AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0);
   260     {$HINTS ON}
       
   261             inc(ticks, GoInfo.Ticks);
       
   262             if ticks > maxticks then
       
   263                 break;
       
   264 
       
   265             if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
       
   266                 if Push(ticks, Actions, AltMe, Me^.Message) then
       
   267                     with Stack.States[Pred(Stack.Count)] do
       
   268                         begin
       
   269                         if Me^.dX.isNegative then
       
   270                             AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0)
       
   271                         else
       
   272                             AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0);
       
   273                             
       
   274                         AddAction(MadeActions, aia_HJump, 0, 305 + random(50), 0, 0);
       
   275                         AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
   257                         
   276                         
   258                     AddAction(MadeActions, aia_HJump, 0, 305 + random(50), 0, 0);
   277                         if Me^.dX.isNegative then
   259                     AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
   278                             AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
   260                     
   279                         else
   261                     if Me^.dX.isNegative then
   280                             AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
   262                         AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
   281                         end;
   263                     else
   282             if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
   264                         AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
   283                 if Push(ticks, Actions, AltMe, Me^.Message) then
   265                     end;
   284                     with Stack.States[Pred(Stack.Count)] do
   266         if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
   285                         AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
   267             if Push(ticks, Actions, AltMe, Me^.Message) then
   286 
   268                 with Stack.States[Pred(Stack.Count)] do
   287             // 'not CanGO' means we can't go straight, possible jumps are checked above
   269                     AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
   288             if not CanGo then
   270 
   289                 break;
   271         // 'not CanGO' means we can't go straight, possible jumps are checked above
   290             
   272         if not CanGo then
   291              inc(steps);
   273             break;
   292              Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
   274         
   293              Rate:= RatePlace(Me);
   275          inc(steps);
   294              if Rate > BestRate then
   276          Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
   295                 begin
   277          Rate:= RatePlace(Me);
   296                 BestActions:= Actions;
   278          if Rate > BestRate then
   297                 BestActions.isWalkingToABetterPlace:= true;
   279             begin
   298                 BestRate:= Rate;
   280             BestActions:= Actions;
   299                 Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo
   281             BestActions.isWalkingToABetterPlace:= true;
   300                 end
   282             BestRate:= Rate;
   301             else if Rate < BestRate then
   283             Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo
   302                 break;
   284             end
   303             if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then
   285         else if Rate < BestRate then
   304                 TestAmmos(Actions, Me, true);
   286             break;
   305             if GoInfo.FallPix >= FallPixForBranching then
   287         if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then
   306                 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   288             TestAmmos(Actions, Me, true);
   307             end {while};
   289         if GoInfo.FallPix >= FallPixForBranching then
   308 
   290             Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
   309         if BestRate > BaseRate then
   291         end {while};
   310             exit
   292 
       
   293     if BestRate > BaseRate then
       
   294         exit
       
   295         end {while}
   311         end {while}
       
   312     end {if}
   296 end;
   313 end;
   297 
   314 
   298 function Think(Me: Pointer): ptrint;
   315 function Think(Me: Pointer): ptrint;
   299 var BackMe, WalkMe: TGear;
   316 var BackMe, WalkMe: TGear;
   300     switchCount: LongInt;
   317     switchCount: LongInt;
   436                 StartTicks:= GameTicks
   453                 StartTicks:= GameTicks
   437                 
   454                 
   438                 end else
   455                 end else
   439                     ProcessAction(BestActions, Gear)
   456                     ProcessAction(BestActions, Gear)
   440         else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
   457         else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
   441         or (TurnTimeLeft <= cStopThinkTime) then
   458             or (TurnTimeLeft <= cStopThinkTime) then
   442             StopThinking:= true
   459                 StopThinking:= true
   443 end;
   460 end;
   444 
   461 
   445 procedure initModule;
   462 procedure initModule;
   446 begin
   463 begin
   447     hasThread:= 0;
   464     hasThread:= 0;