diff -r 8c4c6ad6ca99 -r 9643d75baf1e hedgewars/uAI.pas --- a/hedgewars/uAI.pas Tue Jun 20 20:08:17 2006 +0000 +++ b/hedgewars/uAI.pas Tue Jun 20 21:18:49 2006 +0000 @@ -40,75 +40,139 @@ implementation uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc; -var Targets: TTargets; - Actions, BestActions: TActions; +var BestActions: TActions; + ThinkThread: PSDL_Thread = nil; + StopThinking: boolean; procedure FreeActionsList; begin +if ThinkThread <> nil then + begin + StopThinking:= true; + SDL_WaitThread(ThinkThread, nil); + ThinkThread:= nil + end; BestActions.Count:= 0; -BestActions.Pos:= 0; +BestActions.Pos:= 0 end; -procedure TestAmmos(Me: PGear); -var MyPoint: TPoint; - Time: Longword; +procedure TestAmmos(var Actions: TActions; Me: PGear); +var Time: Longword; Angle, Power, Score: integer; i: integer; + a, aa: TAmmoType; begin -Mypoint.x:= round(Me.X); -Mypoint.y:= round(Me.Y); for i:= 0 to Pred(Targets.Count) do - begin - Score:= TestBazooka(MyPoint, Targets.ar[i].Point, Time, Angle, Power); - if Actions.Score + Score + Targets.ar[i].Score > BestActions.Score then - begin - BestActions:= Actions; - inc(BestActions.Score, Score + Targets.ar[i].Score); - AddAction(BestActions, aia_Weapon, Longword(amBazooka), 500); - if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200) - else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200); - Angle:= integer(Me.Angle) - Abs(Angle); - if Angle > 0 then - begin - AddAction(BestActions, aia_Up, aim_push, 500); - AddAction(BestActions, aia_Up, aim_release, Angle) - end else if Angle < 0 then - begin - AddAction(BestActions, aia_Down, aim_push, 500); - AddAction(BestActions, aia_Down, aim_release, -Angle) - end; - AddAction(BestActions, aia_attack, aim_push, 300); - AddAction(BestActions, aia_attack, aim_release, Power); - end - end + if Targets.ar[i].Score >= 0 then + begin + a:= Low(TAmmoType); + aa:= a; + repeat + if Assigned(AmmoTests[a]) then + begin + Score:= AmmoTests[a](Me, Targets.ar[i].Point, Time, Angle, Power); + if Actions.Score + Score + Targets.ar[i].Score > BestActions.Score then + begin + BestActions:= Actions; + inc(BestActions.Score, Score + Targets.ar[i].Score); + AddAction(BestActions, aia_Weapon, Longword(a), 500); + if Time <> 0 then AddAction(BestActions, aia_Timer, Time div 1000, 400); + if (Angle > 0) then AddAction(BestActions, aia_LookRight, 0, 200) + else if (Angle < 0) then AddAction(BestActions, aia_LookLeft, 0, 200); + Angle:= integer(Me.Angle) - Abs(Angle); + if Angle > 0 then + begin + AddAction(BestActions, aia_Up, aim_push, 500); + AddAction(BestActions, aia_Up, aim_release, Angle) + end else if Angle < 0 then + begin + AddAction(BestActions, aia_Down, aim_push, 500); + AddAction(BestActions, aia_Down, aim_release, -Angle) + end; + AddAction(BestActions, aia_attack, aim_push, 300); + AddAction(BestActions, aia_attack, aim_release, Power); + end + end; + if a = High(TAmmoType) then a:= Low(TAmmoType) + else inc(a) + until isInMultiShoot or (a = aa) or (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].AttacksNum > 0) + end end; procedure Walk(Me: PGear); +var Actions: TActions; + BackMe: TGear; + Dir, t, avoidt, steps: integer; begin -TestAmmos(Me) -end; - -procedure Think(Me: PGear); -begin -FillTargets(Targets); Actions.Score:= 0; Actions.Count:= 0; Actions.Pos:= 0; +BackMe:= Me^; +if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me); +avoidt:= CheckBonuses(Me); +for Dir:= aia_Left to aia_Right do + begin + Me.Message:= Dir; + steps:= 0; + while HHGo(Me) do + begin + inc(steps); + Actions.Count:= 0; + AddAction(Actions, Dir, aim_push, 50); + AddAction(Actions, aia_WaitX, round(Me.X), 0); + AddAction(Actions, Dir, aim_release, 0); + t:= CheckBonuses(Me); + if t < avoidt then break + else if (t > 0) or (t > avoidt) then + begin + BestActions:= Actions; + exit + end; + if ((Me.State and gstAttacked) = 0) + and ((steps mod 4) = 0) then TestAmmos(Actions, Me); + if StopThinking then exit; + end; + Me^:= BackMe + end +end; + +procedure Think(Me: PGear); cdecl; +var BackMe: TGear; + StartTicks: Longword; +begin +{$IFDEF DEBUGFILE}AddFileLog('Enter Think Thread');{$ENDIF} +StartTicks:= GameTicks; +ThinkingHH:= Me; +FillTargets; +FillBonuses; BestActions.Score:= Low(integer); if Targets.Count > 0 then - Walk(Me) + begin + BackMe:= Me^; + Walk(@BackMe); + end; +if StartTicks > GameTicks - 1000 then SDL_Delay(500); +Me.State:= Me.State and not gstHHThinking; +{$IFDEF DEBUGFILE}AddFileLog('Exit Think Thread');{$ENDIF} +ThinkThread:= nil +end; + +procedure StartThink(Me: PGear); +begin +Me.State:= Me.State or gstHHThinking; +StopThinking:= false; +ThinkThread:= SDL_CreateThread(@Think, Me) end; procedure ProcessBot; -var Me: PGear; begin with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do - if (Gear <> nil)and((Gear.State and gstHHDriven) <> 0) and (TurnTimeLeft < 29990) then - begin - Me:= CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].Gear; - if BestActions.Count = BestActions.Pos then Think(Me); - ProcessAction(BestActions, Me) - end + if (Gear <> nil) + and ((Gear.State and gstHHDriven) <> 0) + and (TurnTimeLeft < 29990) + and ((Gear.State and gstHHThinking) = 0) then + if (BestActions.Pos = BestActions.Count) then StartThink(Gear) + else ProcessAction(BestActions, Gear) end; end.