# HG changeset patch # User Wuzzy # Date 1593060275 -7200 # Node ID 21dece8f55fe3d63c93323536f70ce03f104ca1b # Parent 0bf5dda8fa435ca8477edfbfd631edb4538354b4 Teach AI how to deal with gfMoreWind diff -r 0bf5dda8fa43 -r 21dece8f55fe ChangeLog.txt --- a/ChangeLog.txt Wed Jun 24 22:34:12 2020 +0300 +++ b/ChangeLog.txt Thu Jun 25 06:44:35 2020 +0200 @@ -11,6 +11,7 @@ + - use RC plane (very basic) + - drop mines from a cliff + Low level computer players are more inaccurate with guns + + Computer player now takes Strong Wind game modifier into account + Various small computer player improvements + New taunt chat commands: /bubble, /happy * Fix many projectiles not being affected by Heavy Wind after turn end diff -r 0bf5dda8fa43 -r 21dece8f55fe hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Wed Jun 24 22:34:12 2020 +0300 +++ b/hedgewars/uAIAmmoTests.pas Thu Jun 25 06:44:35 2020 +0200 @@ -571,6 +571,7 @@ function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const timeLimit = 50; + Density : real = 2.0; var Vx, Vy, r, meX, meY: real; rTime: LongInt; EX, EY: LongInt; @@ -596,6 +597,8 @@ Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime else Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime; + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx; Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime; r:= sqr(Vx) + sqr(Vy); @@ -609,6 +612,8 @@ repeat x:= CheckWrap(x); x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; @@ -654,10 +659,11 @@ function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const tDelta = 24; + Density : real = 1.5; var Vx, Vy, r: real; Score, EX, EY, valueResult: LongInt; TestTime: LongInt; - targXWrap, x, y, meX, meY, dY: real; + targXWrap, x, y, meX, meY, dX, dY: real; t: LongInt; begin valueResult:= BadTurn; @@ -674,18 +680,24 @@ inc(TestTime, 1000); if (WorldEdge = weWrap) and (random(2)=0) then Vx:= (targXWrap + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta) - else Vx:= (Targ.Point.X + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta); + else + Vx:= (Targ.Point.X + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta); + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * (TestTime + tDelta) * 0.5 + Vx; Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta); r:= sqr(Vx) + sqr(Vy); if not (r > 1) then begin x:= meX; y:= meY; + dX:= Vx; dY:= -Vy; t:= TestTime; repeat x:= CheckWrap(x); - x:= x + Vx; + x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; dec(t) @@ -718,10 +730,11 @@ function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const tDelta = 24; + Density : real = 1.5; var Vx, Vy, r: real; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - x, y, dY, meX, meY: real; + x, y, dX, dY, meX, meY: real; t: LongInt; begin Flags:= Flags; // avoid compiler hint @@ -733,8 +746,10 @@ meY:= hwFloat2Float(Me^.Y); repeat inc(TestTime, 900); + if (GameFlags and gfMoreWind) <> 0 then + Vx:= (-(windSpeed / Density) * (TestTime + tDelta) * 0.5) + ((Targ.Point.X - meX) / (TestTime + tDelta)) // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster - if meX 1) then begin x:= meX; + dX:= Vx; y:= meY; dY:= -Vy; t:= TestTime; repeat - x:= x + Vx; + x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; dec(t) @@ -777,10 +795,11 @@ function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const tDelta = 24; + Density : real = 2.0; var Vx, Vy, r: real; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - targXWrap, x, y, dY, meX, meY: real; + targXWrap, x, y, dX, dY, meX, meY: real; t: LongInt; begin Flags:= Flags; // avoid compiler hint @@ -796,19 +815,26 @@ repeat inc(TestTime, 900); if (WorldEdge = weWrap) and (random(2)=0) then - Vx:= (targXWrap - meX) / (TestTime + tDelta) - else Vx:= (Targ.Point.X - meX) / (TestTime + tDelta); + Vx:= (targXWrap - meX) / (TestTime + tDelta) + else + Vx:= (Targ.Point.X - meX) / (TestTime + tDelta); + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * (TestTime + tDelta) * 0.5 + Vx; + Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta); r:= sqr(Vx)+sqr(Vy); if not (r > 1) then begin x:= meX; + dX:= Vx; y:= meY; dY:= -Vy; t:= TestTime; repeat x:= CheckWrap(x); - x:= x + Vx; + x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; dec(t) @@ -860,11 +886,11 @@ end; function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; -//const tDelta = 24; +const Density : real = 1.0; var Vx, Vy: real; Score, EX, EY: LongInt; TestTime: Longword; - x, y, dY, meX, meY: real; + x, y, dX, dY, meX, meY: real; begin Flags:= Flags; // avoid compiler hint TestMortar:= BadTurn; @@ -882,14 +908,19 @@ exit(BadTurn); Vx:= (Targ.Point.X - meX) / TestTime; + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * TestTime * 0.5 + Vx; Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime; x:= meX; + dX:= Vx; y:= meY; dY:= -Vy; repeat - x:= x + Vx; + x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; EX:= trunc(x); @@ -1361,7 +1392,8 @@ function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const cShift = 4; -var bombsSpeed, X, Y, dY: real; + Density : real = 2.0; +var bombsSpeed, X, Y, dX, dY: real; b: array[0..9] of boolean; dmg: array[0..9] of LongInt; fexit: boolean; @@ -1381,6 +1413,7 @@ X:= Targ.Point.X - 135 - cShift; // hh center - cShift X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf); Y:= -128; +dX:= bombsSpeed; dY:= 0; for i:= 0 to 9 do @@ -1391,7 +1424,9 @@ valueResult:= 0; repeat - X:= X + bombsSpeed; + X:= X + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; Y:= Y + dY; dY:= dY + cGravityf; fexit:= true; @@ -1443,7 +1478,8 @@ begin Flags:= Flags; // avoid compiler hint ap.ExplR:= 0; -if (Level > 3) or (cGravityf = 0) then +// TODO: Add support for More Wind +if (Level > 3) or (cGravityf = 0) or ((GameFlags and gfMoreWind) <> 0) then exit(BadTurn); ap.Angle:= 0; @@ -1571,7 +1607,8 @@ function TestMineStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const cShift = 4; -var minesSpeed, X, Y, dY: real; + Density : real = 1.0; +var minesSpeed, X, Y, dX, dY: real; b: array[0..9] of boolean; dmg: array[0..9] of LongInt; fexit: boolean; @@ -1598,6 +1635,7 @@ X:= Targ.Point.X - 135 - cShift; // hh center - cShift X:= X - minesSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf); Y:= -128; +dX:= minesSpeed; dY:= 0; for i:= 0 to 9 do @@ -1608,7 +1646,9 @@ valueResult:= 0; repeat - X:= X + minesSpeed; + X:= X + dX; + if (GameFlags and (gfMoreWind or gfInfAttack)) <> 0 then + dX:= dX + windSpeed / Density; Y:= Y + dY; dY:= dY + cGravityf; fexit:= true; @@ -1650,6 +1690,7 @@ function TestSMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const timeLimit = 50; + Density : real = 1.6; var Vx, Vy, r, meX, meY: real; rTime: LongInt; EX, EY: LongInt; @@ -1675,6 +1716,8 @@ Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime else Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime; + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx; Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime; r:= sqr(Vx) + sqr(Vy); @@ -1688,6 +1731,8 @@ repeat x:= CheckWrap(x); x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf; @@ -1932,6 +1977,7 @@ end; function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +const Density : real = 2.0; var valueResult: LongInt; x, y, dx, dy: real; EX, EY, t: LongInt; @@ -1942,10 +1988,14 @@ x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7; y:= hwFloat2Float(Me^.Y); dx:= hwSign(Me^.dX) * 0.03; +if (GameFlags and gfMoreWind) <> 0 then + dx:= -(windSpeed / Density) + dx; dy:= 0; t:= 5000; repeat dec(t); + if (GameFlags and gfMoreWind) <> 0 then + dx:= dx + windSpeed / Density; x:= x + dx; dy:= dy + cGravityf; y:= y + dy; @@ -1977,6 +2027,7 @@ end; function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; +const Density : real = 1.0; var valueResult: LongInt; x, y, dx, dy: real; EX, EY, t: LongInt; @@ -1987,10 +2038,14 @@ x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7; y:= hwFloat2Float(Me^.Y); dx:= hwSign(Me^.dX) * 0.02; +if (GameFlags and gfMoreWind) <> 0 then + dx:= -(windSpeed / Density) + dx; dy:= 0; t:= 10000; repeat dec(t); + if (GameFlags and gfMoreWind) <> 0 then + dx:= dx + windSpeed / Density; x:= x + dx; dy:= dy + cGravityf; y:= y + dy; @@ -2028,6 +2083,7 @@ function TestKnife(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt; const timeLimit = 300; + Density : real = 4.0; var Vx, Vy, r, meX, meY: real; rTime: LongInt; EX, EY: LongInt; @@ -2054,6 +2110,8 @@ Vx:= (targXWrap - meX) / rTime else Vx:= (Targ.Point.X - meX) / rTime; + if (GameFlags and gfMoreWind) <> 0 then + Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx; Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime; r:= sqr(Vx) + sqr(Vy); @@ -2067,6 +2125,8 @@ repeat x:= CheckWrap(x); x:= x + dX; + if (GameFlags and gfMoreWind) <> 0 then + dX:= dX + windSpeed / Density; y:= y + dY; dY:= dY + cGravityf;