public bool TryPushMyCapsule(Pirate myPirateWithCapsule, Pirate pusherPirate) { if (!pusherPirate.CanPush(myPirateWithCapsule) || myPiratesWithCapsulePushes[myPirateWithCapsule] == myPirateWithCapsule.NumPushesForCapsuleLoss - 1) { return(false); } var destination = GetMyBestMothershipThroughWormholes(myPirateWithCapsule); var bestWormhole = GetBestWormhole(myPirateWithCapsule, destination.Location); Location locationOfPush = null; if (bestWormhole != null) { var distance = DistanceThroughWormhole(myPirateWithCapsule.Location, destination, bestWormhole, game.GetActiveWormholes().Where(wormhole => wormhole != bestWormhole), 0, myPirateWithCapsule.MaxSpeed); locationOfPush = (distance > myPirateWithCapsule.Distance(destination)) ? destination.Location : bestWormhole.Location; } else { locationOfPush = destination.Location; } if (!IsWorthPushing(myPirateWithCapsule, pusherPirate)) { return(false); } availablePirates.Remove(pusherPirate); myPiratesWithCapsulePushes[myPirateWithCapsule]++; pusherPirate.Push( myPirateWithCapsule, game.GetMyMotherships().OrderBy(mothership => mothership.Distance(myPirateWithCapsule)) .FirstOrDefault()); return(true); }
public bool TryPushAsteroidTowardsCapsule(Pirate pirate, Asteroid asteroid) { if (pirate.CanPush(asteroid) && !asteroids[asteroid]) { // Check if there is a capsule holder. var enemyCapsuleHolders = game.GetEnemyLivingPirates().Where(p => p.HasCapsule()); if (enemyCapsuleHolders.Any()) { enemyCapsuleHolders = enemyCapsuleHolders.OrderBy(p => p.Distance(asteroid)); var closestHolder = enemyCapsuleHolders.FirstOrDefault(); var closestMothership = game.GetEnemyMotherships().OrderBy(m => m.Distance(closestHolder)).FirstOrDefault(); if (closestMothership != null) { // Intercept the capsule with the asteroid. var interception = IntersectionPoint(closestHolder.Location, asteroid.Location, closestMothership.Location, closestHolder.MaxSpeed, asteroid.Speed); if (interception != null) { // Push the asteroid. pirate.Push(asteroid, interception); asteroids[asteroid] = true; ("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " to intercept " + closestHolder.ToString() + " at " + interception).Print(); return(true); } } } } return(false); }
private bool TryPushAsteroid(Pirate pirate, Asteroid asteroid) { if (!pirate.CanPush(asteroid)) { return(false); } // Push the asteroid towards: 1) capsule that can be intercepted, 2) // Get the best capsule. var bestCapsule = game.GetEnemyCapsules().Where(capsule => capsule.Holder != null && GetEnemyBestMothershipThroughWormholes(capsule.Holder) != null && GetOptimalAsteroidInterception(capsule.Holder, pirate, asteroid, GetEnemyBestMothershipThroughWormholes(capsule.Holder).GetLocation()) != null) .OrderByDescending(capsule => capsule.Holder.Steps(GetEnemyBestMothershipThroughWormholes(capsule.Holder))).FirstOrDefault(); var bestGrouping = game.GetEnemyLivingPirates().OrderByDescending(enemy => enemy.PushReloadTurns). OrderBy(enemy => game.GetEnemyLivingPirates().Count(enemyPirate => enemyPirate.InRange(enemy, asteroid.Size))).FirstOrDefault(); if (bestCapsule != null) { // Push towards the capsule var pushLocation = GetOptimalAsteroidInterception(bestCapsule.Holder, pirate, asteroid, GetEnemyBestMothershipThroughWormholes(bestCapsule.Holder).Location); pirate.Push(asteroid, pushLocation); Print(pirate + " pushes asteroid " + asteroid + " towards " + pushLocation + " to intercept " + bestCapsule); return(true); } else if (bestGrouping != null) { // Push towards the grouping var pushLocation = bestGrouping.Location; pirate.Push(asteroid, pushLocation); Print(pirate + " pushes asteroid " + asteroid + " towards " + pushLocation); return(true); } return(false); }
public bool TryPushInterceptedEnemyCapsule(Pirate pirate, Pirate capsuleHolder) { var bestMothership = game.GetEnemyMotherships().OrderBy(mothership => mothership.Distance(capsuleHolder)).FirstOrDefault(); if (pirate.CanPush(capsuleHolder)) { // Check how much other pirates can push it. var numOfPushers = NumOfPushesAvailable(capsuleHolder); // Check if we can either make the pirate lose his capsule or get pushed outside the border. var pushesToBorder = capsuleHolder.Distance(GetClosestToBorder(capsuleHolder.Location)) / pirate.PushDistance; if ((numOfPushers >= pushesToBorder && enemyCapsulesPushes[capsuleHolder.Capsule] < pushesToBorder) || (numOfPushers >= capsuleHolder.NumPushesForCapsuleLoss && enemyCapsulesPushes[capsuleHolder.Capsule] < capsuleHolder.NumPushesForCapsuleLoss)) { // Push the pirate towards the border! pirate.Push(capsuleHolder, GetClosestToBorder(capsuleHolder.Location)); enemyCapsulesPushes[capsuleHolder.Capsule]++; return(true); } } else if (capsuleHolder.InRange(pirate, pirate.PushRange * 2) && pirate.InRange(bestMothership, (int)(game.PushDistance * 2))) { // Send the pirate towards the capsule where it can push. if (pirateDestinations.ContainsKey(pirate)) { pirateDestinations[pirate] = capsuleHolder.Location.Towards(pirate, (int)(pirate.PushRange * 0.9)); } else { pirateDestinations.Add(pirate, capsuleHolder.Location.Towards(pirate, (int)(pirate.PushRange * 0.9))); } return(true); } return(false); }
private bool DefensivePush(Pirate pirate, SpaceObject obj) { // If pirate, push towards the border. if (obj is Pirate) { // This pirate has a capsule. Push him to the edge, all his friends are dead. var enemy = (Pirate)obj; if (pirate.CanPush(enemy)) { pirate.Push(enemy, GetClosestToBorder(enemy.Location)); Print("Pirate " + pirate.ToString() + " has pushed enemy " + enemy.ToString() + " towards " + GetClosestToBorder(enemy.Location)); return(true); } return(false); } if (obj is Asteroid) { var asteroid = (Asteroid)obj; if (asteroids[asteroid]) { return(true); } // This object is an asteroid. Push it to the nearest enemy. if (pirate.CanPush(asteroid)) { var closestEnemy = enemyPirates.OrderBy(enemy => enemy.Distance(pirate)).FirstOrDefault(); if (closestEnemy != null) { // Push the asteroid towards it. pirate.Push(asteroid, closestEnemy); Print("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " towards " + closestEnemy.ToString()); return(true); } } else if (!pirate.HasCapsule()) { // Go towards the asteroid's destination where it is in range of a push. var dest = asteroid.Location.Add(asteroid.Direction).Towards(pirate, game.PushRange); pirate.Sail(dest); Print("Pirate " + pirate.ToString() + " sails towards asteroid " + asteroid.ToString() + " in his direction to push."); return(true); } } return(false); }
public bool TryPushEnemy(Pirate pirate, Pirate enemy) { if (pirate.CanPush(enemy)) { pirate.Push(enemy, GetClosestToBorder(enemy.Location)); ("Pirate " + pirate.ToString() + " pushes enemy " + enemy.ToString() + " towards " + GetClosestToBorder(enemy.Location)).Print(); return(true); } return(false); }
public bool TryPushWormhole(Pirate pirate, Wormhole wormhole) { List <Pirate> AvailablePirates = new List <Pirate>(); AvailablePirates.Add(pirate); if (pirate.CanPush(wormhole)) { PushWormhole(wormhole, AvailablePirates, false); } return(AvailablePirates.Count == 0); }
private bool TryPushWormhole(Pirate pirate, Wormhole wormhole) { if (pirate.CanPush(wormhole)) { // Push the wormhole var pushLocation = BestWormholePushLocation(wormhole); pirate.Push(wormhole, pushLocation); movedWormholeLocations[wormhole] = pushLocation; Print(pirate + " pushes " + wormhole + " towards " + pushLocation); return(true); } return(false); }
public bool ShouldPushPirates(Pirate first, Pirate second, Location destination) { if (first.CanPush(second) && second.CanPush(first)) { if (IsInDanger(second.Location, second.Location.Towards(destination, second.MaxSpeed), second) || IsInDanger(first.Location, first.Location.Towards(destination, first.MaxSpeed), first) || IsInDanger(second.Location, second.Location, second) || IsInDanger(first.Location, first.Location, first)) { return(true); } } return(false); }
private void PushInTheBestWay(Pirate p1, Pirate p2) { if (p1.CanPush(p2)) { if (p2.HasCapsule()) { p1.Push(p2, game.GetEnemyMothership().Location.Towards(p2, game.PushRange * 2)); } else { p1.Push(p2, GetOutsideBorder(p2.Location)); } } }
/// <summary> Tries to interact with a Wormhole. </summary> /// <returns> A tuple with a bool and the action string </returns> protected static Tuple <bool, string> InteractWithWormHole(Pirate pirate, Location goal) { if (!game.GetAllWormholes().Any() || !game.GetMyMotherships().Any() || !Main.mines.Any() || !game.GetEnemyMotherships().Any() || pirate.PushReloadTurns > 0) { return(new Tuple <bool, string>(false, "Did not interact with a wormhole")); } foreach (Wormhole wormhole in game.GetAllWormholes().Where(w => w.InRange(pirate, pirate.PushRange + pirate.MaxSpeed))) { if (Utils.DistanceWithWormhole(pirate.Location, goal, pirate.MaxSpeed) != pirate.Distance(goal)) { return(new Tuple <bool, string>(false, "Sailing into hole is faster")); } var cloestFriendlyMum = game.GetMyMotherships().OrderBy(wormhole.Distance).First(); var cloestFriendlyMine = Main.mines.OrderBy(wormhole.Distance).First(); bool closerToMum = wormhole.Distance(cloestFriendlyMum) < wormhole.Partner.Distance(cloestFriendlyMum); bool closerToMine = wormhole.Distance(cloestFriendlyMine) < wormhole.Partner.Distance(Main.mines.OrderBy(wormhole.Partner.Distance).First()); var pushLocation = cloestFriendlyMum.Location; if (closerToMine) { pushLocation = cloestFriendlyMine; } if (closerToMum || closerToMine) { if (pirate.CanPush(wormhole)) { pirate.Push(wormhole, pushLocation); Main.wormsPushed.Add(wormhole); } else { pirate.Sail(wormhole); } Main.didTurn.Add(pirate.Id); return(new Tuple <bool, string>(true, "Interacted with Wormhole")); } } return(new Tuple <bool, string>(false, "Did not interact with a wormhole")); }
public Dictionary <Pirate, MapObject> PushWormhole(Wormhole wormhole, List <Pirate> availablePirates, bool Assign) { // Checks if the wormhole can be pushed to a better location, and if is it returns the new location. // List<Location> candidates = new List<Location>(); // candidates.Add(wormhole.GetLocation()); // const int steps = 24; // for (int i = 0; i < steps; i++) // { // double angle = System.Math.PI * 2 * i / steps; // double deltaX = pirate.PushDistance * System.Math.Sin(angle); // double deltaY = pirate.PushDistance * System.Math.Cos(angle); // Location option = wormhole.Location.Add(new Location(-(int)deltaX, (int)deltaY)); // if (!option.InMap()) // { // continue; // } // candidates.Add(option); // } Dictionary <Pirate, MapObject> PiratePush = new Dictionary <Pirate, MapObject>(); List <MapObject> best = bestMothershipAndCapsulePair(wormhole); foreach (MapObject mapObject in best) { Pirate closestPirate = availablePirates.OrderBy(pirate => pirate.Distance(wormhole)).FirstOrDefault(); if (closestPirate == null) { break; } PiratePush.Add(closestPirate, mapObject); availablePirates.Remove(closestPirate); myPirates.Remove(closestPirate); if (closestPirate.CanPush(wormhole)) { closestPirate.Push(wormhole, mapObject); NewWormholeLocation[wormhole] = mapObject.GetLocation(); FinishedTurn[closestPirate] = true; } else if (Assign) { AssignDestination(closestPirate, wormhole.GetLocation().Towards(closestPirate, wormhole.WormholeRange)); } wormhole = wormhole.Partner; } return(PiratePush); }
public bool TryPushAsteroid(Pirate pirate, Asteroid asteroid) { if (pirate.CanPush(asteroid) && !asteroids[asteroid]) { var closestEnemy = game.GetEnemyLivingPirates().OrderBy(enemy => enemy.Distance(asteroid)).OrderByDescending(enemy => GetGroupingNumber(enemy)).FirstOrDefault(); var pushDestination = game.GetLivingAsteroids().OrderBy(ast => ast.Distance(asteroid)).Where(ast => ast != asteroid).FirstOrDefault(); if (closestEnemy != null && pushDestination != null) { // Check which one is closest to the pirate. if (closestEnemy.Distance(pirate) < pushDestination.Distance(pirate)) { // Push the asteroid towards the enemies. pirate.Push(asteroid, closestEnemy); ("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " towards " + closestEnemy.ToString()).Print(); } else { pirate.Push(asteroid, pushDestination); ("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " towards " + pushDestination.ToString()).Print(); } asteroids[asteroid] = true; return(true); } else if (closestEnemy != null) { // astroids.OrderBy(asteroid => asteroid.Distance(destination)).OrderBy(asteroid => asteroid.Distance(closestAsteroid)).Where(asteroid => asteroid != closestAsteroid).FirstOrDefault() // Push the asteroid towards it. pirate.Push(asteroid, closestEnemy); ("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " towards " + closestEnemy.ToString()).Print(); asteroids[asteroid] = true; return(true); } else if (pushDestination != null) { pirate.Push(asteroid, pushDestination); ("Pirate " + pirate.ToString() + " pushes asteroid " + asteroid.ToString() + " towards " + pushDestination.ToString()).Print(); asteroids[asteroid] = true; return(true); } } return(false); }
private bool TryPush(Pirate pirate, Pirate enemy) { if (pirate.CanPush(enemy)) { if (enemy.HasCapsule()) { // Push the capsule to the initial location pirate.Push(enemy, GetClosestToBorder(enemy.Location)); Print("Pirate " + pirate + " pushes " + enemy + " (capsule holder) to " + GetClosestToBorder(enemy.Location)); } else { // Push the enemy to the border pirate.Push(enemy, GetClosestToBorder(enemy.Location)); Print("Pirate " + pirate + " pushes " + enemy + " towards " + GetClosestToBorder(enemy.Location)); } return(true); } return(false); }
public bool TryPushEnemyCapsuleDefensively(Pirate pirate, Pirate capsuleHolder) { var bestMothership = game.GetEnemyMotherships().OrderBy(mothership => mothership.Distance(capsuleHolder)).FirstOrDefault();; if (pirate.CanPush(capsuleHolder)) { // Check how much other pirates can push it. var numOfPushers = NumOfPushesAvailable(capsuleHolder); // Check if we can either make the pirate lose his capsule or get pushed outside the border. var pushesToBorder = capsuleHolder.Distance(GetClosestToBorder(capsuleHolder.Location)) / pirate.PushDistance; if ((numOfPushers >= pushesToBorder && enemyCapsulesPushes[capsuleHolder.Capsule] < pushesToBorder) || (numOfPushers >= capsuleHolder.NumPushesForCapsuleLoss && enemyCapsulesPushes[capsuleHolder.Capsule] < capsuleHolder.NumPushesForCapsuleLoss)) { // Push the pirate towards the border! pirate.Push(capsuleHolder, capsuleHolder.Location.Towards(capsuleHolder.Capsule.InitialLocation, -numOfPushers * pirate.PushDistance)); enemyCapsulesPushes[capsuleHolder.Capsule]++; return(true); } } return(false); }
public bool TryPushMyCapsule(Pirate myPirateWithCapsule, Pirate pusherPirate) { if (!pusherPirate.CanPush(myPirateWithCapsule) || myPiratesWithCapsulePushes[myPirateWithCapsule] == myPirateWithCapsule.NumPushesForCapsuleLoss - 1) { return(false); } var destination = GetMyBestMothershipThroughWormholes(myPirateWithCapsule); var locationOfPush = myPirateWithCapsule.Location.Towards(destination, pusherPirate.PushDistance); if (!IsWorthPushing(myPirateWithCapsule, pusherPirate, locationOfPush, destination.Location)) { return(false); } availablePirates.Remove(pusherPirate); myPiratesWithCapsulePushes[myPirateWithCapsule]++; pusherPirate.Push( myPirateWithCapsule, game.GetMyMotherships().OrderBy(mothership => mothership.Distance(myPirateWithCapsule)) .FirstOrDefault()); return(true); }
private bool PushCarrier(Pirate pirate, PirateGame game) { // Go over all enemies. foreach (Pirate enemy in game.GetEnemyLivingPirates()) { // Check if the pirate can push the enemy. if (pirate.CanPush(enemy) && enemy.HasCapsule()) { // Push enemy! pirate.Push(enemy, enemy.InitialLocation); // Print a message. System.Console.WriteLine("pirate " + pirate + " pushes " + enemy + " towards " + enemy.InitialLocation); // Did push. return(true); } } // Didn't push. return(false); }
/// <summary> Tries to either avoid or push the asteroid </summary> /// <returns> A tuple with bool and the action string </returns> protected static Tuple <bool, string> InteractWithAsteroid(Pirate pirate, Location to) { var asteroids = Utils.AsteroidsByDistance(pirate.Location).Where(ass => ass.Direction.Add(ass.Location).Distance(pirate) <= game.PushDistance + pirate.MaxSpeed + ass.Size).ToList(); foreach (Asteroid asteroid in asteroids) { if (pirate.CanPush(asteroid) && !Main.asteroidsPushed.Contains(asteroid)) { var pushTuple = Utils.OptimalAsteroidPushLocation(pirate.PushDistance, asteroid); if (pirate.InRange(asteroid.Location.Add(asteroid.Direction), asteroid.Size + pirate.MaxSpeed)) { pirate.Push(asteroid, pushTuple.Item1); return(new Tuple <bool, string>(true, "Pushed asteroid in an emergency")); } if (pushTuple.Item2 > 0) { pirate.Push(asteroid, pushTuple.Item1); Main.asteroidsPushed.Add(asteroid); Main.didTurn.Add(pirate.Id); return(new Tuple <bool, string>(true, "Pushed asteroid to best location")); } } bool shouldAvoid = pirate.Distance(asteroid) < game.PushDistance + asteroid.Size; shouldAvoid = shouldAvoid && game.GetEnemyLivingPirates().Any(p => p.InRange(asteroid, p.PushDistance + p.MaxSpeed)); if (Utils.AsteroidIsMoving(asteroid) && (shouldAvoid || pirate.Location == to)) { pirate.Sail(SafestCloestLocation(pirate.Location, to, pirate)); Main.didTurn.Add(pirate.Id); return(new Tuple <bool, string>(true, "Avoiding asteroid")); } } return(new Tuple <bool, string>(false, "Did not run")); }
/// <summary> /// Makes the pirate try to push an enemy pirate. Returns true if it did. /// </summary> /// <param name="pirate">The pushing pirate.</param> /// <param name="game">The current game state.</param> /// <returns> true if the pirate pushed. </returns> public static bool TryPush(Pirate pirate) { // Go over all enemies. foreach (Pirate enemy in GameSettings.game.GetEnemyLivingPirates()) { // Check if the pirate can push the enemy. if (pirate.CanPush(enemy)) { //Changed //Push enemy! Location oppositeSide = enemy.GetLocation().Subtract(GameSettings.game.GetEnemyMothership().GetLocation()); //Vector: the distance (x,y) you need to go through to go from the mothership to the enemy oppositeSide = enemy.GetLocation().Towards(enemy.GetLocation().Add(oppositeSide), 600); pirate.Push(enemy, oppositeSide); //Print a message. GameSettings.game.Debug("pirate " + pirate + " pushes " + enemy + " towards " + enemy.InitialLocation); //Did push. return(true); } } // Didn't push. return(false); }
override public string Preform() { if (!Utils.GetMyHolders().Any() || !game.GetMyCapsules().Any() || !game.GetAllMotherships().Any()) { if (Main.mines.Count > 0 && game.GetMyMotherships().Any()) { var sailLocation = Utils.GetMyHolders().OrderBy(h => h.Distance(pirate)).First().Location; return(Utils.GetPirateStatus(pirate, "Sailing to rendezvous point, " + Sailing.SafeSail(pirate, sailLocation))); } return(Utils.GetPirateStatus(pirate, "Is idle.")); } var holders = Utils.GetMyHolders().OrderBy(h => h.Distance(pirate)); var cloestHolder = holders.First(); foreach (Pirate holder in Utils.GetMyHolders().OrderBy(h => h.Distance(pirate))) { var nearestShip = Utils.OrderByDistance(game.GetMyMotherships().ToList(), holder.Location).First(); if (!pirate.CanPush(holder)) { var sailLocation = Utils.GetMyHolders().OrderBy(h => h.Distance(pirate)).First().Location; return(Utils.GetPirateStatus(pirate, "Sailing towards holder, " + Sailing.SafeSail(pirate, sailLocation))); } var threats = game.GetEnemyLivingPirates().Where(t => t.PushReloadTurns > 2 && t.Distance(nearestShip) < pirate.Distance(nearestShip) * 1.5).OrderBy(nearestShip.Distance); // Checks if the holder can be pushed directly onto the ship bool caseI = holder.Distance(nearestShip) - game.MothershipUnloadRange <= pirate.PushDistance + holder.MaxSpeed; bool caseII = false; if (threats.Any() && threats.First().Distance(nearestShip) > holder.Distance(nearestShip)) { caseII = holder.Distance(nearestShip) - threats.First().Distance(nearestShip) < pirate.PushRange; } var holderLocAfterPush = holder.GetLocation().Towards(nearestShip, pirate.PushDistance + holder.MaxSpeed / 2); bool caseIII_PI = threats.Any() && threats.First().Distance(nearestShip) < holder.Distance(nearestShip); bool caseIII_PII = threats.Any() && threats.First().PushRange < holderLocAfterPush.Distance(threats.First()); bool ImminentDeath = game.GetEnemyLivingPirates().Count(t => holder.InRange(t, holder.MaxSpeed + t.PushRange) && t.PushReloadTurns <= 1) >= holder.NumPushesForCapsuleLoss; if (ImminentDeath && !caseI && holder.MaxSpeed * 10 < holder.Distance(nearestShip)) { var safest = Sailing.SafestCloestLocation(holder.Location, nearestShip.Location, 2, true, pirate); pirate.Push(holder, safest); Main.piratesPushed.Add(holder); Main.didTurn.Add(pirate.Id); if (!Main.didTurn.Contains(holder.Id)) { holder.Push(pirate, safest); Main.piratesPushed.Add(pirate); Main.didTurn.Add(holder.Id); } return(Utils.GetPirateStatus(pirate, "Moved away from danger zone")); } bool caseIII = threats.Any() && caseIII_PI && caseIII_PII && ImminentDeath; game.Debug(caseI + " || " + caseII + " || " + caseIII + " +| IMD: " + ImminentDeath); if (caseI || caseIII) { if (Utils.GetMyHolders().Count() > 1) { var secondHolder = Utils.GetMyHolders().First(h => h.Id != holder.Id); if (!Main.didTurn.Contains(holder.Id) && holder.CanPush(secondHolder) && !Main.piratesPushed.Contains(secondHolder) && secondHolder.Distance(nearestShip) - nearestShip.UnloadRange < pirate.PushDistance + secondHolder.MaxSpeed) { holder.Push(secondHolder, nearestShip); Main.piratesPushed.Add(secondHolder); pirate.Push(holder, nearestShip); Main.piratesPushed.Add(holder); if (!Main.didTurn.Contains(secondHolder.Id) && holder.NumPushesForCapsuleLoss > 2 && secondHolder.CanPush(holder)) { secondHolder.Push(holder, nearestShip); Main.piratesPushed.Add(holder); } Main.didTurn.Add(holder.Id); Main.didTurn.Add(pirate.Id); return(Utils.GetPirateStatus(pirate, "Pushed holder to the motherShip while the holder boosted another holder")); } } if (!Main.didTurn.Contains(holder.Id)) { holder.Sail(nearestShip); Main.didTurn.Add(holder.Id); } pirate.Push(holder, nearestShip); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(holder); return(Utils.GetPirateStatus(pirate, "Pushed holder directly to ship")); } Main.holdersPaired.Add(holder); return(Utils.GetPirateStatus(pirate, "Sailing towards paired holder, " + Sailing.SafeSail(pirate, holder.Location))); } return("Did nothing"); }
override public string Preform() { if (game.GetEnemyCapsules().Count() == 0 || game.GetEnemyMotherships().Count() == 0) { return(Utils.GetPirateStatus(pirate, "No enemy capsules or ships")); } var nearestCapsule = Utils.OrderByDistance(game.GetEnemyCapsules().ToList(), pirate.Location).First(); var nearestShip = Utils.OrderByDistance(game.GetEnemyMotherships().ToList(), nearestCapsule.Location).First(); if (Main.didTurn.Contains(pirate.Id)) { return(Utils.GetPirateStatus(pirate, "Already did turn")); } if (Utils.HasEnemyBomb(pirate)) { return(Utils.GetPirateStatus(pirate, Sailing.SafeSail(pirate, new Location(0, 0)))); } var sortedEnemyHolders = Utils.EnemyHoldersByDistance(pirate.GetLocation()).Where(enemy => !Main.piratesPushed.Contains(enemy) && pirate.CanPush(enemy)); bool shouldGo = !sortedEnemyHolders.Any() || pirate.MaxSpeed * 4 + pirate.Distance(nearestShip) < sortedEnemyHolders.First().Distance(nearestShip); if (shouldGo) { foreach (Wormhole hole in game.GetAllWormholes().Where(h => h.Distance(nearestShip) < pirate.MaxSpeed * 10 && !Main.wormsPushed.Contains(h))) { var molesByDistance = Utils.PiratesWithTask(TaskType.MOLE).OrderBy(hole.Distance); bool closest = molesByDistance.First().Id == pirate.Id || (molesByDistance.Count() > 1 && molesByDistance.Take(2).Contains(pirate)); var eholdersbydistance = Utils.EnemyHoldersByDistance(nearestShip.GetLocation()); if (!pirate.CanPush(hole) && pirate.PushRange < pirate.Distance(hole) && closest) { var wormLoc = pirate.Location.Towards(hole, pirate.Distance(hole) - hole.WormholeRange); var assDanger = game.__livingAsteroids.Any(a => a.Location.Add(a.Direction).Distance(pirate) <= a.Size + pirate.MaxSpeed * 2); var bombDanger = game.__stickyBombs.Any(b => b.Distance(pirate) < b.ExplosionRange + pirate.MaxSpeed * 2); var wormPushLocation = pirate.Location.Towards(hole, pirate.Distance(hole) - pirate.PushRange); var caseI = pirate.Distance(wormPushLocation) / pirate.MaxSpeed >= pirate.PushReloadTurns; var caseII = true; if (eholdersbydistance.Any()) { caseII = hole.Distance(nearestShip) + pirate.MaxSpeed * 4 < eholdersbydistance.First().Distance(nearestShip); } if (!assDanger && !bombDanger && caseI && caseII) { pirate.Sail(wormLoc); Main.didTurn.Add(pirate.Id); return(Utils.GetPirateStatus(pirate, "Sailing out to worm hole ")); } if (caseI && caseII) { return(Utils.GetPirateStatus(pirate, "Safely sailing out to worm hole " + Sailing.SafeSail(pirate, wormLoc))); } } var enemyHolders = Utils.EnemyHoldersByDistance(pirate.GetLocation()).SkipWhile(Main.piratesPushed.Contains).OrderBy(hole.Distance); if (pirate.CanPush(hole) && hole.IsActive && enemyHolders.Any() && hole.Distance(nearestShip) < hole.Partner.Distance(nearestShip)) { foreach (Pirate enemyHolder in enemyHolders) { int cost = enemyHolder.Distance(hole) + enemyHolder.MaxSpeed / 2; if (cost < pirate.PushDistance) { pirate.Push(hole, pirate.Location.Towards(enemyHolder.Location, cost)); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(enemyHolder); Main.wormsPushed.Add(hole); return(Utils.GetPirateStatus(pirate, "Pushed hole on enemy")); } } } if (pirate.CanPush(hole) && Main.mines.Any()) { pirate.Push(hole, Main.mines.OrderBy(nearestShip.Distance).First()); Main.didTurn.Add(pirate.Id); Main.wormsPushed.Add(hole); return(Utils.GetPirateStatus(pirate, "Pushed hole away")); } } } foreach (Pirate enemyHolder in sortedEnemyHolders) { game.Debug("pirate can push holder: " + pirate.CanPush(enemyHolder)); var killLocation = Utils.NearestKillLocation(enemyHolder.Location); double maxDistance = ((double)killLocation.Item1 + enemyHolder.MaxSpeed / 2); var canKillAlone = maxDistance / pirate.PushDistance <= 1; if (canKillAlone) { pirate.Push(enemyHolder, killLocation.Item2); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(enemyHolder); return(Utils.GetPirateStatus(pirate, "Killed enemy holder")); } // Initialize variables var pushHelpers = game.GetMyLivingPirates().Where(h => h.CanPush(enemyHolder) && !Main.didTurn.Contains(h.Id)).OrderBy(h => h.PushDistance); var killHelpers = pushHelpers.Where(h => h.Id != pirate.Id && ((double)killLocation.Item1 + enemyHolder.MaxSpeed / 2) / ((double)h.PushDistance + pirate.PushDistance) <= 1); // If they can kill him if (killHelpers.Any()) { var partner = killHelpers.OrderByDescending(h => maxDistance / ((double)h.PushDistance + pirate.PushDistance) <= 1).First(); pirate.Push(enemyHolder, killLocation.Item2); partner.Push(enemyHolder, killLocation.Item2); Main.didTurn.AddRange(new List <int> { pirate.Id, partner.Id }); Main.piratesPushed.Add(enemyHolder); return(Utils.GetPirateStatus(pirate, "Couple killed enemy holder")); } // If they can make him drop his capsule but not kill him if (pushHelpers.Count() >= enemyHolder.NumPushesForCapsuleLoss) { var pushers = pushHelpers.Take(enemyHolder.NumPushesForCapsuleLoss).ToList(); var pushLocation = Utils.NearestKillLocation(enemyHolder.GetLocation()).Item2; if (Utils.NearestKillLocation(enemyHolder.GetLocation()).Item2.Distance(nearestCapsule) < nearestShip.Distance(nearestCapsule)) { pushLocation = nearestShip.GetLocation(); } pushers.ForEach(m => m.Push(enemyHolder, pushLocation)); Main.didTurn.AddRange(from p in pushers select p.Id); Main.piratesPushed.Add(enemyHolder); return(Utils.GetPirateStatus(pirate, enemyHolder.NumPushesForCapsuleLoss + " pirates droped the enemy capsule")); } // Boost enemy to closest dropers couple var myMoles = Utils.PiratesWithTask(TaskType.MOLE).ToList().Where(p => p.Id != pirate.Id && p.PushReloadTurns <= 1).OrderBy(p => p.Distance(nearestShip)).ToList(); var regularEnemyPirates = game.GetEnemyLivingPirates().Where(prt => !prt.HasCapsule()).ToList(); bool shouldUseBuddies = myMoles.Any() && pirate.PushRange + pirate.MaxSpeed / 2 < myMoles.OrderBy(pirate.Distance).First().Distance(pirate); bool enemyIsTerr = Utils.HasMyBomb(enemyHolder); if (regularEnemyPirates.Any() && myMoles.Count() >= 2 && shouldUseBuddies && !enemyIsTerr) { foreach (Pirate A in myMoles) { foreach (Pirate B in myMoles.Where(m => m.Id != A.Id)) { if (A.Distance(pirate) < A.PushRange * 1.5) { continue; } var centerLoc = Utils.Center(A.Location, B.Location); var pushLocation = pirate.GetLocation().Towards(centerLoc, pirate.PushDistance - enemyHolder.MaxSpeed / 2); bool checkI = pushLocation.Distance(A) <= A.PushRange && pushLocation.Distance(B) <= B.PushRange; bool checkII = enemyHolder.StateName == "normal"; // TODO add check if there is a booster close to the enemy pirate if (checkI && checkII) { pirate.Push(enemyHolder, centerLoc); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(enemyHolder); return(Utils.GetPirateStatus(pirate, "Pushed pirates towards buddies!")); } } } } } int radius = (game.PushRange + game.HeavyPushDistance) / 3; int coupleIndex = Utils.PiratesWithTask(TaskType.MOLE).OrderBy(nearestShip.Distance).ToList().IndexOf(pirate) / 2; if (coupleIndex > 0) { radius += game.HeavyPushDistance; } var loc = nearestShip.GetLocation().Towards(nearestCapsule, radius); foreach (Pirate enemyHolder in sortedEnemyHolders) { var CheckI = enemyHolder.Distance(nearestShip) < 2 * pirate.PushRange + pirate.Distance(nearestShip); var CheckII = pirate.PushReloadTurns <= (enemyHolder.Distance(nearestShip) - pirate.Distance(nearestShip)) / (2 * enemyHolder.MaxSpeed); var CheckIII = pirate.Distance(loc) < 2 * pirate.MaxSpeed; var CheckIV = game.GetMyLivingPirates().Count(p => p.Id != pirate.Id && p.GetLocation().Col == pirate.Location.Col && p.GetLocation().Row == pirate.Location.Row) >= 1; //var CheckV = Utils.PiratesWithTask(TaskType.MOLE).OrderBy(enemyHolder.Distance).First().Id == pirate.Id; //game.Debug(CheckI + " || " + CheckII + " || " + CheckIII + " || " + CheckIV + " || "/*+ CheckV + " || "*/); if (CheckI && CheckII && CheckIII && CheckIV /* && CheckV*/) { return(Utils.GetPirateStatus(pirate, "Sailing out to enemy holder " + Sailing.SafeSail(pirate, enemyHolder.GetLocation()))); } } return(Utils.GetPirateStatus(pirate, "Is sailing to position, " + Sailing.SafeSail(pirate, loc))); }
/// <summary> Tries to kill an enemy, alone or with other pirates </summary> /// <returns> A tuple with bool and the action string </returns> protected static Tuple <bool, string> TryKill(Pirate pirate) { foreach (Pirate enemy in game.GetEnemyLivingPirates().OrderBy(pirate.Distance).Where(e => pirate.CanPush(e))) { var killLocation = Utils.NearestKillLocation(enemy.Location); if (((double)killLocation.Item1 + enemy.MaxSpeed / 2) / pirate.PushDistance <= 1) { pirate.Push(enemy, killLocation.Item2); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(enemy); return(new Tuple <bool, string>(true, "Killed enemy")); } double killCost = killLocation.Item1 + ((double)enemy.MaxSpeed / 2); var helpers = game.GetMyLivingPirates().Where(h => h.CanPush(enemy) && h.Id != pirate.Id && !Main.didTurn.Contains(h.Id)).OrderBy(h => h.PushDistance); var killHelpers = helpers.Where(h => killCost / ((double)h.PushDistance + pirate.PushDistance) <= 1); if (killHelpers.Any()) { var partner = killHelpers.OrderByDescending(h => killCost / ((double)h.PushDistance + pirate.PushDistance) <= 1).First(); pirate.Push(enemy, killLocation.Item2); Main.didTurn.Add(pirate.Id); partner.Push(enemy, killLocation.Item2); Main.didTurn.Add(partner.Id); Main.piratesPushed.Add(enemy); return(new Tuple <bool, string>(true, "Couple killed holder")); } if (enemy.HasCapsule() && game.GetEnemyCapsules().ToList().Any() && game.GetEnemyMotherships().ToList().Any()) { var nearestCapsule = Utils.OrderByDistance(game.GetEnemyCapsules().ToList(), pirate.Location).First(); var nearestShip = Utils.OrderByDistance(game.GetEnemyMotherships().ToList(), nearestCapsule.Location).First(); // If they can make him drop his capsule but not kill him if (helpers.Count() + 1 >= enemy.NumPushesForCapsuleLoss) { var pushers = helpers.Take(enemy.NumPushesForCapsuleLoss - 1).ToList(); pushers.Add(pirate); var pushLocation = Utils.NearestKillLocation(enemy.GetLocation()).Item2; if (Utils.NearestKillLocation(enemy.GetLocation()).Item2.Distance(nearestCapsule) < nearestShip.Distance(nearestCapsule)) { pushLocation = nearestShip.GetLocation(); } pushers.ForEach(m => m.Push(enemy, pushLocation)); Main.didTurn.AddRange(from p in pushers select p.Id); Main.piratesPushed.Add(enemy); return(new Tuple <bool, string>(true, " pirates droped the enemy capsule")); } } } return(new Tuple <bool, string>(false, "Did not run")); }
private bool CanCatchUpAndPush(Pirate pirate, Pirate destinationPirate, Location destination) { Location intercept = Interception(destinationPirate.Location, destination, pirate.Location); int steps = pirate.Distance(intercept) / pirate.MaxSpeed; return((steps < pirate.PushReloadTurns && pirate.Distance(intercept) < pirate.Distance(destination)) || pirate.CanPush(destinationPirate)); }
public void PushInterferingEnemy(Pirate pirate) { Pirate closestEnemy = game.GetEnemyLivingPirates().Where(enemy => enemy.CanPush(pirate) && pirate.CanPush(enemy)).OrderBy(enemy => enemy.Distance(pirate)).FirstOrDefault(); pirate.Push(closestEnemy, GetClosestToBorder(closestEnemy.Location)); pirateDestinations.Remove(pirate); }
/// <summary> /// Makes the defender try to push an enemy pirate. Returns true if it did. /// If can be pushed out of the map, else push againts the motherboard. /// </summary> /// <returns> true if the pirate pushed. </returns> public override bool Push() { foreach (Asteroid asteroid in GameSettings.Game.GetLivingAsteroids()) { if (pirate.CanPush(asteroid)) { GameSettings.Game.Debug("Pirate in Backup = " + pirate); GameSettings.Game.Debug("Location in Backup = " + asteroidHandler.FindBestLocationToPushTo(this.Pirate)); pirate.Push(asteroid, asteroidHandler.FindBestLocationToPushTo(this.Pirate)); return(true); } } if (PirateToPush != null && WhereToPush != null) { if (pirate.CanPush(PirateToPush)) { pirate.Push(PirateToPush, WhereToPush); return(true); } } GameSettings.Game.Debug("Front WhereToPush " + WhereToDefend); foreach (Pirate enemy in GameSettings.Game.GetEnemyLivingPirates()) { // Check if the pirate can push the enemy. if (Pirate.CanPush(enemy) && enemy.HasCapsule()) { //Changed //Push enemy! Location outOfBorder = FieldAnalyzer.GetCloseEnoughToBorder(enemy, Pirate.PushRange); if (outOfBorder != null) { Pirate.Push(enemy, outOfBorder); return(true); } else { Location oppositeSide = enemy.GetLocation().Subtract(GameSettings.Game.GetEnemyMotherships()[0].GetLocation()); //Vector: the distance (x,y) you need to go through to go from the mothership to the enemy oppositeSide = enemy.GetLocation().Towards(enemy.GetLocation().Add(oppositeSide), 600); Pirate.Push(enemy, oppositeSide); //Print a message. GameSettings.Game.Debug("defender " + Pirate + " pushes " + enemy + " towards " + enemy.InitialLocation); //Did push. return(true); } } } foreach (Wormhole wormhole in GameSettings.Game.GetAllWormholes()) { if (wormhole.Distance(pirate) < 750) { if (pirate.CanPush(wormhole)) { int cols = GameSettings.Game.Cols; int rows = GameSettings.Game.Rows; //Push to the center for now if (pirate.CanPush(wormhole)) { pirate.Push(wormhole, new Location(rows / 2, cols / 2)); GameSettings.Game.Debug("Pirate pushed wormhole"); return(true); } } } } return(false); }
/// <summary> Sails to goal safely </summary> /// <returns> A tuple with bool and the action string </returns> public static string SafeSail(Pirate pirate, Location to) { if (Main.didTurn.Contains(pirate.Id)) { return("Already did turn"); } if (Utils.HasEnemyBomb(pirate)) { var bomb = game.__stickyBombs.Where(b => b.Owner == game.GetEnemy()).OrderBy(pirate.Distance).First(); if (bomb.Countdown < 2) { foreach (Pirate enemy in game.GetEnemyLivingPirates().Where(pirate.CanPush).SkipWhile(Main.piratesPushed.Contains).OrderBy(pirate.Distance)) { pirate.Push(enemy, pirate); Main.didTurn.Add(pirate.Id); return("Hugged an enemy to death"); } } foreach (Pirate enemy in game.GetEnemyLivingPirates().OrderBy(pirate.Distance)) { double turnsToArrive = pirate.Distance(enemy) / pirate.MaxSpeed; var shouldSail = (game.GetMyLivingPirates().Count(p => p.InRange(pirate, bomb.ExplosionRange)) - game.GetEnemyLivingPirates().Count(e => e.InRange(pirate, bomb.ExplosionRange))) <= 0; if (shouldSail) { pirate.Sail(enemy); Main.didTurn.Add(pirate.Id); return("Sailing to bomb enemy"); } } Main.didTurn.Add(pirate.Id); return("Stop!"); } var dangerPirates = game.GetMyLivingPirates().ToList(); dangerPirates.AddRange(game.GetEnemyLivingPirates().ToList()); dangerPirates = dangerPirates.Where(p => (Utils.HasEnemyBomb(p) || Utils.HasMyBomb(p)) && p.StickyBombs.First().Countdown <= 2 && pirate.CanPush(p)).ToList(); foreach (Pirate prt in dangerPirates) { pirate.Push(prt, Utils.OptimalBomberPushLocation(pirate, prt)); Main.didTurn.Add(pirate.Id); return("Pushed bomber away"); } var interactWithAsteroid = InteractWithAsteroid(pirate, to); if (interactWithAsteroid.Item1) { return(interactWithAsteroid.Item2); } if (!Utils.PiratesWithTask(TaskType.MOLE).Contains(pirate)) { var killEnemy = TryKill(pirate); if (killEnemy.Item1) { return(killEnemy.Item2); } } var enemys = game.GetEnemyLivingPirates().OrderBy(p => p.Distance(pirate)).ToList(); if (enemys.Any() && pirate.InStickBombRange(enemys.First()) && game.GetMyself().TurnsToStickyBomb == 0) { //pirate.StickBomb(enemys.First()); //Main.didTurn.Add(pirate.Id); //return "Stick bombed enemy holder"; } var interactWithWormHole = InteractWithWormHole(pirate, to); if (interactWithWormHole.Item1) { return(interactWithWormHole.Item2); } var objects = new List <MapObject>(); objects.AddRange(Utils.AsteroidsByDistance(pirate.Location).Where(ass => ass.Direction.Add(ass.Location).Distance(pirate) <= 4 * pirate.MaxSpeed + ass.Size)); objects.AddRange(game.GetActiveWormholes().Where(hole => hole.Distance(pirate.GetLocation()) <= 4 * Chunk.size)); objects.AddRange(game.GetAllStickyBombs().Where(bomb => bomb.Distance(pirate) < 1.5 * bomb.ExplosionRange + pirate.MaxSpeed)); objects = objects.OrderBy(obj => obj.Distance(pirate)).ToList(); if (!objects.Any()) { pirate.Sail(to); Main.didTurn.Add(pirate.Id); return("Sailing safely directly to goal i.e. " + Chunk.GetChunk(to)); } var traits = new List <Trait>() { new TraitRateByLazyAsteroid(game.HeavyPushDistance), new TraitRateByMovingAsteroid(game.HeavyPushDistance / 2 + game.PirateMaxSpeed * 3), new TraitWormhole(to, pirate), new TraitRateByStickyBomb() }; Path path = new Path(pirate.Location, to, traits); if (path.GetSailLocations().Count > 1) { pirate.Sail(path.Pop()); Main.didTurn.Add(pirate.Id); return(Chunk.GetChunk(to).ToString()); } pirate.Sail(to); Main.didTurn.Add(pirate.Id); return(Chunk.GetChunk(to).ToString()); }
public bool CanPush(SpaceObject target) { return(CanPlay && pirate.CanPush(target)); }
override public string Preform() { if (Main.didTurn.Contains(pirate.Id) || !game.GetMyMotherships().Any()) { return(Utils.GetPirateStatus(pirate, "Already did turn")); } if (!pirate.HasCapsule()) { turnCounter = 0; if (Main.capsulesTargetted.ContainsKey(pirate)) { var sailLocation = Main.capsulesTargetted[pirate].Location; return(Utils.GetPirateStatus(pirate, "Sailing to capsule " + Sailing.SafeSail(pirate, sailLocation))); } return(Utils.GetPirateStatus(pirate, "Is idle... ")); } var nearestShip = Utils.OrderByDistance(game.GetMyMotherships().ToList(), pirate.Location).First(); var threats = game.GetEnemyLivingPirates().ToList().Where(e => e.PushReloadTurns < 3 && e.Distance(nearestShip) < pirate.Distance(nearestShip)).OrderBy(nearestShip.Distance).ToList(); if (Utils.HasEnemyBomb(pirate)) { var suicideObj = Utils.NearestKillLocation(pirate.GetLocation()).Item2; var bomb = game.__stickyBombs.OrderBy(pirate.Distance).First(); bool canReachMum = pirate.Distance(nearestShip) / pirate.MaxSpeed + pirate.MaxSpeed < bomb.Countdown; if (!canReachMum) { return(Utils.GetPirateStatus(pirate, Sailing.SafeSail(pirate, new Location(0, 0)))); } } turnCounter++; if (turnCounter == 0) { maxTurnsToArrive = ((double)pirate.Distance(nearestShip) / pirate.MaxSpeed) * 2.5; } if (Utils.GetMyHolders().Count() > 1) { var secondHolder = Utils.GetMyHolders().Where(h => h.Id != pirate.Id).First(); var nearestShipToSecondHolder = Utils.OrderByDistance(game.GetMyMotherships().ToList(), secondHolder.Location).First(); var secondThreats = game.GetEnemyLivingPirates().ToList().Where(e => e.CanPush(secondHolder) && e.Distance(nearestShip) < secondHolder.Distance(nearestShip)); secondThreats = secondThreats.OrderBy(treath => treath.Distance(secondHolder)).ToList(); bool caseVI = secondHolder.Distance(nearestShip) < pirate.Distance(nearestShip); bool caseVII = secondHolder.Distance(nearestShip) < pirate.PushDistance + secondHolder.MaxSpeed + game.MothershipUnloadRange; if (pirate.CanPush(secondHolder) && caseVI && caseVII && !Main.piratesPushed.Contains(secondHolder)) { pirate.Push(secondHolder, nearestShipToSecondHolder); Main.didTurn.Add(pirate.Id); Main.piratesPushed.Add(secondHolder); return(Utils.GetPirateStatus(pirate, "Boosted second holder")); } } var traits = new List <Trait>() { new TraitRateByLazyAsteroid(game.PushDistance + game.AsteroidSize), new TraitRateByMovingAsteroid(game.HeavyPushDistance / 2 + game.PirateMaxSpeed * 3), new TraitRateByEdges(750, 4), new TraitRateByStickyBomb(), new TraitRateByEnemy(150, 3, -1), new TraitAttractedToGoal(500, nearestShip.Location), new TraitWormhole(nearestShip.Location, pirate) }; if (threats.Any() && maxTurnsToArrive < turnCounter && Utils.GetNumOfEnemyPiratesOnPoint(threats.First().Location) >= 4) { pirate.Sail(nearestShip); Main.didTurn.Add(pirate.Id); return(Utils.GetPirateStatus(pirate, "Kamikazad on ship")); } int abstainRadius = 8 * pirate.MaxSpeed; if (Utils.GetMyHolders().Count() > 1) { var secondHolder = Utils.GetMyHolders().First(h => h.Id != pirate.Id); abstainRadius = 3 * (pirate.MaxSpeed + secondHolder.MaxSpeed); if (abstainRadius / 2 < pirate.Distance(nearestShip)) { traits.Add(new TraitRateByEnemy(abstainRadius, 100, secondHolder.UniqueId)); } } var path = new Path(pirate.GetLocation(), nearestShip.Location, traits); bool nearWormHole = game.__wormholes.Any() && game.__wormholes.Any(w => w.TurnsToReactivate <= 2 && pirate.Distance(w) < w.WormholeRange + pirate.MaxSpeed); bool safe = (threats.Any() && game.PushDistance + game.AsteroidSize <= threats.OrderBy(pirate.Distance).First().Distance(pirate)) && !game.GetLivingAsteroids().Any(a => a.Distance(pirate) <= a.Size + pirate.MaxSpeed * 2); if (!nearWormHole && safe && (!threats.Any() && pirate.Distance(nearestShip) < abstainRadius || pirate.Distance(nearestShip) <= Chunk.size || path.GetSailLocations().Count <= 1)) { pirate.Sail(nearestShip); Main.didTurn.Add(pirate.Id); return(Utils.GetPirateStatus(pirate, "Sailing directly to ship")); } Location pathPopLocation = path.Pop(); Location nextSailLocation = pathPopLocation; if (Utils.GetMyHolders().Count() > 1 && safe && threats.Count() >= pirate.NumPushesForCapsuleLoss) { var otherMiner = Utils.GetMyHolders().First(h => h.Id != pirate.Id); bool sameTargetShip = Utils.OrderByDistance(game.GetMyMotherships().ToList(), otherMiner.Location).First() == nearestShip; bool checkI = pirate.Distance(nearestShip) < otherMiner.Distance(nearestShip); bool checkII = Chunk.size * 4 < otherMiner.Distance(nearestShip) - pirate.Distance(nearestShip); if (sameTargetShip && checkI && checkII) { nextSailLocation = pirate.Location.Towards(pathPopLocation, pirate.MaxSpeed / 2); } } if (Utils.PiratesWithTask(TaskType.BOOSTER).Any() && safe) { var closestBooster = Utils.OrderByDistance(Utils.PiratesWithTask(TaskType.BOOSTER), pirate.Location).First(); bool cloestToBooster = Utils.OrderByDistance(Utils.GetMyHolders(), closestBooster.Location).First().Id == pirate.Id; bool checkI = threats.Any() && threats.First().MaxSpeed * 2 <= threats.First().Distance(pirate); if (cloestToBooster && game.PushRange < pirate.Distance(closestBooster) && checkI) { nextSailLocation = pirate.Location.Towards(pathPopLocation, closestBooster.MaxSpeed / 2); } } return(Utils.GetPirateStatus(pirate, "Sailing to goal, " + Sailing.SafeSail(pirate, nextSailLocation.GetLocation()))); }
/// <summary> /// Makes the pirate try to push an enemy pirate. Returns true if it did. /// </summary> /// <param name="pirate">The pushing pirate.</param> /// <param name="game">The current game state.</param> /// <returns>true if the pirate pushed.</returns> private bool TryPush(Pirate pirate, PirateGame game) { foreach (Pirate ally in game.GetMyLivingPirates()) { // IF WE HAVE CAP AND PIRATE IS THE CAPSULE HOLDER RETURN FALSE if (game.GetMyCapsule().Holder != null && game.GetMyCapsule().Holder == pirate) { return(false); } // IF WE HAVE CAP AND PIRATE CAN PUSH CAP HOLDER AND HE IS THE CLOSEST TO HIM WE RETURN TRUE if (game.GetMyCapsule().Holder != null && ally.CanPush(game.GetMyCapsule().Holder) && PiratesInRangeOfPush(game, game.GetMyCapsule().Holder)[0] == pirate) { ally.Push(game.GetMyCapsule().Holder, game.GetMyMothership()); System.Console.WriteLine($"pirate:{ally} did push capholder: {game.GetMyCapsule().Holder} to MOTHERSHIP"); return(true); } // IF WE DONT HAVE CAPSULE AND WE CAN PUSH THE CLOSEST PIRATE TO CAP LOCATION THAN DO IT! if (game.GetMyCapsule().Holder == null && ally.CanPush(xClosestToY(game.GetMyCapsule().InitialLocation, game.GetMyLivingPirates().Cast <GameObject>().ToList())[0] as Pirate)) { if ((xClosestToY(game.GetMyCapsule().InitialLocation, game.GetMyLivingPirates().Cast <GameObject>().ToList())[0] as Pirate).Distance(game.GetMyCapsule().InitialLocation) >= game.PirateMaxSpeed * 3 && ally.CanPush(xClosestToY(game.GetMyCapsule().InitialLocation, game.GetMyLivingPirates().Cast <GameObject>().ToList())[0] as Pirate) && xClosestToY(game.GetMyCapsule().InitialLocation, game.GetMyLivingPirates().Cast <GameObject>().ToList())[0] as Pirate == ally) { ally.Push(xClosestToY(game.GetMyCapsule().InitialLocation, game.GetMyLivingPirates().Cast <GameObject>().ToList())[0] as Pirate, game.GetMyCapsule().InitialLocation); System.Console.WriteLine($"pirate:{ally} did push closest to cap: {game.GetMyCapsule().Holder} to CAP"); return(true); } } } //WE PREFFER TO PUSH OURSELVES FIRST! foreach (Pirate enemy in game.GetEnemyLivingPirates()) { //TODO : IF TIGBORET PUSH HIM TO BUY SOME TIME // IF ENEMY HAS CAP AND WE HAVE MORE THAN 2 TO DROP HIS CAP if (game.GetEnemyCapsule().Holder != null && enemy == game.GetEnemyCapsule().Holder&& PiratesInRangeOfPush(game, enemy).Count > 1 && pirate.CanPush(enemy)) { pirate.Push(enemy, EnemyCanExplode(game, enemy)); return(true); } // IF ENEMY CAN GO OUT OF MAP KICK HIM! if (!EnemyCanExplode(game, enemy).Equals(enemy.InitialLocation.Add(enemy.InitialLocation))) { if (isOneFromThisList(game, PiratesInRangeOfPush(game, enemy), pirate)) { pirate.Push(enemy, EnemyCanExplode(game, enemy)); return(true); } } // Check if the pirate can push the enemy. /*if (pirate.CanPush(enemy)) * { * // Push enemy! * //***POSSIBLE BUG*** * pirate.Push(enemy, EnemyCanExplode(game, enemy)); * * // Print a message. * System.Console.WriteLine("pirate " + pirate + " pushes " + enemy + " towards " + EnemyCanExplode(game, enemy)); * * // Did push. * return true; * }*/ } // Didn't push. return(false); }