Bots know shotgun behavior better
authorunc0rr
Mon, 07 May 2007 20:21:26 +0000
changeset 509 fd58135a4407
parent 508 f5473c50adbd
child 510 4e994e1b7abb
Bots know shotgun behavior better
hedgewars/uAI.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
hedgewars/uConsts.pas
hedgewars/uGears.pas
--- a/hedgewars/uAI.pas	Sun May 06 20:50:53 2007 +0000
+++ b/hedgewars/uAI.pas	Mon May 07 20:21:26 2007 +0000
@@ -25,22 +25,24 @@
 
 implementation
 uses uTeams, uConsts, SDLh, uAIMisc, uGears, uAIAmmoTests, uAIActions, uMisc,
-     uAmmos, uConsole, uCollisions{$IFDEF UNIX}, cthreads{$ENDIF};
+     uAmmos, uConsole, uCollisions, SysUtils{$IFDEF UNIX}, cthreads{$ENDIF};
 
 var BestActions: TActions;
-    ThinkThread: THandle = 0;
+    CanUseAmmo: array [TAmmoType] of boolean;
     StopThinking: boolean;
-    CanUseAmmo: array [TAmmoType] of boolean;
-
+    ThinkThread: THandle;
+    hasThread: LongInt = 0;
+    
 procedure FreeActionsList;
 begin
 {$IFDEF DEBUGFILE}AddFileLog('FreeActionsList called');{$ENDIF}
-if ThinkThread <> 0 then
+if hasThread <> 0 then
    begin
    {$IFDEF DEBUGFILE}AddFileLog('Waiting AI thread to finish');{$ENDIF}
    StopThinking:= true;
-   WaitForThreadTerminate(ThinkThread, 5000);
-   ThinkThread:= 0
+   repeat
+     SDL_Delay(10)
+   until hasThread = 0
    end;
 
 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
@@ -64,7 +66,7 @@
 BotLevel:= PHedgehog(Me^.Hedgehog)^.BotLevel;
 
 for i:= 0 to Pred(Targets.Count) do
-    if (Targets.ar[i].Score >= 0) then
+    if (Targets.ar[i].Score >= 0) and (not StopThinking) then
        begin
        with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
             a:= Ammo^[CurSlot, CurAmmo].AmmoType;
@@ -103,7 +105,9 @@
            end;
         if a = High(TAmmoType) then a:= Low(TAmmoType)
                                else inc(a)
-       until (a = aa) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].AttacksNum > 0)
+       until (a = aa) or
+             (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].AttacksNum > 0) or
+             StopThinking
        end
 end;
 
@@ -241,15 +245,14 @@
 var BackMe, WalkMe: TGear;
     StartTicks: Longword;
 begin
+InterlockedIncrement(hasThread);
 StartTicks:= GameTicks;
-BestActions.Count:= 0;
-BestActions.Pos:= 0;
-BestActions.Score:= Low(integer);
 BackMe:= PGear(Me)^;
-WalkMe:= BackMe;
+
 if (PGear(Me)^.State and gstAttacked) = 0 then
    if Targets.Count > 0 then
       begin
+      WalkMe:= BackMe;
       Walk(@WalkMe);
       if (StartTicks > GameTicks - 1500) and not StopThinking then SDL_Delay(2000);
       if BestActions.Score < -1023 then
@@ -259,17 +262,17 @@
          end;
       end else
 else begin
-      Walk(@WalkMe);
       while (not StopThinking) and (BestActions.Count = 0) do
             begin
-            SDL_Delay(100);
             FillBonuses(true);
             WalkMe:= BackMe;
-            Walk(@WalkMe)
+            Walk(@WalkMe);
+            if not StopThinking then SDL_Delay(100)
             end
       end;
 PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking;
-Think:= 0
+Think:= 0;
+InterlockedDecrement(hasThread)
 end;
 
 procedure StartThink(Me: PGear);
@@ -281,8 +284,14 @@
 DeleteCI(Me); // don't let collision info in Land to confuse AI
 Me^.State:= Me^.State or gstHHThinking;
 Me^.Message:= 0;
+
+BestActions.Count:= 0;
+BestActions.Pos:= 0;
+BestActions.Score:= Low(integer);
+
 StopThinking:= false;
 ThinkingHH:= Me;
+
 FillTargets;
 if Targets.Count = 0 then
    begin
@@ -298,19 +307,21 @@
 
 procedure ProcessBot;
 const StartTicks: Longword = 0;
+      cStopThinkTime = 40;
 begin
 with CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog] do
      if (Gear <> nil)
         and ((Gear^.State and gstHHDriven) <> 0)
         and (TurnTimeLeft < cHedgehogTurnTime - 50) then
         if ((Gear^.State and gstHHThinking) = 0) then
-           if (BestActions.Pos >= BestActions.Count) then
+           if (BestActions.Pos >= BestActions.Count)
+              and (TurnTimeLeft > cStopThinkTime) then
               begin
               StartThink(Gear);
               StartTicks:= GameTicks
               end else ProcessAction(BestActions, Gear)
-        else if (GameTicks - StartTicks) > cMaxAIThinkTime then StopThinking:= true
+        else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
+                or (TurnTimeLeft <= cStopThinkTime) then StopThinking:= true
 end;
 
-
 end.
--- a/hedgewars/uAIAmmoTests.pas	Sun May 06 20:50:53 2007 +0000
+++ b/hedgewars/uAIAmmoTests.pas	Mon May 07 20:21:26 2007 +0000
@@ -192,7 +192,9 @@
   ry:= hwRound(y);
   if TestColl(rx, ry, 2) then
      begin
-     Result:= RateShove(Me, rx, ry, 25, 25) * 2;
+     x:= x + vX * 8;
+     y:= y + vY * 8;
+     Result:= RateShotgun(Me, rx, ry) * 2;
      if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, rx, ry) div 64
                    else dec(Result, Level * 4000);
      exit(Result)
--- a/hedgewars/uAIMisc.pas	Sun May 06 20:50:53 2007 +0000
+++ b/hedgewars/uAIMisc.pas	Mon May 07 20:21:26 2007 +0000
@@ -43,6 +43,7 @@
 function TestColl(x, y, r: LongInt): boolean;
 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt;
 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt;
+function RateShotgun(Me: PGear; x, y: LongInt): LongInt;
 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
 function AIrndSign(num: LongInt): LongInt;
 
@@ -184,7 +185,7 @@
          if dmg > 0 then
             begin
             dmg:= dmg shr 1;
-            if dmg > abs(Score) then
+            if dmg >= abs(Score) then
                if Score > 0 then inc(Result, KillScore)
                             else dec(Result, KillScore * 3)
             else
@@ -205,7 +206,7 @@
          dmg:= r - hwRound(DistanceI(Point.x - x, Point.y - y));
          if dmg > 0 then
             begin
-            if power > abs(Score) then
+            if power >= abs(Score) then
                if Score > 0 then inc(Result, KillScore)
                             else dec(Result, KillScore * 3)
             else
@@ -216,6 +217,35 @@
 RateShove:= Result * 1024
 end;
 
+function RateShotgun(Me: PGear; x, y: LongInt): LongInt;
+var i, dmg, Result: LongInt;
+begin
+Result:= 0;
+// add our virtual position
+with Targets.ar[Targets.Count] do
+     begin
+     Point.x:= hwRound(Me^.X);
+     Point.y:= hwRound(Me^.Y);
+     Score:= - ThinkingHH^.Health
+     end;
+// rate shot
+for i:= 0 to Targets.Count do
+    with Targets.ar[i] do
+         begin
+         dmg:= min(cHHRadius + cShotgunRadius - hwRound(DistanceI(Point.x - x, Point.y - y)), 25);
+         if dmg > 0 then
+            begin
+            if dmg >= abs(Score) then
+               if Score > 0 then inc(Result, KillScore)
+                            else dec(Result, KillScore * 3)
+            else
+               if Score > 0 then inc(Result, dmg)
+                            else dec(Result, dmg * 3)
+            end;
+         end;
+RateShotgun:= Result * 1024
+end;
+
 function HHJump(Gear: PGear; JumpType: TJumpType; var GoInfo: TGoInfo): boolean;
 var bX, bY: LongInt;
     Result: boolean;
--- a/hedgewars/uConsts.pas	Sun May 06 20:50:53 2007 +0000
+++ b/hedgewars/uConsts.pas	Mon May 07 20:21:26 2007 +0000
@@ -121,9 +121,12 @@
 
       cHHRadius = 9;
       cHHStepTicks = 38;
+
       cHHZ = 1000;
       cCurrHHZ = Succ(cHHZ);
 
+      cShotgunRadius = 22;
+
       cKeyMaxIndex = 1023;
 
       cMaxCaptions = 4;
--- a/hedgewars/uGears.pas	Sun May 06 20:50:53 2007 +0000
+++ b/hedgewars/uGears.pas	Mon May 07 20:21:26 2007 +0000
@@ -700,7 +700,7 @@
 var t: PGear;
     dmg: integer;
 begin
-Gear^.Radius:= 22;
+Gear^.Radius:= cShotgunRadius;
 t:= GearsList;
 while t <> nil do
     begin
@@ -725,7 +725,7 @@
            end;
     t:= t^.NextGear
     end;
-DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 22)
+DrawExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), cShotgunRadius)
 end;
 
 procedure AmmoShove(Ammo: PGear; Damage, Power: LongInt);