private ATree _getNearestTree(Point a, Point b) { var dir = b - a; for (var i = 0; i <= SegmentDivideParts; i++) { Point p = dir * (1.0 * i / SegmentDivideParts) + a; var trees = TreesObserver.GetNearestTrees(p); foreach (var tree in trees) { if (Geom.SegmentCircleIntersects(a, b, tree, tree.Radius + Const.WizardRadius + MagicConst.RadiusAdditionalEpsilon)) { return(tree); } } } return(null); }
private bool _TryGoByGradient(Func <AWizard, double> costFunction, Func <AWizard, bool> firstMoveCondition, FinalMove move) { var self = new AWizard(ASelf); var obstacles = Combats.Where(x => x.Id != Self.Id && !(x is ABuilding)).Cast <ACircularUnit>() .Concat(BuildingsObserver.Buildings) .Where(x => self.GetDistanceTo2(x) < Geom.Sqr(x.Radius + 150)) .ToArray(); var danger = costFunction(self); // for debug List <double> selVec = null; var minDanger = double.MaxValue; Point selMoveTo = null; foreach (var angle in Utility.Range(self.Angle, Math.PI * 2 + self.Angle, 24, false)) { var moveTo = self + Point.ByAngle(angle) * self.VisionRange; var nearest = Combats .Where(x => x.GetDistanceTo(self) < Math.Max(self.VisionRange, x.VisionRange) * 1.3) .Select(Utility.CloneCombat) .ToArray(); var tergetsSelector = new TargetsSelector(nearest); var opponents = nearest.Where(x => x.IsOpponent).ToArray(); var vec = new List <double>(); const int steps = 18; var my = (AWizard)nearest.FirstOrDefault(x => x.Id == self.Id); var ok = true; var canMove = true; while (vec.Count < steps) { if (canMove) { canMove = my.MoveTo(moveTo, null, w => w.GetFirstIntersection(obstacles) == null); if (TreesObserver.GetNearestTrees(my).Any(t => t.IntersectsWith(my))) { break; } } else { my.SkipTick(); } var tmp = OpponentCombats;//HACK OpponentCombats = opponents; vec.Add(costFunction(my)); OpponentCombats = tmp; foreach (var x in opponents) { var tar = tergetsSelector.Select(x); if (tar != null || x is AWizard) { x.EthalonMove(tar); } } if (vec.Count == 1 && firstMoveCondition != null && !firstMoveCondition(my)) { ok = false; break; } } if (!ok || vec.Count == 0) { continue; } while (vec.Count < steps) { vec.Add(CantMoveDanger); } var newDanger = 0.0; for (var k = 0; k < steps; k++) { newDanger += vec[k] * Math.Pow(0.87, k); } newDanger += 3 * vec[0]; if (newDanger < minDanger) { minDanger = newDanger; selMoveTo = Utility.PointsEqual(my, self) ? null : moveTo; selVec = vec; } } if (selVec != null) { move.Speed = move.StrafeSpeed = 0; move.MoveTo(selMoveTo, null); return(true); } return(false); }