# HG changeset patch # User unc0rr # Date 1338540164 -14400 # Node ID fad64b97947ee19a1e738476d03184302b96bb39 # Parent 7db1e3a7422a7e440f24014c7d2aac5ae48785d6 Some brainfucking code which greatly reduces number of TestCollision* calls in hedgehog walk routine. Especially helpful to AI optimization. Also fixes some edge cases. diff -r 7db1e3a7422a -r fad64b97947e hedgewars/uAI.pas --- a/hedgewars/uAI.pas Fri Jun 01 00:19:30 2012 +0200 +++ b/hedgewars/uAI.pas Fri Jun 01 12:42:44 2012 +0400 @@ -266,9 +266,11 @@ with Stack.States[Pred(Stack.Count)] do AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0); + // 'not CanGO' means we can't go straight, possible jumps are checked above if not CanGo then break; - inc(steps); + + inc(steps); Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X); Rate:= RatePlace(Me); if Rate > BestRate then @@ -284,11 +286,11 @@ TestAmmos(Actions, Me, true); if GoInfo.FallPix >= FallPixForBranching then Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right - end; + end {while}; if BestRate > BaseRate then exit - end + end {while} end; function Think(Me: Pointer): ptrint; diff -r 7db1e3a7422a -r fad64b97947e hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Fri Jun 01 00:19:30 2012 +0200 +++ b/hedgewars/uAIMisc.pas Fri Jun 01 12:42:44 2012 +0400 @@ -129,12 +129,14 @@ procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline; begin -bonuses.ar[bonuses.Count].x:= x; -bonuses.ar[bonuses.Count].y:= y; -bonuses.ar[bonuses.Count].Radius:= r; -bonuses.ar[bonuses.Count].Score:= s; -inc(bonuses.Count); -TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) +if(bonuses.Count < MAXBONUS) then + begin + bonuses.ar[bonuses.Count].x:= x; + bonuses.ar[bonuses.Count].y:= y; + bonuses.ar[bonuses.Count].Radius:= r; + bonuses.ar[bonuses.Count].Score:= s; + inc(bonuses.Count); + end; end; procedure FillBonuses(isAfterAttack: boolean); @@ -162,7 +164,7 @@ gtExplosives: if isAfterAttack then - AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60+Gear^.Health); + AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60 + Gear^.Health); gtSMine: AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -30); @@ -210,7 +212,7 @@ r:= Radius; if abs(gX-X)+abs(gY-Y) < Radius then r:= trunc(sqrt(sqr(gX - X)+sqr(gY - Y))); - if r < 15 then + if r < 20 then inc(rate, Score * Radius) else if r < Radius then inc(rate, Score * (Radius - r)) @@ -612,114 +614,124 @@ GoInfo.Ticks:= 0; GoInfo.FallPix:= 0; GoInfo.JumpType:= jmpNone; + repeat -pX:= hwRound(Gear^.X); -pY:= hwRound(Gear^.Y); -if pY + cHHRadius >= cWaterLine then - exit(false); -if (Gear^.State and gstMoving) <> 0 then - begin - inc(GoInfo.Ticks); - Gear^.dY:= Gear^.dY + cGravity; - if Gear^.dY > _0_4 then + pX:= hwRound(Gear^.X); + pY:= hwRound(Gear^.Y); + if pY + cHHRadius >= cWaterLine then + exit(false); + + // hog is falling + if (Gear^.State and gstMoving) <> 0 then begin - Goinfo.FallPix:= 0; - HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall with damage - exit(false) - end; - Gear^.Y:= Gear^.Y + Gear^.dY; - if hwRound(Gear^.Y) > pY then - inc(GoInfo.FallPix); - if TestCollisionYwithGear(Gear, 1) <> 0 then - begin - inc(GoInfo.Ticks, 410); - Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); - Gear^.dY:= _0; - HHJump(AltGear, jmpLJump, GoInfo); // try ljump instead of fall - HHGo:= true; - exit(false) + inc(GoInfo.Ticks); + Gear^.dY:= Gear^.dY + cGravity; + if Gear^.dY > _0_4 then + begin + Goinfo.FallPix:= 0; + // try ljump instead of fall with damage + HHJump(AltGear, jmpLJump, GoInfo); + exit(false) + end; + Gear^.Y:= Gear^.Y + Gear^.dY; + if hwRound(Gear^.Y) > pY then + inc(GoInfo.FallPix); + if TestCollisionYwithGear(Gear, 1) <> 0 then + begin + inc(GoInfo.Ticks, 410); + Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); + Gear^.dY:= _0; + // try ljump instead of fall + HHJump(AltGear, jmpLJump, GoInfo); + exit(true) + end; + continue end; - continue - end; - if (Gear^.Message and gmLeft )<>0 then - Gear^.dX:= -cLittle - else - if (Gear^.Message and gmRight )<>0 then - Gear^.dX:= cLittle + + // usual walk + if (Gear^.Message and gmLeft) <> 0 then + Gear^.dX:= -cLittle else - exit(false); - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then - begin - if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if (Gear^.Message and gmRight) <> 0 then + Gear^.dX:= cLittle + else + exit(false); + + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - - if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y + _6 + end else Gear^.Y:= Gear^.Y + _5 else + end else Gear^.Y:= Gear^.Y + _4 else + end else Gear^.Y:= Gear^.Y + _3 else + end else Gear^.Y:= Gear^.Y + _2 else + end else Gear^.Y:= Gear^.Y + _1 + end; + + if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + begin + Gear^.X:= Gear^.X + int2hwFloat(hwSign(Gear^.dX)); + inc(GoInfo.Ticks, cHHStepTicks) end; - if not TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then - begin - Gear^.X:= Gear^.X + int2hwFloat(hwSign(Gear^.dX)); - inc(GoInfo.Ticks, cHHStepTicks) - end; + // too scared to reformat this part + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; + + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; + + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - // too scared to reformat this part - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; - - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y + _1; + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y + _1; - if TestCollisionYwithGear(Gear, 1) = 0 then - begin - Gear^.Y:= Gear^.Y - _6; - Gear^.dY:= _0; - Gear^.State:= Gear^.State or gstMoving + if TestCollisionYwithGear(Gear, 1) = 0 then + begin + Gear^.Y:= Gear^.Y - _6; + Gear^.dY:= _0; + Gear^.State:= Gear^.State or gstMoving + end + end + end end - end - end - end - end - end - end; -if (pX <> hwRound(Gear^.X)) and ((Gear^.State and gstMoving) = 0) then - exit(true) + end + end + end; + // we have moved for 1 px + if (pX <> hwRound(Gear^.X)) and ((Gear^.State and gstMoving) = 0) then + exit(true) until (pX = hwRound(Gear^.X)) and (pY = hwRound(Gear^.Y)) and ((Gear^.State and gstMoving) = 0); + HHJump(AltGear, jmpHJump, GoInfo); end; diff -r 7db1e3a7422a -r fad64b97947e hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Fri Jun 01 00:19:30 2012 +0200 +++ b/hedgewars/uGearsHedgehog.pas Fri Jun 01 12:42:44 2012 +0400 @@ -723,26 +723,32 @@ DeleteCI(Gear); // must be after exit!! (see previous line) Gear^.Hedgehog^.visStepPos:= (Gear^.Hedgehog^.visStepPos + 1) and 7; - if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then begin - if not (TestCollisionXwithXYShift(Gear, _0, -6, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -5, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -4, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -3, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; - if not (TestCollisionXwithXYShift(Gear, _0, -1, hwSign(Gear^.dX)) - or (TestCollisionYwithGear(Gear, -1) <> 0)) then - Gear^.Y:= Gear^.Y - _1; + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then if (TestCollisionYwithGear(Gear, -1) = 0) then + begin + Gear^.Y:= Gear^.Y - _1; + if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then + Gear^.Y:= Gear^.Y + _6 + end else Gear^.Y:= Gear^.Y + _5 else + end else Gear^.Y:= Gear^.Y + _4 else + end else Gear^.Y:= Gear^.Y + _3 else + end else Gear^.Y:= Gear^.Y + _2 else + end else Gear^.Y:= Gear^.Y + _1 end; if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) and (not TestCollisionXwithGear(Gear, hwSign(Gear^.dX))) then