# HG changeset patch # User Wuzzy # Date 1593992782 -7200 # Node ID 78e383fff6050033c6df5e5d6345291e693fbbfa # Parent c7fe94d56d6e201cc22398730c466a5003d9f394 Teach AI how to use resurrector diff -r c7fe94d56d6e -r 78e383fff605 ChangeLog.txt --- a/ChangeLog.txt Mon Jul 06 00:25:13 2020 +0200 +++ b/ChangeLog.txt Mon Jul 06 01:46:22 2020 +0200 @@ -6,7 +6,7 @@ + Easier to push hogs around with blowtorch + Backjumps are now a bit easier + Teach computer players how to ... - + - use drill strike, piano strike, air mine, cleaver, seduction, laser sight + + - use drill strike, piano strike, air mine, cleaver, seduction, resurrector, laser sight + - use mine strike (0 seconds only) + - use RC plane (very basic) + - drop mines from a cliff diff -r c7fe94d56d6e -r 78e383fff605 hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Mon Jul 06 00:25:13 2020 +0200 +++ b/hedgewars/uAIAmmoTests.pas Mon Jul 06 01:46:22 2020 +0200 @@ -64,6 +64,7 @@ function TestPiano(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +function TestResurrector(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestSeduction(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; @@ -130,7 +131,7 @@ (proc: nil; flags: 0), // amFlamethrower (proc: @TestSMine; flags: 0), // amSMine (proc: @TestHammer; flags: amtest_NoTarget or amtest_NoInvulnerable), // amHammer - (proc: nil; flags: 0), // amResurrector + (proc: @TestResurrector; flags: amtest_NoTarget or amtest_NoInvulnerable or amtest_NoVampiric), // amResurrector (proc: @TestDrillStrike; flags: amtest_Rare), // amDrillStrike (proc: nil; flags: 0), // amSnowball (proc: nil; flags: 0), // amTardis @@ -1487,6 +1488,40 @@ TestAirAttack:= valueResult; end; +function TestResurrector(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +var rate, heal: LongInt; +begin +Flags:= Flags; // avoid compiler hint +Targ:= Targ; + +if (Level = 5) then + exit(BadTurn); + +if (Me^.Health <= 1) then + exit(BadTurn); + +if (Level <= 2) and (Me^.Hedgehog^.Effects[hePoisoned] > 0) then + // Sacrifice almost all health if poisoned + heal:= Me^.Health - 1 +else + // Sacrifice up to 10% of own health + heal:= (Me^.Health div 10); + +ap.ExplR:= 0; +ap.Time:= 0; +if (GameFlags and gfInfAttack) = 0 then + ap.Power:= max(min(500 * heal - 500, 10000), 10) +else + // Shorter attack duration in inf attack because the clock is ticking! + ap.Power:= max(min(500 * heal - 500, 3000), 10); +ap.Angle:= 0; + +rate:= RateResurrector(Me); +if rate <= 0 then + rate:= BadTurn; +TestResurrector:= rate; +end; + function TestDrillStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const cShift = 4; Density : real = 1.0; diff -r c7fe94d56d6e -r 78e383fff605 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Mon Jul 06 00:25:13 2020 +0200 +++ b/hedgewars/uAIMisc.pas Mon Jul 06 01:46:22 2020 +0200 @@ -88,6 +88,7 @@ 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 RateSeduction(Me: PGear): LongInt; +function RateResurrector(Me: PGear): LongInt; function RateHammer(Me: PGear): LongInt; function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; @@ -102,6 +103,7 @@ walkbonuses: Twalkbonuses; const KillScore = 200; + ResurrectScore = 100; var friendlyfactor: LongInt = 300; var dmgMod: real = 1.0; @@ -137,6 +139,8 @@ (Gear <> ThinkingHH) and (Gear^.Health > Gear^.Damage) and (not Gear^.Hedgehog^.Team^.hasgone)) or + ((Gear^.Kind = gtGrave) and + (Gear^.Health = 0)) or ((Gear^.Kind = gtExplosives) and (Gear^.Health > Gear^.Damage)) or ((Gear^.Kind = gtMine) and @@ -170,6 +174,17 @@ inc(e) end; end + else if Gear^.Kind = gtGrave then + if (Gear^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then + begin + Score:= ResurrectScore; + inc(f); + end + else + begin + Score:= -ResurrectScore; + inc(e); + end else if Gear^.Kind = gtExplosives then Score:= Gear^.Health - Gear^.Damage else if Gear^.Kind = gtMine then @@ -923,6 +938,45 @@ RateSeduction:= rate * 1024; end; +function RateResurrector(Me: PGear): LongInt; +var i, r, rate, pX, pY: LongInt; + meX, meY: hwFloat; + hadSkips: boolean; +begin +meX:= Me^.X; +meY:= Me^.Y; +rate:= 0; +for i:= 0 to Targets.Count do + if (Targets.ar[i].Kind = gtGrave) and (not Targets.ar[i].dead) then + with Targets.ar[i] do + begin + pX:= Point.X; + pY:= Point.Y; + + if (not matters) then + hadSkips:= true + else if matters and (abs(pX - hwRound(meX)) + abs(pY - hwRound(meY)) < cResurrectorDist) then + begin + r:= trunc(sqrt(sqr(abs(pX - hwRound(meX)))+sqr(abs(pY - hwRound(meY))))); + if r < cResurrectorDist then + begin + if Score > 0 then + inc(rate, Score * 1024) + else + inc(rate, Score * friendlyFactor div 100 * 1024); + // a "dead" grave is a grave that we have resurrected + dead:= true; + Targets.reset:= true; + end; + end; + end; + +if hadSkips and (rate <= 0) then + RateResurrector:= BadTurn +else + RateResurrector:= rate * 1024; +end; + function RateHammer(Me: PGear): LongInt; var x, y, i, r, rate: LongInt; hadSkips: boolean;