Implement bot levels
authorunc0rr
Sun, 03 Sep 2006 15:26:52 +0000
changeset 136 89970b70b076
parent 135 53faa20669de
child 137 bcab861a3262
Implement bot levels
hedgewars/uAI.pas
hedgewars/uAIAmmoTests.pas
hedgewars/uAIMisc.pas
hedgewars/uRandom.pas
--- a/hedgewars/uAI.pas	Sun Sep 03 14:34:08 2006 +0000
+++ b/hedgewars/uAI.pas	Sun Sep 03 15:26:52 2006 +0000
@@ -58,11 +58,13 @@
 end;
 
 procedure TestAmmos(var Actions: TActions; Me: PGear);
-var Time: Longword;
+var Time, BotLevel: Longword;
     Angle, Power, Score, ExplX, ExplY, ExplR: integer;
     i: integer;
     a, aa: TAmmoType;
 begin
+BotLevel:= PHedgehog(Me.Hedgehog).BotLevel;
+
 for i:= 0 to Pred(Targets.Count) do
     if (Targets.ar[i].Score >= 0) then
        begin
@@ -72,11 +74,11 @@
        repeat
         if CanUseAmmo[a] then
            begin
-           Score:= AmmoTests[a](Me, Targets.ar[i].Point, Time, Angle, Power, ExplX, ExplY, ExplR);
+           Score:= AmmoTests[a](Me, Targets.ar[i].Point, BotLevel, Time, Angle, Power, ExplX, ExplY, ExplR);
            if Actions.Score + Score + Targets.ar[i].Score > BestActions.Score then
               begin
               BestActions:= Actions;
-              inc(BestActions.Score, Score + Targets.ar[i].Score);
+              inc(BestActions.Score, 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)
@@ -162,7 +164,7 @@
 
 
 var Actions: TActions;
-    ticks, maxticks, steps: Longword;
+    ticks, maxticks, steps, BotLevel: Longword;
     BaseRate, BestRate, Rate: integer;
     GoInfo: TGoInfo;
     CanGo: boolean;
@@ -172,11 +174,12 @@
 Actions.Pos:= 0;
 Actions.Score:= 0;
 Stack.Count:= 0;
+BotLevel:= PHedgehog(Me.Hedgehog).BotLevel;
 
 Push(0, Actions, Me^, aia_Left);
 Push(0, Actions, Me^, aia_Right);
 
-if (Me.State and gstAttacked) = 0 then maxticks:= max(0, integer(TurnTimeLeft) - 10000)
+if (Me.State and gstAttacked) = 0 then maxticks:= max(0, TurnTimeLeft - 5000 - 4000 * BotLevel)
                                   else maxticks:= TurnTimeLeft;
 
 if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me);
@@ -196,14 +199,14 @@
        CanGo:= HHGo(Me, @AltMe, GoInfo);
        inc(ticks, GoInfo.Ticks);
        if ticks > maxticks then break;
-       if GoInfo.JumpType = jmpHJump then // hjump support
+       if (BotLevel < 5) and (GoInfo.JumpType = jmpHJump) then // hjump support
           if Push(ticks, Actions, AltMe, Me^.Message) then
              with Stack.States[Pred(Stack.Count)] do
                   begin
                   AddAction(MadeActions, aia_HJump, 0, 305);
                   AddAction(MadeActions, aia_HJump, 0, 350);
                   end;
-       if GoInfo.JumpType = jmpLJump then // ljump support
+       if (BotLevel < 3) and (GoInfo.JumpType = jmpLJump) then // ljump support
           if Push(ticks, Actions, AltMe, Me^.Message) then
              with Stack.States[Pred(Stack.Count)] do
                   AddAction(MadeActions, aia_LJump, 0, 305);
--- a/hedgewars/uAIAmmoTests.pas	Sun Sep 03 14:34:08 2006 +0000
+++ b/hedgewars/uAIAmmoTests.pas	Sun Sep 03 15:26:52 2006 +0000
@@ -35,14 +35,14 @@
 interface
 uses SDLh, uGears, uConsts;
 
-function TestBazooka(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
-function TestGrenade(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
-function TestShotgun(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
-function TestDesertEagle(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
-function TestBaseballBat(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
-function TestFirePunch(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestBazooka(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestGrenade(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestShotgun(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestDesertEagle(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestBaseballBat(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestFirePunch(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 
-type TAmmoTestProc = function (Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 const AmmoTests: array[TAmmoType] of TAmmoTestProc =
                  (
 {amGrenade}       TestGrenade,
@@ -69,7 +69,7 @@
 Result:= abs(x1 - x2) + abs(y1 - y2)
 end;
 
-function TestBazooka(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestBazooka(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 var Vx, Vy, r: Double;
     rTime: Double;
     Score, EX, EY: integer;
@@ -102,7 +102,7 @@
 ExplR:= 0;
 Result:= BadTurn;
 repeat
-  rTime:= rTime + 150 + random*250;
+  rTime:= rTime + 150 + Level * 25 + random * 250;
   Vx:= - cWindSpeed * rTime / 2 + (Targ.X - Me.X) / rTime;
   Vy:= cGravity * rTime / 2 - (Targ.Y - Me.Y) / rTime;
   r:= sqr(Vx) + sqr(Vy);
@@ -112,18 +112,18 @@
      if Result <= Score then
         begin
         r:= sqrt(r);
-        Angle:= DxDy2AttackAngle(Vx, Vy);
-        Power:= round(r * cMaxPower);
+        Angle:= DxDy2AttackAngle(Vx, Vy) + rndSign(random((Level - 1) * 8) + 1);
+        Power:= round(r * cMaxPower) - random((Level - 1) * 15 + 1);
         ExplR:= 100;
         ExplX:= EX;
         ExplY:= EY;
-        Result:= Score
+        Result:= Score - random((Level - 1) * 2500)
         end;
      end
 until (rTime >= 4500)
 end;
 
-function TestGrenade(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestGrenade(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 const tDelta = 24;
 var Vx, Vy, r: Double;
     Score, EX, EY: integer;
@@ -164,8 +164,8 @@
      if Result < Score then
         begin
         r:= sqrt(r);
-        Angle:= DxDy2AttackAngle(Vx, Vy);
-        Power:= round(r * cMaxPower);
+        Angle:= DxDy2AttackAngle(Vx, Vy) + rndSign(random(Level));
+        Power:= round(r * cMaxPower) + rndSign(random(Level) * 12);
         Time:= TestTime;
         ExplR:= 100;
         ExplX:= EX;
@@ -176,9 +176,9 @@
 until (TestTime = 5000)
 end;
 
-function TestShotgun(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestShotgun(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 var Vx, Vy, x, y: Double;
-begin
+begin       
 ExplR:= 0;
 if Metric(round(Me.X), round(Me.Y), Targ.X, Targ.Y) < 80 then
    begin
@@ -197,7 +197,7 @@
   y:= y + vY;
   if TestColl(round(x), round(y), 2) then
      begin
-     Result:= RateShove(Me, round(x), round(y), 25, 25);
+     Result:= RateShove(Me, round(x), round(y), 25, 25) * 2 - Level * 4000;
      if Result = 0 then Result:= - Metric(Targ.X, Targ.Y, round(x), round(y)) div 64;
      exit
      end
@@ -205,7 +205,7 @@
 Result:= BadTurn
 end;
 
-function TestDesertEagle(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestDesertEagle(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 var Vx, Vy, x, y, t: Double;
     d: Longword;
 begin
@@ -234,10 +234,10 @@
                                          else Result:= Low(integer)
 end;
 
-function TestBaseballBat(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestBaseballBat(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 begin
 ExplR:= 0;
-if abs(Me.X - Targ.X) + abs(Me.Y - Targ.Y) >= 25 then
+if (Level < 2) and (abs(Me.X - Targ.X) + abs(Me.Y - Targ.Y) >= 25) then
    begin
    Result:= BadTurn;
    exit
@@ -248,7 +248,7 @@
 Result:= RateShove(Me, round(Me.X) + 10 * hwSign(Targ.X - Me.X), round(Me.Y), 15, 30)
 end;
 
-function TestFirePunch(Me: PGear; Targ: TPoint; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
+function TestFirePunch(Me: PGear; Targ: TPoint; Level: Integer; out Time: Longword; out Angle, Power: integer; out ExplX, ExplY, ExplR: integer): integer;
 var i: integer;
 begin
 ExplR:= 0;
--- a/hedgewars/uAIMisc.pas	Sun Sep 03 14:34:08 2006 +0000
+++ b/hedgewars/uAIMisc.pas	Sun Sep 03 15:26:52 2006 +0000
@@ -59,6 +59,7 @@
 function RateExplosion(Me: PGear; x, y, r: integer): integer;
 function RateShove(Me: PGear; x, y, r, power: integer): integer;
 function HHGo(Gear, AltGear: PGear; out GoInfo: TGoInfo): boolean;
+function rndSign(num: integer): integer;
 
 var ThinkingHH: PGear;
     Targets: TTargets;
@@ -401,4 +402,10 @@
 HHJump(AltGear, jmpHJump, GoInfo)
 end;
 
+function rndSign(num: integer): integer;
+begin
+if random(2) = 0 then Result:=   num
+                 else Result:= - num
+end;
+
 end.
--- a/hedgewars/uRandom.pas	Sun Sep 03 14:34:08 2006 +0000
+++ b/hedgewars/uRandom.pas	Sun Sep 03 15:26:52 2006 +0000
@@ -1,6 +1,6 @@
 (*
  * Hedgewars, a worms-like game
- * Copyright (c) 2004, 2005 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2006 Andrey Korotaev <unC0Rr@gmail.com>
  *
  * Distributed under the terms of the BSD-modified licence:
  *
@@ -50,6 +50,7 @@
            (cirbuf[(n + 40) and $3F] +           {n - 24 mod 64}
             cirbuf[(n +  9) and $3F])            {n - 55 mod 64}
             and $7FFFFFFF;                       {mod 2^31}
+
 Result:= cirbuf[n]
 end;