Make hogs aware of dud mines and explosives. Still a bit more needed.
--- a/hedgewars/uAIAmmoTests.pas Thu May 02 23:46:48 2013 +0400
+++ b/hedgewars/uAIAmmoTests.pas Fri May 03 07:28:08 2013 -0400
@@ -308,7 +308,7 @@
EX:= trunc(x);
EY:= trunc(y);
- value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
+ value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
// LOL copypasta: this is score for digging with... snowball
//if value = 0 then
// value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
@@ -802,10 +802,10 @@
dx:= sin(a / cMaxAngle * pi) * 0.5;
dy:= cos(a / cMaxAngle * pi) * 0.5;
- v1:= RateShove(x - 10, y + 2
+ v1:= RateShove(Me, x - 10, y + 2
, 32, 30, 115
, -dx, -dy, trackFall);
- v2:= RateShove(x + 10, y + 2
+ v2:= RateShove(Me, x + 10, y + 2
, 32, 30, 115
, dx, -dy, trackFall);
if (v1 > valueResult) or (v2 > valueResult) then
@@ -848,11 +848,11 @@
v1:= 0;
for i:= 0 to 8 do
begin
- v1:= v1 + RateShove(x - 5, y - 10 * i
+ v1:= v1 + RateShove(Me, x - 5, y - 10 * i
, 19, 30, 40
, -0.45, -0.9, trackFall or afSetSkip);
end;
- v1:= v1 + RateShove(x - 5, y - 90
+ v1:= v1 + RateShove(Me, x - 5, y - 90
, 19, 30, 40
, -0.45, -0.9, trackFall);
@@ -861,11 +861,11 @@
v2:= 0;
for i:= 0 to 8 do
begin
- v2:= v2 + RateShove(x + 5, y - 10 * i
+ v2:= v2 + RateShove(Me, x + 5, y - 10 * i
, 19, 30, 40
, 0.45, -0.9, trackFall or afSetSkip);
end;
- v2:= v2 + RateShove(x + 5, y - 90
+ v2:= v2 + RateShove(Me, x + 5, y - 90
, 19, 30, 40
, 0.45, -0.9, trackFall);
@@ -907,19 +907,19 @@
{first RateShove checks farthermost of two whip's AmmoShove attacks
to encourage distant attacks (damaged hog is excluded from view of second
RateShove call)}
- v1:= RateShove(x - 13, y
+ v1:= RateShove(Me, x - 13, y
, 30, 30, 25
, -1, -0.8, trackFall or afSetSkip);
v1:= v1 +
- RateShove(x - 2, y
+ RateShove(Me, x - 2, y
, 30, 30, 25
, -1, -0.8, trackFall);
// now try opposite direction
- v2:= RateShove(x + 13, y
+ v2:= RateShove(Me, x + 13, y
, 30, 30, 25
, 1, -0.8, trackFall or afSetSkip);
v2:= v2 +
- RateShove(x + 2, y
+ RateShove(Me, x + 2, y
, 30, 30, 25
, 1, -0.8, trackFall);
@@ -986,7 +986,7 @@
for i:= 0 to 512 div step - 2 do
begin
valueResult:= valueResult +
- RateShove(trunc(x), trunc(y)
+ RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall or afSetSkip);
@@ -998,14 +998,14 @@
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
tx:= trunc(x);
- v:= RateShove(tx, trunc(y)
+ v:= RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall);
for i:= 1 to 512 div step - 2 do
begin
y:= y + dy;
v:= v +
- RateShove(tx, trunc(y)
+ RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall or afSetSkip);
end
@@ -1016,7 +1016,7 @@
valueResult:= v
end;
- v:= RateShove(trunc(x), trunc(y)
+ v:= RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall);
valueResult:= valueResult + v - KillScore * friendlyfactor div 100 * 1024;
--- a/hedgewars/uAIMisc.pas Thu May 02 23:46:48 2013 +0400
+++ b/hedgewars/uAIMisc.pas Fri May 03 07:28:08 2013 -0400
@@ -34,10 +34,11 @@
Point: TPoint;
Score: LongInt;
skip, matters, dead: boolean;
+ Kind: TGearType;
end;
TTargets = record
Count: Longword;
- ar: array[0..Pred(cMaxHHs)] of TTarget;
+ ar: array[0..Pred(256)] of TTarget;
reset: boolean;
end;
TJumpType = (jmpNone, jmpHJump, jmpLJump);
@@ -70,9 +71,8 @@
function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
-function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
-function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; inline;
-function RealRateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
+function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
function RateHammer(Me: PGear): LongInt;
function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
@@ -114,42 +114,53 @@
procedure FillTargets;
var i, t: Longword;
f, e: LongInt;
+ iter: PGear;
begin
Targets.Count:= 0;
Targets.reset:= false;
f:= 0;
e:= 0;
-for t:= 0 to Pred(TeamsCount) do
- with TeamsArray[t]^ do
- if not hasGone then
+iter:= GearsList;
+while iter <> nil do
+ begin
+ if ((iter^.Kind = gtHedgehog) and
+ (iter <> ThinkingHH) and
+ (iter^.Health > iter^.Damage) and
+ not(iter^.Hedgehog^.Team^.hasgone)) or
+ ((iter^.Kind = gtExplosives) and
+ (iter^.Health > iter^.Damage)) or
+ ((iter^.Kind = gtMine) and
+ (iter^.Health = 0) and
+ (iter^.Damage < 35)) and
+ (Targets.Count < 256) then
+ begin
+ with Targets.ar[Targets.Count] do
begin
- for i:= 0 to cMaxHHIndex do
- if (Hedgehogs[i].Gear <> nil)
- and (Hedgehogs[i].Gear <> ThinkingHH)
- and (Hedgehogs[i].Gear^.Health > Hedgehogs[i].Gear^.Damage)
- then
- begin
- with Targets.ar[Targets.Count], Hedgehogs[i] do
- begin
- skip:= false;
- dead:= false;
- matters:= (Hedgehogs[i].Gear^.AIHints and aihDoesntMatter) = 0;
+ skip:= false;
+ dead:= false;
+ Kind:= iter^.Kind;
+ matters:= (iter^.AIHints and aihDoesntMatter) = 0;
- Point.X:= hwRound(Gear^.X);
- Point.Y:= hwRound(Gear^.Y);
- if Clan <> CurrentTeam^.Clan then
- begin
- Score:= Gear^.Health - Gear^.Damage;
- inc(e)
- end else
- begin
- Score:= Gear^.Damage - Gear^.Health;
- inc(f)
- end
- end;
- inc(Targets.Count)
- end;
+ Point.X:= hwRound(iter^.X);
+ Point.Y:= hwRound(iter^.Y);
+ if (iter^.Kind = gtHedgehog) then
+ if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then
+ begin
+ Score:= iter^.Damage - iter^.Health;
+ inc(f)
+ end
+ else
+ begin
+ Score:= iter^.Health - iter^.Damage;
+ inc(e)
+ end
+ else if iter^.Kind = gtExplosives then Score:= iter^.Health - iter^.Damage
+ else if iter^.Kind = gtMine then Score:= max(0,35-iter^.Damage)
end;
+ inc(Targets.Count)
+ end;
+ iter:= iter^.NextGear
+ end;
if e > f then friendlyfactor:= 300 + (e - f) * 30
else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
@@ -463,27 +474,42 @@
fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod)
end;
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if (dmg+fallDmg) >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or (Flags and afTrackFall)));
+ if Score > 0 then
+ inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill
+ else dec(rate, KillScore * friendlyfactor div 100 * 1024)
+ end
else
- dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
- else if (dmg+fallDmg) >= abs(Score) then
+ begin
+ if Score > 0 then
+ inc(rate, (dmg + fallDmg) * 1024)
+ else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
+ end
+ end
+// FIXME - need to make TraceFall calculate damage for barrels/mines correctly
+ else if (Kind <> gtHedgehog) and (FallDmg >= 0) and ((dmg+fallDmg) >= Score) then
begin
dead:= true;
Targets.reset:= true;
- if dX < 0.035 then
- inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or (Flags and afTrackFall)));
- if Score > 0 then
- inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill
- else
- dec(rate, KillScore * friendlyfactor div 100 * 1024)
+ if Kind = gtExplosives then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall)))
+ else inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall)))
end
- else
- if Score > 0 then
- inc(rate, (dmg + fallDmg) * 1024)
- else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
- end;
+ end
end;
if hadSkips and (rate = 0) then
@@ -492,9 +518,9 @@
RealRateExplosion:= rate;
end;
-function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
var i, fallDmg, dmg, rate: LongInt;
- dX, dY: real;
+ dX, dY, pX, pY: real;
begin
fallDmg:= 0;
dX:= gdX * 0.01 * kick;
@@ -512,35 +538,54 @@
if dmg > 0 then
begin
+ pX:= Point.x;
+ pY:= Point.y;
if (Flags and afSetSkip <> 0) then skip:= true;
if (Flags and afTrackFall <> 0) and (Score > 0) then
- fallDmg:= trunc(TraceShoveFall(Point.x, Point.y - 2, dX, dY) * dmgMod);
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
+ fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY) * dmgMod);
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if power+fallDmg >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or (Flags and afTrackFall)) div 1024);
+ if Score > 0 then
+ inc(rate, KillScore)
+ else
+ dec(rate, KillScore * friendlyfactor div 100)
+ end
else
- dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
- else if power+fallDmg >= abs(Score) then
- if Score > 0 then
- inc(rate, KillScore)
- else
- dec(rate, KillScore * friendlyfactor div 100)
- else
- if Score > 0 then
- inc(rate, power+fallDmg)
- else
- dec(rate, (power+fallDmg) * friendlyfactor div 100)
- end;
+ begin
+ if Score > 0 then
+ inc(rate, power+fallDmg)
+ else
+ dec(rate, (power+fallDmg) * friendlyfactor div 100)
+ end
+ end
+// FIXME - need to make TraceFall calculate damage for barrels/mines correctly
+ else if (Kind <> gtHedgehog) and (fallDmg >= 0) and ((power+fallDmg) >= Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if Kind = gtExplosives then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall)) div 1024)
+ else inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall)) div 1024)
+ end
+ end
end;
RateShove:= rate * 1024
end;
-function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; inline;
-begin
- RateShotgun:= RealRateShotgun(Me, gdX, gdY, x, y);
- ResetTargets;
-end;
-function RealRateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
+function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
pX, pY, dX, dY: real;
hadSkips: boolean;
@@ -589,34 +634,47 @@
(Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod);
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
- else
- dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
- else if (dmg+fallDmg) >= abs(Score) then
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if (dmg+fallDmg) >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall) div 1024);
+ if Score > 0 then
+ inc(rate, KillScore)
+ else
+ dec(rate, KillScore * friendlyfactor div 100)
+ end
+ else if Score > 0 then
+ inc(rate, dmg+fallDmg)
+ else dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
+ end
+// FIXME - need to make TraceFall calculate damage for barrels/mines correctly
+ else if (Kind <> gtHedgehog) and (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
begin
dead:= true;
Targets.reset:= true;
- if dX < 0.035 then
- inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall) div 1024);
- if Score > 0 then
- inc(rate, KillScore)
- else
- dec(rate, KillScore * friendlyfactor div 100)
+ if Kind = gtExplosives then
+ inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or afTrackFall) div 1024)
+ else inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or afTrackFall) div 1024)
end
- else
- if Score > 0 then
- inc(rate, dmg+fallDmg)
- else
- dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
- end;
+ end
end;
if hadSkips and (rate = 0) then
- RealRateShotgun:= BadTurn
+ RateShotgun:= BadTurn
else
- RealRateShotgun:= rate * 1024;
+ RateShotgun:= rate * 1024;
+ ResetTargets;
end;
function RateHammer(Me: PGear): LongInt;