--- a/hedgewars/uAIAmmoTests.pas Mon Jan 16 10:22:21 2012 +0100
+++ b/hedgewars/uAIAmmoTests.pas Tue Jan 17 09:01:31 2012 -0500
@@ -24,11 +24,11 @@
const amtest_OnTurn = $00000001;
type TAttackParams = record
- Time: Longword;
- Angle, Power: LongInt;
- ExplX, ExplY, ExplR: LongInt;
- AttackPutX, AttackPutY: LongInt;
- end;
+ Time: Longword;
+ Angle, Power: LongInt;
+ ExplX, ExplY, ExplR: LongInt;
+ AttackPutX, AttackPutY: LongInt;
+ end;
function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
@@ -137,29 +137,31 @@
ap.ExplR:= 0;
valueResult:= BadTurn;
repeat
- rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - cWindSpeedf * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
- r:= sqrt(sqr(Vx) + sqr(Vy));
- if not (r > 1) then
- begin
+ rTime:= rTime + 300 + Level * 50 + random(300);
+ Vx:= - cWindSpeedf * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
+ r:= sqrt(sqr(Vx) + sqr(Vy));
+ if not (r > 1) then
+ begin
x:= mX;
y:= mY;
dX:= Vx;
dY:= -Vy;
t:= rTime;
repeat
- x:= x + dX;
- y:= y + dY;
- dX:= dX + cWindSpeedf;
- dY:= dY + cGravityf;
- dec(t)
+ x:= x + dX;
+ y:= y + dY;
+ dX:= dX + cWindSpeedf;
+ dY:= dY + cGravityf;
+ dec(t)
until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
+
EX:= trunc(x);
EY:= trunc(y);
value:= RateExplosion(Me, EX, EY, 101);
- if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
- if valueResult <= value then
+ if value = 0 then
+ value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ if valueResult <= value then
begin
ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1);
@@ -168,7 +170,7 @@
ap.ExplY:= EY;
valueResult:= value
end;
- end
+ end
until (rTime > 4250);
TestBazooka:= valueResult
end;
@@ -188,28 +190,29 @@
ap.ExplR:= 0;
valueResult:= BadTurn;
repeat
- rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime);
- Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
- begin
+ rTime:= rTime + 300 + Level * 50 + random(300);
+ Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime);
+ Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
+ r:= Distance(Vx, Vy);
+ if not (r > _1) then
+ begin
x:= Me^.X;
y:= Me^.Y;
dX:= Vx;
dY:= -Vy;
t:= rTime;
repeat
- x:= x + dX;
- y:= y + dY;
- dX:= dX + cWindSpeed;
- dY:= dY + cGravity;
- dec(t)
+ x:= x + dX;
+ y:= y + dY;
+ dX:= dX + cWindSpeed;
+ dY:= dY + cGravity;
+ dec(t)
until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
EX:= hwRound(x);
EY:= hwRound(y);
value:= RateExplosion(Me, EX, EY, 5);
- if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ if value = 0 then
+ value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
if valueResult <= value then
begin
@@ -236,26 +239,28 @@
TestTime:= 0;
ap.ExplR:= 0;
repeat
- inc(TestTime, 300);
- Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
- Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
- begin
+ inc(TestTime, 300);
+ Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
+ Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
+ r:= Distance(Vx, Vy);
+ if not (r > _1) then
+ begin
x:= Me^.X;
y:= Me^.Y;
dY:= -Vy;
t:= TestTime;
repeat
- x:= x + Vx;
- y:= y + dY;
- dY:= dY + cGravity;
- dec(t)
+ x:= x + Vx;
+ y:= y + dY;
+ dY:= dY + cGravity;
+ dec(t)
until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
EX:= hwRound(x);
EY:= hwRound(y);
- if t < 50 then Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly
- else Score:= BadTurn;
+ if t < 50 then
+ Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly
+ else
+ Score:= BadTurn;
if valueResult < Score then
begin
@@ -267,7 +272,7 @@
ap.ExplY:= EY;
valueResult:= Score
end;
- end
+ end
until (TestTime > 4250);
TestMolotov:= valueResult
end;
@@ -284,22 +289,22 @@
TestTime:= 0;
ap.ExplR:= 0;
repeat
- inc(TestTime, 1000);
- Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
- Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
- begin
- x:= Me^.X;
- y:= Me^.Y;
- dY:= -Vy;
- t:= TestTime;
- repeat
- x:= x + Vx;
- y:= y + dY;
- dY:= dY + cGravity;
- dec(t)
- until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
+ inc(TestTime, 1000);
+ Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
+ Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
+ r:= Distance(Vx, Vy);
+ if not (r > _1) then
+ begin
+ x:= Me^.X;
+ y:= Me^.Y;
+ dY:= -Vy;
+ t:= TestTime;
+ repeat
+ x:= x + Vx;
+ y:= y + dY;
+ dY:= dY + cGravity;
+ dec(t)
+ until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
EX:= hwRound(x);
EY:= hwRound(y);
if t < 50 then
@@ -334,20 +339,20 @@
TestTime:= 0;
ap.ExplR:= 0;
repeat
- inc(TestTime, 1000);
- // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
- if Me^.X<int2hwFloat(Targ.X) then
- Vx:= (int2hwFloat(Targ.X+10) - Me^.X) / int2hwFloat(TestTime + tDelta)
- else
- Vx:= (int2hwFloat(Targ.X-10) - Me^.X) / int2hwFloat(TestTime + tDelta);
- Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-150) - Me^.Y) / int2hwFloat(TestTime + tDelta);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
- begin
- x:= Me^.X;
- y:= Me^.Y;
- dY:= -Vy;
- t:= TestTime;
+ inc(TestTime, 1000);
+ // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
+ if Me^.X<int2hwFloat(Targ.X) then
+ Vx:= (int2hwFloat(Targ.X+10) - Me^.X) / int2hwFloat(TestTime + tDelta)
+ else
+ Vx:= (int2hwFloat(Targ.X-10) - Me^.X) / int2hwFloat(TestTime + tDelta);
+ Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-150) - Me^.Y) / int2hwFloat(TestTime + tDelta);
+ r:= Distance(Vx, Vy);
+ if not (r > _1) then
+ begin
+ x:= Me^.X;
+ y:= Me^.Y;
+ dY:= -Vy;
+ t:= TestTime;
repeat
x:= x + Vx;
y:= y + dY;
@@ -388,16 +393,16 @@
TestTime:= 0;
ap.ExplR:= 0;
repeat
- inc(TestTime, 1000);
- Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
- Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta);
- r:= Distance(Vx, Vy);
- if not (r > _1) then
- begin
- x:= Me^.X;
- y:= Me^.Y;
- dY:= -Vy;
- t:= TestTime;
+ inc(TestTime, 1000);
+ Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
+ Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta);
+ r:= Distance(Vx, Vy);
+ if not (r > _1) then
+ begin
+ x:= Me^.X;
+ y:= Me^.Y;
+ dY:= -Vy;
+ t:= TestTime;
repeat
x:= x + Vx;
y:= y + dY;
@@ -443,7 +448,9 @@
else
T:= _0;
Solve:= hwRound(T)
- end else Solve:= 0
+ end
+ else
+ Solve:= 0
end;
function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
@@ -456,11 +463,13 @@
valueResult:= BadTurn;
ap.ExplR:= 0;
-if (Level > 2) then exit(BadTurn);
+if (Level > 2) then
+ exit(BadTurn);
TestTime:= Solve(Targ.X, Targ.Y, hwRound(Me^.X), hwRound(Me^.Y));
-if TestTime = 0 then exit(BadTurn);
+if TestTime = 0 then
+ exit(BadTurn);
Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
@@ -485,7 +494,8 @@
Score:= - abs(Targ.Y - EY) div 32
else
Score:= BadTurn
- else if (Score < 0) then Score:= BadTurn
+ else if (Score < 0) then
+ Score:= BadTurn
end
else
Score:= BadTurn;
@@ -505,8 +515,8 @@
function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
const
- MIN_RANGE = 80;
- MAX_RANGE = 400;
+ MIN_RANGE = 80;
+ MAX_RANGE = 400;
var Vx, Vy, x, y: hwFloat;
rx, ry, valueResult: LongInt;
range: integer;
@@ -517,27 +527,28 @@
x:= Me^.X;
y:= Me^.Y;
range:= Metric(hwRound(x), hwRound(y), Targ.X, Targ.Y);
-if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then exit(BadTurn);
+if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then
+ exit(BadTurn);
Vx:= (int2hwFloat(Targ.X) - x) * _1div1024;
Vy:= (int2hwFloat(Targ.Y) - y) * _1div1024;
ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
repeat
- x:= x + vX;
- y:= y + vY;
- rx:= hwRound(x);
- ry:= hwRound(y);
- if TestCollExcludingMe(Me, rx, ry, 2) then
- begin
- x:= x + vX * 8;
- y:= y + vY * 8;
- valueResult:= RateShotgun(Me, rx, ry);
+ x:= x + vX;
+ y:= y + vY;
+ rx:= hwRound(x);
+ ry:= hwRound(y);
+ if TestCollExcludingMe(Me, rx, ry, 2) then
+ begin
+ x:= x + vX * 8;
+ y:= y + vY * 8;
+ valueResult:= RateShotgun(Me, rx, ry);
- if valueResult = 0 then
+ if valueResult = 0 then
valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64
- else
+ else
dec(valueResult, Level * 4000);
- exit(valueResult * 27 div 20) // 27/20 is reuse bonus
- end
+ exit(valueResult * 27 div 20) // 27/20 is reuse bonus
+ end
until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4)
or (x.isNegative)
or (y.isNegative)
@@ -567,10 +578,11 @@
d:= 0;
repeat
- x:= x + vX;
- y:= y + vY;
- if ((hwRound(x) and LAND_WIDTH_MASK) = 0)and((hwRound(y) and LAND_HEIGHT_MASK) = 0)
- and (Land[hwRound(y), hwRound(x)] <> 0) then inc(d);
+ x:= x + vX;
+ y:= y + vY;
+ if ((hwRound(x) and LAND_WIDTH_MASK) = 0)and((hwRound(y) and LAND_HEIGHT_MASK) = 0)
+ and (Land[hwRound(y), hwRound(x)] <> 0) then
+ inc(d);
until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4)
or (x.isNegative)
or (y.isNegative)
@@ -578,8 +590,10 @@
or (y.Round > LongWord(LAND_HEIGHT))
or (d > 200);
-if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then valueResult:= Max(0, (4 - d div 50) * 7 * 1024)
- else valueResult:= BadTurn;
+if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then
+ valueResult:= Max(0, (4 - d div 50) * 7 * 1024)
+else
+ valueResult:= BadTurn;
TestDesertEagle:= valueResult
end;
@@ -590,16 +604,21 @@
Level:= Level; // avoid compiler hint
ap.ExplR:= 0;
if (Level > 2) or (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 25) then
- exit(BadTurn);
+ exit(BadTurn);
ap.Time:= 0;
ap.Power:= 1;
x:= Me^.X;
y:= Me^.Y;
-if (Targ.X) - hwRound(x) >= 0 then ap.Angle:= cMaxAngle div 4
- else ap.Angle:= - cMaxAngle div 4;
+if (Targ.X) - hwRound(x) >= 0 then
+ ap.Angle:= cMaxAngle div 4
+else
+ ap.Angle:= - cMaxAngle div 4;
valueResult:= RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x), hwRound(y), 15, 30);
-if valueResult <= 0 then valueResult:= BadTurn else inc(valueResult);
+if valueResult <= 0 then
+ valueResult:= BadTurn
+else
+ inc(valueResult);
TestBaseballBat:= valueResult;
end;
@@ -648,9 +667,10 @@
if (Abs(hwRound(Me^.X) + hwSign(Me^.dX) * 10 - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 20) then
rate:= 0
- else
+else
rate:= RateHammer(Me);
-if rate = 0 then rate:= BadTurn;
+if rate = 0 then
+ rate:= BadTurn;
TestHammer:= rate;
end;
@@ -664,7 +684,8 @@
begin
ap.ExplR:= 0;
ap.Time:= 0;
-if (Level > 3) then exit(BadTurn);
+if (Level > 3) then
+ exit(BadTurn);
ap.AttackPutX:= Targ.X;
ap.AttackPutY:= Targ.Y;
@@ -682,22 +703,22 @@
valueResult:= 0;
repeat
- X:= X + cBombsSpeed;
- Y:= Y + dY;
- dY:= dY + cGravity;
- fexit:= true;
+ X:= X + cBombsSpeed;
+ Y:= Y + dY;
+ dY:= dY + cGravity;
+ fexit:= true;
- for i:= 0 to 9 do
- if b[i] then
- begin
- fexit:= false;
- if TestColl(hwRound(X) + i * 30, hwRound(Y), 4) then
- begin
- b[i]:= false;
- dmg[i]:= RateExplosion(Me, hwRound(X) + i * 30, hwRound(Y), 58)
- // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets)
- end
- end;
+ for i:= 0 to 9 do
+ if b[i] then
+ begin
+ fexit:= false;
+ if TestColl(hwRound(X) + i * 30, hwRound(Y), 4) then
+ begin
+ b[i]:= false;
+ dmg[i]:= RateExplosion(Me, hwRound(X) + i * 30, hwRound(Y), 58)
+ // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets)
+ end
+ end;
until fexit or (Y.Round > cWaterLine);
for i:= 0 to 5 do inc(valueResult, dmg[i]);
@@ -709,13 +730,14 @@
dec(t, dmg[i]);
inc(t, dmg[i + 6]);
if t > valueResult then
- begin
- valueResult:= t;
- ap.AttackPutX:= Targ.X - 30 - cShift + i * 30
- end
+ begin
+ valueResult:= t;
+ ap.AttackPutX:= Targ.X - 30 - cShift + i * 30
+ end
end;
-if valueResult <= 0 then valueResult:= BadTurn;
+if valueResult <= 0 then
+ valueResult:= BadTurn;
TestAirAttack:= valueResult;
end;
@@ -728,30 +750,38 @@
TestTeleport := BadTurn;
Level:= Level; // avoid compiler hint
FillBonuses(true, [gtCase]);
- if bonuses.Count = 0 then begin
- if Me^.Health <= 100 then begin
+ if bonuses.Count = 0 then
+ begin
+ if Me^.Health <= 100 then
+ begin
maxTop := Targ.Y - cHHRadius * 2;
+
while not TestColl(Targ.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do
- dec(maxTop, cHHRadius*2);
- if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then begin
+ dec(maxTop, cHHRadius*2);
+ if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then
+ begin
ap.AttackPutX := Targ.X;
ap.AttackPutY := maxTop + cHHRadius;
TestTeleport := Targ.Y - maxTop;
+ end;
end;
- end;
- end
- else begin
+ end
+ else
+ begin
failNum := 0;
repeat
i := random(bonuses.Count);
inc(failNum);
- until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius) or (failNum = bonuses.Count*2);
- if failNum < bonuses.Count*2 then begin
+ until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius)
+ or (failNum = bonuses.Count*2);
+
+ if failNum < bonuses.Count*2 then
+ begin
ap.AttackPutX := bonuses.ar[i].X;
ap.AttackPutY := bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius;
TestTeleport := 0;
+ end;
end;
- end;
end;
end.