public static void DefendMother(Point defender, IEnumerable <Point> targets) { Bb.readBoard(); if (!targets.Any() || !Bb.plantLookup.ContainsKey(defender)) { return; } var mother = Bb.ourMother.First(); var plant = defender.GetPlant(); var nearestTarget = targets.MinByValue(t => Trig.Distance(defender, t)); var nearestDistance = Trig.Distance(defender, nearestTarget); switch (plant.Mutation) { case AI.ARALIA: case AI.CHOKER: if (plant.RadiatesLeft > 0) { if (plant.UprootsLeft > 0 && nearestDistance > plant.Range && nearestDistance <= plant.Range + Bb.GetUprootRange(plant.Mutation)) { var astar = Search(defender.Single(), Bb.GetUprootRange(plant.Mutation), nearestTarget, plant.Range); if (astar.Path.Count() == 2) { var step = astar.Path.ElementAt(1); plant.uproot(step.x, step.y); } } if (Trig.Distance(plant.ToPoint(), nearestTarget) <= plant.Range) { plant.radiate(nearestTarget.x, nearestTarget.y); } } if (plant.UprootsLeft > 0 && Trig.Distance(mother, defender) > 75) { Uproot(defender, mother, 75); } break; case AI.TITAN: if (plant.UprootsLeft > 0 && Trig.Distance(mother, defender) > 75) { Uproot(defender, mother, 75); } if (plant.UprootsLeft > 0) { var dest = Trig.CalcPointsInCircle(plant.ToUprootCircle()).Where(p => IsPassable(p)).MaxByValue(d => targets.Count(t => Trig.Distance(d, t) <= plant.Range)); if (!dest.Equals(defender)) { plant.uproot(dest.x, dest.y); } } break; } }
public static bool Uproot(Point mover, Point goal, int goalRange, bool avoidPools = true) { if (mover.GetPlant().UprootsLeft <= 0) { return(false); } Bb.readBoard(); var plant = mover.GetPlant(); var astar = Search(mover.Single(), Bb.GetUprootRange(plant), goal, goalRange); if (astar.Path.Count() > 1) { var step = astar.Path.ElementAt(1); plant.uproot(step.x, step.y); return(true); } return(false); }
public static Point Spawn(int plantType, Point goal, int goalRange, bool avoidPools = true) { if (AI.me.Spores < AI.sporeCosts[plantType]) { return(new Point(-1, -1)); } var uprootRange = Bb.GetUprootRange(plantType); var starts = Bb.ourMother.Concat(Bb.ourSpawners); var goalEdge = Trig.CalcInnerEdgeOfCircle(new Circle(goal, goalRange)); var additionalNeighboors = goalEdge.Where(n => IsPassable(n)).ToHashSet(); Func <Point, IEnumerable <Point> > getNeighboors = p => { var stepSize = Bb.plantLookup.ContainsKey(p) ? p.GetPlant().Range : uprootRange; return(Trig.CalcInnerEdgeOfCircle(new Circle(p, stepSize)) .Concat(additionalNeighboors) .Where(n => IsPassable(n, avoidPools) && Trig.IsInRange(p, n, stepSize))); }; var astar = new Pather.AStar( starts, p => Trig.IsInRange(p, goal, goalRange) && IsPassable(p, avoidPools), (a, b) => 1, p => (int)Math.Ceiling(Trig.Distance(p, goal) / (double)uprootRange), getNeighboors); if (astar.Path.Count() > 1) { var p = astar.Path.ElementAt(1); AI.me.germinate(p.x, p.y, plantType); Bb.spawning.Add(p); return(p); } return(new Point(-1, -1)); }