示例#1
0
        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);
        }
 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));
         }
     }
 }
示例#3
0
        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);
        }
示例#4
0
 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);
 }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
 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);
 }
示例#8
0
 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);
 }
示例#9
0
        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);
        }
示例#10
0
 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);
 }
示例#11
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);
 }
示例#12
0
        /// <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"));
        }
示例#13
0
        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);
        }
示例#14
0
        /// <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"));
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
 /// <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);
 }
示例#19
0
        /// <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);
        }
示例#20
0
        /// <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);
                }
            }

            Pirate enemyToPush = Protect();

            if (enemyToPush != null)
            {
                if (pirate.CanPush(enemyToPush))
                {
                    //Sorry about those location numbers :\
                    //#Onemanarmy
                    if (GameSettings.Game.GetMyMotherships().Length == 0 && GameSettings.Game.GetMyCapsules().Length == 0)
                    {
                        pirate.Push(enemyToPush, new Location(3097, 1557));
                        return(true);
                    }
                    Location pushTowardsOutOfMap = FieldAnalyzer.GetCloseEnoughToBorder(enemyToPush, Pirate.PushDistance);
                    if (pushTowardsOutOfMap != null)
                    {
                        pirate.Push(enemyToPush, pushTowardsOutOfMap);
                        return(true);
                    }
                    else
                    {
                        if (GameSettings.Game.GetEnemyMotherships().Length > 0)
                        {
                            Location oppositeSide = enemyToPush.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 = enemyToPush.GetLocation().Towards(enemyToPush.GetLocation().Add(oppositeSide), 600);
                            Pirate.Push(enemyToPush, oppositeSide);
                            //Print a message.
                            //GameSettings.Game.Debug("defender " + Pirate + " pushes " + enemyToPush + " towards " + enemyToPush.InitialLocation);
                            //Did push.
                            return(true);
                        }
                        else
                        {
                            Location oppositeSide = enemyToPush.GetLocation().Subtract(new Location(0, 0));
                            //Vector: the distance (x,y) you need to go through to go from the mothership to the enemy
                            oppositeSide = enemyToPush.GetLocation().Towards(enemyToPush.GetLocation().Add(oppositeSide), 600);
                            Pirate.Push(enemyToPush, oppositeSide);
                        }
                        return(true);
                    }
                }
            }

            GameSettings.Game.Debug("Push distance = " + pirate.PushDistance);
            GameSettings.Game.Debug("Reached Wormhole zone");
            bool canPushWormhole = true;

            foreach (Wormhole wormhole in GameSettings.Game.GetAllWormholes())
            {
                GameSettings.Game.Debug("wormhole foreach");
                if (pirate.CanPush(wormhole))
                {
                    //GameSettings.Game.Debug("pirate.PushRange ==> " + pirate.PushRange);
                    //GameSettings.Game.Debug("pirate.MaxSpeed ==> " + pirate.MaxSpeed);
                    GameSettings.Game.Debug("wormhole.Distance(pirate)" + wormhole.Distance(pirate));

                    if (GameSettings.Game.GetEnemyMotherships().Length > 0)
                    {
                        Mothership mothership   = FieldAnalyzer.FindClosestMotherShip(pirate);
                        Pirate     enemyCarrier = FieldAnalyzer.GetMostThreatningEnemyCarrier(mothership);
                        if (enemyCarrier != null)
                        {
                            //Checks if the enemyPirate can come in more then 5 turns
                            GameSettings.Game.Debug("pirate.CanPush(wormhole) = " + pirate.CanPush(wormhole));
                            //Checks if the enemyPirate can come in more then 8 turns
                            if (enemyCarrier.Distance(pirate) < enemyCarrier.MaxSpeed * 8)
                            {
                                canPushWormhole = false;
                            }
                            if (canPushWormhole)
                            {
                                int cols = GameSettings.Game.Cols;
                                int rows = GameSettings.Game.Rows;
                                //Push to the center for now
                                pirate.Push(wormhole, new Location(rows / 2, cols / 2));
                                GameSettings.Game.Debug("Pirate pushed wormhole");
                                return(true);
                            }
                        }
                    }
                }
            }

            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");
        }
示例#22
0
 public void PushPair(Pirate pirate1, Pirate pirate2, Location destination) //Take two pirates and a destination and lets them push eachother towards the destination
 {
     pirate1.Push(pirate2, destination);
     pirate2.Push(pirate1, destination);
 }
        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)));
        }
示例#24
0
        /// <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);
        }
示例#25
0
        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())));
        }
示例#26
0
        /// <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"));
        }
示例#27
0
        /// <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());
        }