bool TryPreDodgeProjectile() { const int preTicks = 18; var opp = OpponentWizards .OrderBy(x => x.GetDistanceTo2(ASelf)) .FirstOrDefault(x => Math.Min(x.RemainingActionCooldownTicks, x.RemainingMagicMissileCooldownTicks) <= preTicks && x.GetDistanceTo(ASelf) <= x.CastRange + ASelf.Radius + Game.MagicMissileRadius + 7 && Math.Abs(x.GetAngleTo(ASelf)) <= Game.StaffSector /* /2*/ ); if (opp == null) { return(false); } if (Math.Abs(ASelf.GetAngleTo(opp)) < Math.PI / 2 && ASelf.GetDistanceTo(opp) > 500) { var obstacles = Combats.Where(x => x.Id != Self.Id && x.GetDistanceTo(ASelf) < 300).ToArray(); var selSign = 0; double selPriority = int.MaxValue; var requiredAngle = ASelf.GetDistanceTo(opp) <= opp.CastRange + ASelf.Radius ? Math.PI - 2 * ASelf.MaxTurnAngle - 0.001 : Math.PI / 2; for (var sign = -1; sign <= 1; sign += 2) { var my = new AWizard(ASelf); var priority = 0.0; while (Math.Abs(my.GetAngleTo(opp)) < requiredAngle) { my.Angle += sign * my.MaxTurnAngle; priority += 0.1; } for (var i = 0; i < 15; i++) { if (!my.MoveTo(my + Point.ByAngle(my.Angle), null, w => !CheckIntersectionsAndTress(w, obstacles))) { break; } priority--; } if (priority < selPriority) { selPriority = priority; selSign = sign; } } FinalMove.Turn = selSign * 10; return(true); } return(false); }
bool GoAwayDetect() { if (Const.TopRightCorner.GetDistanceTo(ASelf) < 800) { return(false); } if (ASelf.GetDistanceTo(BuildingsObserver.MyBase) <= Game.FactionBaseVisionRange) { return(false); } var nearest = OpponentWizards .Where(x => ASelf.GetDistanceTo(x) < x.CastRange + ASelf.Radius + GoAwayMaxDist && GoAwayCond(ASelf, x)) .ArgMin(x => x.GetDistanceTo2(ASelf)); if (nearest != null) { return(true); } return(false); }
bool _tryDodgeProjectile() { var obstacles = Combats.Where(x => x.Id != Self.Id && x.GetDistanceTo(ASelf) < 300).ToArray(); var minTicks = int.MaxValue; var minDamage = 1000.0; Point selMoveTo = null; Point selTurnTo = null; foreach (var doTurn in new[] { false, true }) { foreach (var angle in Utility.Range(0, Math.PI * 2, 40, false)) { if (minTicks == 0 && minDamage < Const.Eps) // ничего не грозит { break; } var ticks = 0; var my = new AWizard(ASelf); var bonus = new ABonus(BonusesObserver.Bonuses.ArgMin(b => b.GetDistanceTo(Self))); var moveTo = my + Point.ByAngle(angle) * 1000; var turnTo = doTurn ? moveTo : null; var myStates = new List <AWizard> { new AWizard(my) }; while (ticks < ProjectilesCheckTicks) { var totalDamage = _getProjectilesDamage(myStates); if (Utility.Less(totalDamage, minDamage) || Utility.Equals(totalDamage, minDamage) && ticks < minTicks) { minTicks = ticks; minDamage = totalDamage; selMoveTo = moveTo; selTurnTo = turnTo; } bonus.SkipTick(); my.MoveTo(moveTo, turnTo, w => { if (CheckIntersectionsAndTress(w, obstacles)) { return(false); } if (bonus.RemainingAppearanceTicks < 15 && bonus.IntersectsWith(w)) { return(false); } return(true); }); myStates.Add(new AWizard(my)); ticks++; } } } if (minTicks == 0 || minTicks == int.MaxValue) // нет необходимости уворачиваться { return(false); } if (selTurnTo != null || Math.Abs(ASelf.GetAngleTo(selMoveTo)) < Math.PI / 2) { FinalMove.Turn = 0; } FinalMove.MoveTo(selMoveTo, selTurnTo); return(true); }