Start on adding drowning bonus to bat/firepunch/whip. AI still is not smart enough to change direction when firepunching to face the water, or change the angle of the bat.
Also try to weight cost of switches based on how many switches were available.
--- a/hedgewars/uAI.pas Sun Mar 11 18:28:32 2012 -0400
+++ b/hedgewars/uAI.pas Sun Mar 11 20:12:31 2012 -0400
@@ -199,7 +199,7 @@
Stack.Count:= 0;
for a:= Low(TAmmoType) to High(TAmmoType) do
- CanUseAmmo[a]:= Assigned(AmmoTests[a].proc) and HHHasAmmo(Me^.Hedgehog^, a);
+ CanUseAmmo[a]:= Assigned(AmmoTests[a].proc) and (HHHasAmmo(Me^.Hedgehog^, a) > 0);
BotLevel:= Me^.Hedgehog^.BotLevel;
@@ -291,8 +291,8 @@
function Think(Me: Pointer): ptrint;
var BackMe, WalkMe: TGear;
- StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
- switchImmediatelyAvailable, switchAvailable: boolean;
+ StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i, switchCount: Longword;
+ switchImmediatelyAvailable: boolean;
Actions: TActions;
begin
InterlockedIncrement(hasThread);
@@ -302,7 +302,7 @@
switchesNum:= 0;
switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
-switchAvailable:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch);
+switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch);
if (PGear(Me)^.State and gstAttacked) = 0 then
if Targets.Count > 0 then
@@ -316,10 +316,10 @@
Actions.Score:= 0;
if switchesNum > 0 then
begin
- if not switchImmediatelyAvailable then
+ if not switchImmediatelyAvailable then
begin
- // when AI has to use switcher, make it cost smth
- Actions.Score:= -20000;
+ // when AI has to use switcher, make it cost smth unless they have a lot of switches
+ if (SwitchCount < 10) then Actions.Score:= (-27+SwitchCount*3)*4000;
AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);
AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
AddAction(Actions, aia_attack, aim_release, 1, 0, 0);
@@ -336,7 +336,7 @@
inc(switchesNum);
- until (not (switchImmediatelyAvailable or switchAvailable))
+ until (not (switchImmediatelyAvailable or (switchCount > 0)))
or StopThinking
or (itHedgehog = currHedgehogIndex)
or BestActions.isWalkingToABetterPlace;
--- a/hedgewars/uAIAmmoTests.pas Sun Mar 11 18:28:32 2012 -0400
+++ b/hedgewars/uAIAmmoTests.pas Sun Mar 11 20:12:31 2012 -0400
@@ -41,6 +41,7 @@
function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
@@ -66,7 +67,7 @@
(proc: @TestDesertEagle; flags: 0), // amDEagle
(proc: nil; flags: 0), // amDynamite
(proc: @TestFirePunch; flags: 0), // amFirePunch
- (proc: @TestFirePunch; flags: 0), // amWhip
+ (proc: @TestWhip; flags: 0), // amWhip
(proc: @TestBaseballBat; flags: 0), // amBaseballBat
(proc: nil; flags: 0), // amParachute
(proc: @TestAirAttack; flags: amtest_OnTurn), // amAirAttack
@@ -618,7 +619,8 @@
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);
+
+valueResult:= RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x), hwRound(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1);
if valueResult <= 0 then
valueResult:= BadTurn
else
@@ -641,7 +643,7 @@
or (Abs(hwRound(y) - 50 - Targ.Y) > 50) then
begin
if TestColl(hwRound(x), hwRound(y) - 16, 6)
- and (RateShove(Me, hwRound(x) + 10 * hwSign(Me^.dX), hwRound(y) - 40, 30, 30) = 0) then
+ and (RateShove(Me, hwRound(x) + 10 * hwSign(Me^.dX), hwRound(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1) = 0) then
valueResult:= Succ(BadTurn)
else
valueResult:= BadTurn;
@@ -651,7 +653,7 @@
valueResult:= 0;
for i:= 0 to 4 do
valueResult:= valueResult + RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x),
- hwRound(y) - 20 * i - 5, 10, 30);
+ hwRound(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1);
if valueResult <= 0 then
valueResult:= BadTurn
else
@@ -660,6 +662,40 @@
TestFirePunch:= valueResult;
end;
+function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+var i, valueResult: LongInt;
+ x, y: hwFloat;
+begin
+Level:= Level; // avoid compiler hint
+ap.ExplR:= 0;
+ap.Time:= 0;
+ap.Power:= 1;
+ap.Angle:= 0;
+x:= Me^.X;
+y:= Me^.Y;
+if (Abs(hwRound(x) - Targ.X) > 25)
+or (Abs(hwRound(y) - 50 - Targ.Y) > 50) then
+ begin
+ if TestColl(hwRound(x), hwRound(y) - 16, 6)
+ and (RateShove(Me, hwRound(x) + 10 * hwSign(Me^.dX), hwRound(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8, 1) = 0) then
+ valueResult:= Succ(BadTurn)
+ else
+ valueResult:= BadTurn;
+ exit(valueResult)
+ end;
+
+valueResult:= 0;
+for i:= 0 to 4 do
+ valueResult:= valueResult + RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x),
+ hwRound(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1);
+if valueResult <= 0 then
+ valueResult:= BadTurn
+else
+ inc(valueResult);
+
+TestWhip:= valueResult;
+end;
+
function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
var rate: LongInt;
begin
--- a/hedgewars/uAIMisc.pas Sun Mar 11 18:28:32 2012 -0400
+++ b/hedgewars/uAIMisc.pas Sun Mar 11 20:12:31 2012 -0400
@@ -54,7 +54,7 @@
function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
function TestColl(x, y, r: LongInt): boolean; inline;
function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt;
-function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
function RateShotgun(Me: PGear; x, y: LongInt): LongInt;
function RateHammer(Me: PGear): LongInt;
function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
@@ -267,11 +267,25 @@
y:= y + dY;
dY:= dY + cGravityf;
skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
+ // consider adding dX/dY calc here for fall damage
if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false);
if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true);
end;
end;
+function TraceShoveDrown(Me: PGear; x, y, dX, dY: Real): boolean;
+begin
+ while true do
+ begin
+ x:= x + dX;
+ y:= y + dY;
+ dY:= dY + cGravityf;
+ // consider adding dX/dY calc here for fall damage
+ if TestCollExcludingMe(Me, trunc(x), trunc(y), cHHRadius) then exit(false);
+ if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true);
+ end;
+end;
+
// Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure.
function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt;
var i, dmg, dmgBase, rate, erasure: LongInt;
@@ -305,9 +319,7 @@
end;
if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then
if Score > 0 then
- begin
inc(rate, KillScore)
- end
else
dec(rate, KillScore * friendlyfactor div 100)
else if dmg >= abs(Score) then
@@ -325,19 +337,32 @@
RateExplosion:= rate * 1024;
end;
-function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
var i, dmg, rate: LongInt;
+ dX, dY: real;
begin
Me:= Me; // avoid compiler hint
rate:= 0;
for i:= 0 to Pred(Targets.Count) do
with Targets.ar[i] do
begin
- dmg:= r - hwRound(DistanceI(Point.x - x, Point.y - y));
+ dmg:= 0;
+ if abs(Point.x - x) + abs(Point.y - y) < r then
+ dmg:= r - hwRound(DistanceI(Point.x - x, Point.y - y));
dmg:= hwRound(_0_01 * cDamageModifier * dmg * cDamagePercent);
if dmg > 0 then
begin
- if power >= abs(Score) then
+ if Flags and 1 <> 0 then
+ begin
+ dX:= gdX * 0.005 * kick;
+ dY:= gdY * 0.005 * kick;
+ end;
+ if (Flags and 1 <> 0) and TraceShoveDrown(Me, Point.x, Point.y, dX, dY) then
+ if Score > 0 then
+ inc(rate, KillScore)
+ else
+ dec(rate, KillScore * friendlyfactor div 100)
+ else if power >= abs(Score) then
if Score > 0 then
inc(rate, KillScore)
else
--- a/hedgewars/uAmmos.pas Sun Mar 11 18:28:32 2012 -0400
+++ b/hedgewars/uAmmos.pas Sun Mar 11 20:12:31 2012 -0400
@@ -33,7 +33,7 @@
procedure AssignStores;
procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType);
procedure AddAmmo(var Hedgehog: THedgehog; ammo: TAmmoType; cnt: LongWord);
-function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): boolean;
+function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): LongWord;
procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt);
procedure OnUsedAmmo(var Hedgehog: THedgehog);
procedure ApplyAngleBounds(var Hedgehog: THedgehog; AmmoType: TAmmoType);
@@ -277,7 +277,7 @@
end;
end;
-function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): boolean;
+function HHHasAmmo(var Hedgehog: THedgehog; Ammo: TAmmoType): LongWord;
var slot, ami: LongInt;
begin
Slot:= Ammoz[Ammo].Slot;
@@ -286,10 +286,12 @@
begin
with Hedgehog.Ammo^[Slot, ami] do
if (AmmoType = Ammo) then
- exit((Count > 0) and (Hedgehog.Team^.Clan^.TurnNumber > Ammoz[AmmoType].SkipTurns));
+ if Hedgehog.Team^.Clan^.TurnNumber > Ammoz[AmmoType].SkipTurns then
+ exit(Count)
+ else exit(0);
inc(ami)
end;
-HHHasAmmo:= false
+HHHasAmmo:= 0
end;
procedure ApplyAngleBounds(var Hedgehog: THedgehog; AmmoType: TAmmoType);