# HG changeset patch # User nemo # Date 1547487287 18000 # Node ID 8736f3a0ff7f76e65217794a6c4fbd51b9bfc18f # Parent 5e4df5413e1eb93d27cf2cc3a8058740e85174db ai improvements are release branch safe diff -r 5e4df5413e1e -r 8736f3a0ff7f hedgewars/uAI.pas --- a/hedgewars/uAI.pas Fri Jan 11 08:45:11 2019 -0500 +++ b/hedgewars/uAI.pas Mon Jan 14 12:34:47 2019 -0500 @@ -66,7 +66,6 @@ const cBranchStackSize = 12; type TStackEntry = record - WastedTicks: Longword; MadeActions: TActions; Hedgehog: TGear; end; @@ -76,14 +75,13 @@ States: array[0..Pred(cBranchStackSize)] of TStackEntry; end; -function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean; +function Push(const Actions: TActions; const Me: TGear; Dir: integer): boolean; var bRes: boolean; begin bRes:= (Stack.Count < cBranchStackSize) and (Actions.Count < MAXACTIONS - 5); if bRes then with Stack.States[Stack.Count] do begin - WastedTicks:= Ticks; MadeActions:= Actions; Hedgehog:= Me; Hedgehog.Message:= Dir; @@ -92,12 +90,11 @@ Push:= bRes end; -procedure Pop(var Ticks: Longword; var Actions: TActions; var Me: TGear); +procedure Pop(var Actions: TActions; var Me: TGear); begin dec(Stack.Count); with Stack.States[Stack.Count] do begin - Ticks:= WastedTicks; Actions:= MadeActions; Me:= Hedgehog end @@ -253,15 +250,16 @@ procedure Walk(Me: PGear; var Actions: TActions); const FallPixForBranching = cHHRadius; var - ticks, maxticks, oldticks, steps, tmp: Longword; + maxticks, oldticks, steps, tmp: Longword; BaseRate, BestRate, Rate: LongInt; GoInfo: TGoInfo; CanGo: boolean; AltMe: TGear; BotLevel: Byte; a: TAmmoType; + isAfterAttack: boolean; begin -ticks:= 0; +Actions.ticks:= 0; oldticks:= 0; // avoid compiler hint Stack.Count:= 0; @@ -272,12 +270,13 @@ BotLevel:= Me^.Hedgehog^.BotLevel; -if (Me^.State and gstAttacked) = 0 then - maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel)) +isAfterAttack:= ((Me^.State and gstAttacked) <> 0) and ((GameFlags and gfInfAttack) = 0); +if isAfterAttack then + maxticks:= Max(0, TurnTimeLeft - 500) else - maxticks:= TurnTimeLeft; + maxticks:= Max(0, TurnTimeLeft - 5000 - LongWord(4000 * BotLevel)); -if (Me^.State and gstAttacked) = 0 then +if not isAfterAttack then TestAmmos(Actions, Me, false); BestRate:= RatePlace(Me); @@ -291,12 +290,12 @@ and (CurrentHedgehog^.Effects[heArtillery] = 0) and (cGravityf <> 0) then begin tmp:= random(2) + 1; - Push(0, Actions, Me^, tmp); - Push(0, Actions, Me^, tmp xor 3); + Push(Actions, Me^, tmp); + Push(Actions, Me^, tmp xor 3); while (Stack.Count > 0) and (not StopThinking) do begin - Pop(ticks, Actions, Me^); + Pop(Actions, Me^); AddAction(Actions, Me^.Message, aim_push, 250, 0, 0); if (Me^.Message and gmLeft) <> 0 then @@ -311,10 +310,25 @@ {$HINTS OFF} CanGo:= HHGo(Me, @AltMe, GoInfo); {$HINTS ON} - oldticks:= ticks; - inc(ticks, GoInfo.Ticks); - if ticks > maxticks then + oldticks:= Actions.ticks; + inc(Actions.ticks, GoInfo.Ticks); + if (Actions.ticks > maxticks) or (TurnTimeLeft < BestActions.ticks + 5000) then + begin + if (BotLevel < 5) + and (not isAfterAttack) + and (BestActions.Score > 0) // we have a good move + and (TurnTimeLeft < BestActions.ticks + 5000) // we won't have a lot of time after attack + and (HHHasAmmo(Me^.Hedgehog^, amExtraTime) > 0) // but can use extra time + then + begin + BestActions.Count:= 0; + AddAction(BestActions, aia_Weapon, Longword(amExtraTime), 80, 0, 0); + AddAction(BestActions, aia_attack, aim_push, 10, 0, 0); + AddAction(BestActions, aia_attack, aim_release, 10, 0, 0); + end; + break; + end; if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) @@ -323,7 +337,7 @@ begin // check if we could go backwards and maybe ljump over a gap after this hjump addMark(hwRound(Me^.X), hwRound(Me^.Y), markHJumped); - if Push(ticks, Actions, AltMe, Me^.Message xor 3) then + if Push(Actions, AltMe, Me^.Message xor 3) then begin with Stack.States[Pred(Stack.Count)] do begin @@ -336,7 +350,7 @@ AddAction(MadeActions, aia_HJump, 0, 350, 0, 0); end; // but first check walking forward - Push(ticks, Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message) + Push(Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message) end; end; if (BotLevel < 3) @@ -346,7 +360,7 @@ begin addMark(hwRound(Me^.X), hwRound(Me^.Y), markLJumped); // at final check where we go after jump walking backward - if Push(ticks, Actions, AltMe, Me^.Message xor 3) then + if Push(Actions, AltMe, Me^.Message xor 3) then with Stack.States[Pred(Stack.Count)] do begin if (Me^.Message and gmLeft) <> 0 then @@ -358,12 +372,13 @@ end; // push current position so we proceed from it after checking jump+forward walk opportunities - if CanGo then Push(ticks, Actions, Me^, Me^.Message); + if CanGo then Push(Actions, Me^, Me^.Message); // first check where we go after jump walking forward - if Push(ticks, Actions, AltMe, Me^.Message) then + if Push(Actions, AltMe, Me^.Message) then with Stack.States[Pred(Stack.Count)] do AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); + break end; @@ -379,27 +394,22 @@ BestActions:= Actions; BestActions.isWalkingToABetterPlace:= true; BestRate:= Rate; - Me^.State:= Me^.State or gstAttacked // we have better place, go there and do not use ammo + isAfterAttack:= true // we have better place, go there and do not use ammo end else if Rate < BestRate then break; - if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then + if (not isAfterAttack) and ((steps mod 4) = 0) then begin if (steps > 4) and checkMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere) then break; addMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere); - TestAmmos(Actions, Me, ticks shr 12 = oldticks shr 12); - + TestAmmos(Actions, Me, Actions.ticks shr 12 = oldticks shr 12); end; if GoInfo.FallPix >= FallPixForBranching then - Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right - - if (StartTicks > GameTicks - 1500) and (not StopThinking) then - SDL_Delay(1000); - + Push(Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right end {while}; if BestRate > BaseRate then @@ -463,8 +473,8 @@ or (itHedgehog = currHedgehogIndex) or BestActions.isWalkingToABetterPlace; - if (StartTicks > GameTicks - 1500) and (not StopThinking) then - SDL_Delay(700); + if (StartTicks > GameTicks - 1500) and (not StopThinking) then + SDL_Delay(700); if (BestActions.Score < -1023) and (not BestActions.isWalkingToABetterPlace) then begin @@ -544,7 +554,7 @@ exit end; -FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot)); +FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot) and ((GameFlags and gfInfAttack) = 0)); SDL_LockMutex(ThreadLock); ThinkThread:= SDL_CreateThread(@Think, PChar('think'), Me); @@ -561,7 +571,7 @@ with CurrentHedgehog^ do if (Gear <> nil) and ((Gear^.State and gstHHDriven) <> 0) - and (TurnTimeLeft < cHedgehogTurnTime - 50) then + and ((TurnTimeLeft < cHedgehogTurnTime - 50) or (TurnTimeLeft > cHedgehogTurnTime)) then if ((Gear^.State and gstHHThinking) = 0) then if (BestActions.Pos >= BestActions.Count) and (TurnTimeLeft > cStopThinkTime) then diff -r 5e4df5413e1e -r 8736f3a0ff7f hedgewars/uAIActions.pas --- a/hedgewars/uAIActions.pas Fri Jan 11 08:45:11 2019 -0500 +++ b/hedgewars/uAIActions.pas Mon Jan 14 12:34:47 2019 -0500 @@ -58,6 +58,7 @@ TActions = record Count, Pos: Longword; + ticks: Longword; actions: array[0..Pred(MAXACTIONS)] of TAction; Score: LongInt; isWalkingToABetterPlace: boolean; diff -r 5e4df5413e1e -r 8736f3a0ff7f hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Fri Jan 11 08:45:11 2019 -0500 +++ b/hedgewars/uAIAmmoTests.pas Mon Jan 14 12:34:47 2019 -0500 @@ -1135,7 +1135,7 @@ if d < 10 then begin dx:= 0; - dy:= 8; + dy:= step; ap.Angle:= 2048 end else @@ -1149,17 +1149,18 @@ if dx >= 0 then cx:= 0.45 else cx:= -0.45; - for i:= 0 to 512 div step - 2 do + for i:= 1 to 512 div step - 2 do begin + x:= x + dx; + y:= y + dy; + valueResult:= valueResult + RateShove(Me, trunc(x), trunc(y) , 30, 30, 25 , cx, -0.9, trackFall or afSetSkip); + end; - x:= x + dx; - y:= y + dy; - end; - if dx = 0 then + if (d < 10) and (dx = 0) then begin x:= hwFloat2Float(Me^.X); y:= hwFloat2Float(Me^.Y); @@ -1176,8 +1177,10 @@ , -cx, -0.9, trackFall or afSetSkip); end end; + if v > valueResult then - begin + begin + cx:= -cx; ap.Angle:= -2048; valueResult:= v end; diff -r 5e4df5413e1e -r 8736f3a0ff7f hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Fri Jan 11 08:45:11 2019 -0500 +++ b/hedgewars/uAIMisc.pas Mon Jan 14 12:34:47 2019 -0500 @@ -229,6 +229,7 @@ , gtAirBomb , gtCluster , gtMelonPiece + , gtBee , gtMolotov: bonuses.activity:= true; gtCase: if (Gear^.AIHints and aihDoesntMatter) = 0 then @@ -246,6 +247,7 @@ else if (Gear^.State and gstAttacking) <> 0 then AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, -50); // mine is on end; + gtAirMine: if ((Gear^.State and gstFrozen) = 0) then AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), gear^.Angle+5, -30); gtExplosives: begin