示例#1
0
        /// <summary>
        /// Executes the best commands out of the given ActionsChooser
        /// </summary>
        public void Execute(ActionsChooser chooser)
        {
            // if chooser is null
            if (chooser == null)
            {
                return;
            }

            ActionsPack bestPack = chooser.ChooseBestStableCombination();

            //increase readability of game-log
            this.Log(LogType.Events, LogImportance.ExtremelyImportant, " ");
            this.Log(LogType.Events, LogImportance.ExtremelyImportant, "------START-EVENT-INFO------");

            // execute all the commands from the best ActionsPack chosen
            foreach (Command cmd in bestPack.GetCommands())
            {
                if (cmd == null)
                {
                    continue;
                }

                cmd.Execute(this.NativeObject);

                this.Log(LogType.Events, LogImportance.ExtremelyImportant, cmd); // log the command in-game
                foreach (string info in cmd.GetAdditionalInformation())          // log the additional info in-game
                {
                    this.Log(LogType.Events, LogImportance.ExtremelyImportant, "Additional information: {0}", info);
                }
                this.Log(LogType.Events, LogImportance.ExtremelyImportant, " ");
            }
            //increase readability of game-log
            this.Log(LogType.Events, LogImportance.ExtremelyImportant, "-------END-EVENT-INFO-------");
            this.Log(LogType.Events, LogImportance.ExtremelyImportant, " ");
        }
示例#2
0
        //////////Methods//////////

        /// <summary>
        /// The method that the engine calls whenever our turn arrives
        /// </summary>
        public void DoTurn(IPirateGame game)
        {
            game.Debug("start turn at {0}", game.TimeRemaining());
            // if this is the first turn
            if (game.GetTurn() == 1)
            {
                // create a new game enviroment
                this.game = new Game(game);

                // initialize the event list, and fill it up!
                this.events = new List <Event>();
                this.AddEvents();

                // initialize the states manager, and fill it up!
                this.statesManager = new StatesManager();
                this.AddStates();

                // initialize the actions chooser
                this.actionsChooser = new ActionsChooser(this.game);
            }
            // if this is NOT the first turn
            else
            {
                // update the game enviroment
                this.game.Update(game);

                // update the states manager
                this.statesManager.Update(this.game);
            }

            this.game.Log(LogType.Timing, LogImportance.Important, "finish update at {0}", this.game.GetTimeRemaining());

            // run the best events for us
            this.UpdateChooser();
            this.game.Execute(this.actionsChooser);

            this.game.Log(LogType.Timing, LogImportance.ExtremelyImportant, "finish turn at {0}", this.game.GetTimeRemaining());
            game.Debug("real finish at {0}", game.TimeRemaining());
        }
示例#3
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            //Counts how many of the pirates in the cluster carry treasure, will be used for event value.
            List <Pirate> treasurePiratesInCluster = this.hotspot.Intersect(game.GetEnemyPirates(PirateState.CarryingTreasure)).ToList();
            int           valueInCluster           = treasurePiratesInCluster.Sum(pirate => pirate.CarriedTreasureValue);
            List <Pirate> protectors = game.GetEnemyPiratesInAttackRange(this.hotspot, PirateState.Free);

            bool myPirateInCluster = false;

            int drunkDouches = game.GetMyPiratesInAttackRange(this.hotspot, PirateState.Drunk).Count;

            //Checks if there is a pirate in the cluster already, if so - tells it to be a smart douchebag!
            foreach (Pirate myPirate in game.GetMyPirates(PirateState.Free))
            {
                if (Game.InAttackRange(myPirate, this.hotspot, myPirate.AttackRadius)) // pirate is in cluster already!
                {
                    myPirateInCluster = true;
                    //Release the douche!;
                    if (treasurePiratesInCluster.Count > 0)
                    {
                        foreach (Pirate enemy in treasurePiratesInCluster) // go to an enemy with treasure spawn to lock it (act as a douch)
                        {
                            if (game.GetPirateOn(enemy.InitialLocation) != null && game.GetPirateOn(enemy.InitialLocation) != myPirate)
                            {
                                continue;
                            }
                            List <Pirate> threats = game.GetEnemyDangerousPiratesInAttackRange(myPirate);

                            var sailOptions = game.GetCompleteSailOptions(myPirate, enemy.InitialLocation, false, Terrain.CurrentTreasureLocation);
                            foreach (var pair in sailOptions)
                            {
                                if (pair.Key.Equals(enemy.InitialLocation) || game.GetEnemyDangerousPiratesInAttackRange(pair.Key).Union(threats).Count() == 0 || myPirate.DefenseDuration > 0)
                                {
                                    ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);

                                    ap.AddEnemyPirate(enemy);

                                    double value = DOUCH_SPAWN_CAMP + valueInCluster * TREASURE_VAL + (this.hotspot.Count - treasurePiratesInCluster.Count) * NO_TREASURE_VAL - Game.ManhattanDistance(enemy.InitialLocation, enemy) - Utils.Pow(pair.Value, 1.2);
                                    if (enemy.HasPowerup(SpeedPowerup.NAME) && statesManager.GetState <ImpendingDoomState>().IsDoomIncoming)
                                    {
                                        value *= IMPENDING_POWERUP_MULTIPLYER;
                                    }

                                    ap.BurnInformation("Made in DouchebagEvent - case: spawn-camp pirate {0}, Value: {1:F3}", enemy.Id, value);

                                    chooser.AddActionsPack(ap, value);
                                }
                            }
                        }
                    }

                    /*else
                     * {
                     *  foreach (var pair in game.GetCompleteSailOptions(myPirate, this.hotspot, 0, 0, myPirate.MaxSpeed, true, 0, myPirate.MaxSpeed, 2, Terrain.CurrentTreasureLocation, Terrain.EnemyLocation)) // or return to the center of the cluster
                     *  {
                     *      //ActionsPack ap = ActionsPack.NewSailPack(game, myPirate, pair.Key, this.Id);
                     *      ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);
                     *
                     *      double value = DOUCH_CLUSTER_CAMP + (this.enemiesInCluster.Count - treasurePiratesInCluster.Count) * NO_TREASURE_VAL - Utils.Pow(pair.Value, 1.2) - PROTECTOR_VAL * protectors.Count + treasurePiratesInCluster.Count * TREASURE_VAL;
                     *
                     *      ap.BurnInformation("Made in DouchebagEvent case: cluster-camp, Value: {0:F3}", value);
                     *
                     *      chooser.AddActionsPack(ap, value);
                     *  }
                     * }*/
                }
            }

            if (!myPirateInCluster && drunkDouches < treasurePiratesInCluster.Count) // no pirate in cluster - send in the douches! (become a doouche)
            {
                foreach (Pirate myPirate in game.GetMyPirates(PirateState.Free))
                {
                    foreach (Pirate enemy in treasurePiratesInCluster) // go to an enemy with treasure spawn to lock it (act as a douch)
                    {
                        var sailOptions = game.GetCompleteSailOptions(myPirate, enemy.InitialLocation, Terrain.CurrentTreasureLocation);
                        foreach (var pair in sailOptions)
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);

                            ap.AddEnemyPirate(enemy);

                            double value = DOUCH_BECOME + valueInCluster * TREASURE_VAL + (this.hotspot.Count - treasurePiratesInCluster.Count) * NO_TREASURE_VAL - Game.ManhattanDistance(enemy.InitialLocation, enemy) - Utils.Pow(pair.Value, 1.5) - PROTECTOR_VAL * protectors.Count;
                            if (enemy.HasPowerup(SpeedPowerup.NAME) && statesManager.GetState <ImpendingDoomState>().IsDoomIncoming)
                            {
                                value *= IMPENDING_POWERUP_MULTIPLYER;
                            }
                            ap.BurnInformation("Made in DouchebagEvent case: become spawn-camper on pirate {0}, Value: {1:F3}", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }

                    /*var sailOptions = game.GetCompleteSailOptions(myPirate, this.hotspot, 0, 0, myPirate.MaxSpeed, true, 0, myPirate.MaxSpeed, 2, Terrain.CurrentTreasureLocation);
                     *
                     * foreach (var pair in sailOptions)
                     * {
                     *  if (sailOptions[0].Value > pair.Value)  //sail only if it's actually better than staying in place
                     *  {
                     *      //ActionsPack ap = ActionsPack.NewSailPack(game, myPirate, pair.Key, this.Id);
                     *      ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);
                     *
                     *      double value = DOUCH_BECOME + treasurePiratesInCluster.Count * TREASURE_VAL + (this.enemiesInCluster.Count - treasurePiratesInCluster.Count) * NO_TREASURE_VAL - Utils.Pow(pair.Value, 1.25) - PROTECTOR_VAL * protectors.Count;
                     *      value = 0.2 * value;
                     *
                     *      ap.BurnInformation("Made in DouchebagEvent case: become cluster-camper, Value: {0:F3}", value);
                     *
                     *      chooser.AddActionsPack(ap, value);
                     *  }
                     * }*/
                }
            }
        }
示例#4
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanMove || this.myPirate.State != PirateState.CarryingTreasure) // can't move = can't dodge / if I'm shielded no point in dodging
            {
                return;
            }

            TreasureDancingState treasureDancingState = statesManager.GetState <TreasureDancingState>();
            bool dodgedLastTurn = treasureDancingState.IsPirateDancing(this.myPirate);

            List <Pirate> enemies = game.GetEnemyPirates(PirateState.Free);

            if (enemies.Count == 0) // no enemies = no threat
            {
                return;
            }

            if (!dodgedLastTurn) //Pirate is carrying Treasure - can only move 1 step
            {
                foreach (var pair in GetTreasureDodgeOptions(this.myPirate, game))
                {
                    ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                    double distanceLeft        = Game.ManhattanDistance(pair.Key, this.myPirate.InitialLocation);
                    double getCloserPrioritize = (distanceLeft == 0 ? myPirate.CarriedTreasureValue * 65536 : (distanceLeft + 1.0) / (distanceLeft)); //This is so it would prioritize moving in the direction that makes us closer.

                    double value = myPirate.CarriedTreasureValue * PIRATE_WITH_TREASURE_DODGING - pair.Value / (pair.Value + 1.0) + getCloserPrioritize;

                    ap.BurnInformation("Made by DodgeEvent - case: dodge attack, Value: {0:F3}", value);

                    chooser.AddActionsPack(ap, value);
                }
            }
            else
            {
                ActionsPack ap    = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, this.myPirate), base.Id);
                double      value = myPirate.CarriedTreasureValue * PIRATE_WITH_TREASURE_DODGING - 0.1;
                ap.BurnInformation("Made by DodgeEvent - case: dodge ram stage 2, Value: {0:F3}", value);
                chooser.AddActionsPack(ap, value);
            }
            foreach (var pair in GetRamDodgeOptions(this.myPirate, game))
            {
                ActionsPack ap    = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);
                double      value = myPirate.CarriedTreasureValue * PIRATE_WITH_TREASURE_DODGING - pair.Value / (pair.Value + 1.0);
                ap.BurnInformation("Made by DodgeEvent - case: dodge ram stage 1, Value: {0:F3}", value);
                chooser.AddActionsPack(ap, value);
            }
        }
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanMove || this.myPirate.State != PirateState.Free) //If my pirate can't move, or isn't free he can't Seek&Destroy
            {
                return;
            }

            // get all the enemy pirates with treasure, sorted by their manhattan distance to me
            List <Pirate> enemyPiratesWithTreasure = game.GetEnemyClosestPirates(this.myPirate, PirateState.CarryingTreasure);

            ImpendingDoomState impendingDoom = statesManager.GetState <ImpendingDoomState>();

            double pirateCountMultiplier = (double)game.ActionsPerTurn / (double)game.GetAllEnemyPiratesCount();

            pirateCountMultiplier = pirateCountMultiplier > 1 ? 1.0 : pirateCountMultiplier;

            // If the enemy has treasure
            foreach (Pirate enemy in enemyPiratesWithTreasure)
            {
                if (Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius - 1))
                {
                    continue; //We are in attack range to AttackEvent. This should be handled by it.
                }
                int distanceLeftForEnemy = Game.ManhattanDistance(enemy, enemy.InitialLocation);

                if (distanceLeftForEnemy <= 1 || distanceLeftForEnemy < Game.ManhattanDistance(this.myPirate, enemy) / game.ActionsPerTurn)
                {
                    continue; //It's too late now, we can't reach him. Douchebag should handle this.
                }
                //get the sailing directions
                ILocateable dest             = enemy;
                int         distanceFromDest = (int)this.myPirate.AttackRadius - 2;
                foreach (Powerup up in game.GetPowerups())
                {
                    if (up is AttackPowerup && Game.OnTrack(myPirate, enemy, up))
                    {
                        dest             = up;
                        distanceFromDest = 0;
                        break;
                    }
                }

                var sailOptions = game.GetCompleteSailOptions(this.myPirate, enemy, 0, distanceFromDest, Terrain.CurrentTreasureLocation, Terrain.EnemyLocation);

                //Get sailing packs - with Value and Burnt information according to the Distance Category from the enemy
                switch (GetDistanceCategory(game, enemy, Game.EuclideanDistance(myPirate, enemy)))
                {
                case DistanceCategory.Close:     //enemy is close to me
                    foreach (var pair in sailOptions)
                    {
                        if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                            ap.AddEnemyPirate(enemy);

                            double value = CLOSE_ENEMY_HAS_TREASURE * enemy.CarriedTreasureValue - Utils.Pow((pair.Value), 1.5) - Game.ManhattanDistance(pair.Key, enemy.InitialLocation);
                            if (impendingDoom.IsDoomIncoming)
                            {
                                value = value * IMPENDING_DOOM_MULTIPLYER;
                            }
                            if (myPirate.HasPowerup(AttackPowerup.NAME))
                            {
                                value = value * ATTACK_POWERUP_MULTIPLYER;
                            }

                            //value *= pirateCountMultiplier;

                            ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: close treasure", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                    break;

                case DistanceCategory.Medium:     //enemy is in medium range
                    foreach (var pair in sailOptions)
                    {
                        if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                            ap.AddEnemyPirate(enemy);

                            double value = MEDIUM_RANGE_ENEMY_HAS_TREASURE * enemy.CarriedTreasureValue - Utils.Pow((pair.Value) + (game.ActionsPerTurn + 1) / 2 - 2, 1.3) - Game.ManhattanDistance(pair.Key, enemy.InitialLocation);
                            if (enemy.HasPowerup(SpeedPowerup.NAME))
                            {
                                value += ENEMY_WITH_SPEED_UP_AND_TREASURE;
                            }
                            if (impendingDoom.IsDoomIncoming)
                            {
                                value = value * IMPENDING_DOOM_MULTIPLYER;
                            }
                            if (myPirate.HasPowerup(AttackPowerup.NAME))
                            {
                                value = value * ATTACK_POWERUP_MULTIPLYER;
                            }

                            value *= pirateCountMultiplier;

                            ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: medium treasure", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                    break;

                case DistanceCategory.Far:     //enemy is far away
                    foreach (var pair in sailOptions)
                    {
                        if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                            ap.AddEnemyPirate(enemy);

                            double value = FAR_RANGE_ENEMY_HAS_TREASURE * enemy.CarriedTreasureValue - Utils.Pow((pair.Value) - game.ActionsPerTurn / 3 - 2, 1.2) - Game.ManhattanDistance(pair.Key, enemy.InitialLocation);
                            if (enemy.HasPowerup(SpeedPowerup.NAME))
                            {
                                value += ENEMY_WITH_SPEED_UP_AND_TREASURE;
                            }
                            if (impendingDoom.IsDoomIncoming)
                            {
                                value = value * IMPENDING_DOOM_MULTIPLYER;
                            }
                            if (myPirate.HasPowerup(AttackPowerup.NAME))
                            {
                                value = value * ATTACK_POWERUP_MULTIPLYER;
                            }

                            value *= pirateCountMultiplier;

                            ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: far treasure", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                    break;
                }
            }
            Pirate closest = null;

            if (game.GetEnemyPiratesCount(PirateState.Free) > 0)
            {
                closest = game.GetEnemyClosestPirates(myPirate, PirateState.Free)[0];
            }
            //if the enemy doesn't have a treasure
            foreach (Pirate enemy in game.GetEnemyPirates(PirateState.Free))
            {
                if (Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius))
                {
                    continue; //We are in attack range to AttackEvent. This should be handled by it.
                }
                //get the sailing directions
                var sailOptions = game.GetCompleteSailOptions(this.myPirate, enemy, 0, (int)this.myPirate.AttackRadius, Terrain.CurrentTreasureLocation, Terrain.EnemyLocation);

                //Get sailing packs - with Value and Burnt information according to the Distance Category from the enemy
                if (enemy.PowerupCount > 0)
                {
                    switch (GetDistanceCategory(game, enemy, Game.EuclideanDistance(myPirate, enemy)))
                    {
                    case DistanceCategory.Close:     //enemy is close to me
                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = CLOSE_ENEMY_HAS_POWERUP - Utils.Pow((pair.Value), 1.3);
                                if (myPirate.HasPowerup(AttackPowerup.NAME))
                                {
                                    value = value * ATTACK_POWERUP_MULTIPLYER;
                                }

                                value *= pirateCountMultiplier;

                                ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: close powerup", enemy.Id, value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                        break;

                    case DistanceCategory.Medium:     //enemy is in medium range
                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = MEDIUM_RANGE_ENEMY_HAS_POWERUP - Utils.Pow((pair.Value) + (game.ActionsPerTurn + 1) / 2 - 2, 1.2);
                                if (myPirate.HasPowerup(AttackPowerup.NAME))
                                {
                                    value = value * ATTACK_POWERUP_MULTIPLYER;
                                }

                                value *= pirateCountMultiplier;

                                ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: medium powerup", enemy.Id, value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                        break;

                    case DistanceCategory.Far:     //enemy is far away
                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = FAR_RANGE_ENEMY_HAS_POWERUP - Utils.Pow((pair.Value) - game.ActionsPerTurn / 3 - 2, 1);
                                if (myPirate.HasPowerup(AttackPowerup.NAME))
                                {
                                    value = value * ATTACK_POWERUP_MULTIPLYER;
                                }

                                value *= pirateCountMultiplier;

                                ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: far powerup", enemy.Id, value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                        break;
                    }
                }
                else if (enemy == closest || !game.EnemyArmada)
                {
                    if (impendingDoom.IsDoomIncoming)
                    {
                        return;
                    }

                    if (myPirate.CanAttack) //Seek and Destroy a non-treasure enemy only if you can shoot him
                    {
                        if (Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius))
                        {
                            continue; //We are in attack range to AttackEvent. This should be handled by it.;
                        }
                        //Get sailing packs
                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value) //sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = Utils.Max(ENEMY_HAS_NO_TREASURE - Utils.Pow(pair.Value, 0.7), 1.0 / (pair.Value + 1.0));
                                if (myPirate.HasPowerup(AttackPowerup.NAME))
                                {
                                    value = value * ATTACK_POWERUP_MULTIPLYER;
                                }
                                value *= pirateCountMultiplier;

                                ap.BurnInformation("Made in SeekAndDestroyEvent, against {0}, value: {1:F3}, case: no Treasure", enemy.Id, value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                    }
                }
            }
        }
示例#6
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanMove || this.myPirate.State != PirateState.Free)
            {
                return;
            }

            int myMaxSteps = myPirate.MaxSpeed;
            int enemyMaxSteps;

            double multiplyer = Utils.Pow(1 - ((double)game.GetMyPiratesCount(PirateState.CarryingTreasure)) / game.GetMyPiratesCount(PirateState.Free, PirateState.CarryingTreasure), 2);

            ThreatenedTreasureState treasureState = statesManager.GetState <ThreatenedTreasureState>();
            List <Treasure>         treasures     = treasureState.GetThreatenedTreasures().OrderBy(t => Game.ManhattanDistance(t, this.myPirate)).ToList();

            while (treasures.Count > 0 && game.GetPirateOn(treasures[0]) != null)
            {
                treasures.Remove(treasures[0]);
            }

            if (treasures.Count == 0)
            {
                return;
            }

            if (Game.ManhattanDistance(this.myPirate, treasures[0]) > myMaxSteps) //only do area clear if close enough to capture treasure
            {
                return;
            }

            Treasure closestTreasure = treasures[0];

            multiplyer *= closestTreasure.Value;

            foreach (Pirate enemy in game.GetEnemyPirates(PirateState.Free))
            {
                enemyMaxSteps = enemy.MaxSpeed;

                if (Game.ManhattanDistance(enemy, closestTreasure) > enemyMaxSteps)//only do area clear if enemy is close enough to capture treasure
                {
                    continue;
                }

                if (!Game.InAttackRange(this.myPirate, closestTreasure, this.myPirate.AttackRadius + 1)) //Get closer.
                {
                    var sailOptions = game.GetCompleteSailOptions(this.myPirate, closestTreasure, (int)this.myPirate.AttackRadius + 1, (int)this.myPirate.AttackRadius + 1, Terrain.InEnemyRange, Terrain.CurrentTreasureLocation);
                    foreach (var pair in sailOptions)
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), this.Id);

                        ap.AddTreasure(treasures[0]);

                        double value = CLEAR_VALUE * multiplyer;

                        ap.BurnInformation("Made in AreaClearEvent on Treasure {0} - case: not close enough, Value {1:F3}", closestTreasure.Id, value);

                        chooser.AddActionsPack(ap, value);
                    }
                }
                else if (Game.InAttackRange(this.myPirate, closestTreasure, this.myPirate.AttackRadius) && this.myPirate.CanAttack && enemy.DefenseDuration == 0 && Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius)) //Attack enemy.
                {
                    ActionsPack ap = ActionsPack.NewCommandPack(game, new AttackCommand(this.myPirate, enemy), this.Id);

                    ap.AddTreasure(treasures[0]);
                    ap.AddEnemyPirate(enemy);

                    double value = CLEAR_VALUE * multiplyer;

                    ap.BurnInformation("Made in AreaClearEvent on Treasure {0} - case: too close, attack pirate {1}, Value: {2:F3}", closestTreasure.Id, enemy.Id, value);

                    chooser.AddActionsPack(ap, value);
                }
                else if (Game.InAttackRange(this.myPirate, closestTreasure, this.myPirate.AttackRadius + 1)) //Stay Still. TODO: ask Adi/Itai why isn't this an else
                {
                    ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, this.myPirate), this.Id);
                    ap.AddTreasure(closestTreasure);

                    double value = CLEAR_VALUE * multiplyer;

                    ap.BurnInformation("Made in AreaClearEvent on Treasure {0} - case: close enough, Value {1:F3}", closestTreasure.Id, value);

                    chooser.AddActionsPack(ap, value);
                }
            }
        }
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanMove || this.myPirate.State != PirateState.Free) //If my pirate can't move or isn't free, he can't go to fetch treasures.
            {
                return;
            }

            // Get threatened treasure state
            ThreatenedTreasureState treasureState = statesManager.GetState <ThreatenedTreasureState>();
            // Get all the free treasures and sort them by manhattan distance to me
            List <Treasure> freeTreasures = treasureState.GetSafeTreasures().OrderBy(t => Game.ManhattanDistance(t, this.myPirate)).ToList();


            // calculate the maximum amount of treasures to check
            int maxTreasuresToCheck = (int)Utils.Min(freeTreasures.Count, game.GetMyPiratesCount(PirateState.Free), game.ActionsPerTurn, game.MaxCommandsPerTurn);

            // remove all the excess treasures, based on their value
            Dictionary <int, int> usedTreasuresDict = new Dictionary <int, int>();   // the key is the value of the treasure, and the value is how many treasures with the value are already in the list

            for (int i = 0; i < freeTreasures.Count;)
            {
                if (usedTreasuresDict.ContainsKey(freeTreasures[i].Value))
                {
                    usedTreasuresDict[freeTreasures[i].Value]++;
                    if (usedTreasuresDict[freeTreasures[i].Value] > maxTreasuresToCheck)
                    {
                        freeTreasures.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }
                else
                {
                    usedTreasuresDict.Add(freeTreasures[i].Value, 1);
                    i++;
                }
            }


            double multiplyer = Utils.Pow(1 - ((double)game.GetMyPiratesCount(PirateState.CarryingTreasure)) / game.GetMyPiratesCount(PirateState.Free, PirateState.CarryingTreasure), 2);

            // try to sail to each treasure
            foreach (Treasure t in freeTreasures)
            {
                if (game.GetPirateOn(t) != null) // there is a pirate where the treasure is, most likely a drunk one. Leave it be.
                {
                    continue;
                }

                ILocateable dest = t;
                // search for a speed powerup on the way to the treasure
                foreach (Powerup up in game.GetPowerups())
                {
                    if (up is SpeedPowerup && Game.OnTrack(myPirate, t, up))
                    {
                        dest = up;
                        break;
                    }
                }

                var sailOptions    = game.GetCompleteSailOptions(this.myPirate, dest, Terrain.EnemyLocation, Terrain.CurrentTreasureLocation);
                int maxActionsUsed = (int)Utils.Min(this.myPirate.MaxSpeed, game.ActionsPerTurn, Game.ManhattanDistance(this.myPirate, dest));

                foreach (var pair in sailOptions)
                {
                    if (sailOptions[0].Value > pair.Value) //sail only if it's actually better than staying in place
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                        ap.AddTreasure(t);

                        double returnDistance = Game.ManhattanDistance(this.myPirate.InitialLocation, t);
                        double maxDistance    = game.Rows + game.Collumns;
                        double value          = (FETCH_VALUE - Utils.Pow(pair.Value, 0.9)) * multiplyer * ((maxDistance - returnDistance) / (maxDistance));
                        if (game.GetTreasuresCount(TreasureState.BeingCarried, TreasureState.Taken) == 0 && Game.ManhattanDistance(pair.Key, this.myPirate) == maxActionsUsed)
                        {
                            value += GAME_START_MULT;
                        }
                        value *= t.Value;
                        if (myPirate.HasPowerup(SpeedPowerup.NAME))
                        {
                            value *= SPEED_POWERUP_MULTIPLYER;
                        }

                        ap.BurnInformation("Made in FetchTreasureEvent. Fetching Treasure: {0}, value: {1:F3}", t.Id, value);

                        chooser.AddActionsPack(ap, value);
                    }
                }
            }
        }
示例#8
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (this.treasurePirate.State != PirateState.CarryingTreasure)
            {
                return;
            }

            //Counts how many of the pirates in the cluster carry treasure, will be used for event value.
            List <Pirate> enemyPirates = new List <Pirate>();

            foreach (Pirate enemy in game.GetEnemyPirates(PirateState.Free))
            {
                if (Game.InAttackRange(enemy, treasurePirate, enemy.AttackRadius + enemy.MaxSpeed))
                {
                    enemyPirates.Add(enemy);
                }
            }

            enemyPirates = enemyPirates.OrderBy(p => Game.EuclideanDistance(p, this.treasurePirate)).ToList();

            if (enemyPirates.Count == 0) //No threats
            {
                return;
            }

            TreasureDancingState  treasureDancingState = statesManager.GetState <TreasureDancingState>();
            ImpendingVictoryState impendingVictory     = statesManager.GetState <ImpendingVictoryState>();

            //Sends in an escort to destory/block an enemy
            foreach (Pirate myPirate in game.GetMyPirates(PirateState.Free))
            {
                //Bodyguard
                foreach (Pirate enemy in enemyPirates) // try to block an enemy's path/destroy it
                {
                    //1st priority - shoot him!
                    if (game.IsAttackPossible(myPirate, enemy) && !game.IsAttackPossible(enemy, treasurePirate))
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new AttackCommand(myPirate, enemy), base.Id);

                        double value = ESCORT_GUARD_VALUE - Game.EuclideanDistance(enemy, this.treasurePirate);
                        if (impendingVictory.IsVictoryIncoming)
                        {
                            value = value * IMPENDING_VICTORY_MULTIPLYER;
                        }
                        value *= this.treasurePirate.CarriedTreasureValue;

                        ap.BurnInformation("Made in EscortEvent - case: shoot threat, Value: {0:F3}", value);

                        chooser.AddActionsPack(ap, value);
                    }

                    //2nd priority - ram him!
                    if (Game.ManhattanDistance(enemy, myPirate) <= myPirate.MaxSpeed)
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, enemy), base.Id);

                        ap.AddEnemyPirate(enemy);

                        double value = ESCORT_GUARD_VALUE - Game.EuclideanDistance(enemy, this.treasurePirate) - Game.ManhattanDistance(enemy, myPirate);
                        if (impendingVictory.IsVictoryIncoming)
                        {
                            value = value * IMPENDING_VICTORY_MULTIPLYER;
                        }
                        value *= this.treasurePirate.CarriedTreasureValue;
                        ap.BurnInformation("Made in EscortEvent - case: ram enemy {0}, Value: {1:F3}", enemy.Id, value);

                        chooser.AddActionsPack(ap, value);
                    }

                    //3rd priority - body block him
                    if (Game.EuclideanDistance(enemy, treasurePirate) >= game.AttackRadius)
                    {
                        foreach (var pair in game.GetCompleteSailOptions(myPirate, ClosestOnCircle(myPirate.AttackRadius, this.treasurePirate, enemy), 0, 1, Terrain.CurrentTreasureLocation, Terrain.EnemyLocation))
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);

                            double value = ESCORT_VALUE - Game.EuclideanDistance(enemy, this.treasurePirate) - Utils.Pow(pair.Value, 1.3);
                            if (impendingVictory.IsVictoryIncoming)
                            {
                                value = value * IMPENDING_VICTORY_MULTIPLYER;
                            }
                            value *= this.treasurePirate.CarriedTreasureValue;

                            ap.BurnInformation("Made in EscortEvent - case: block enemy {0}, Value: {1:F3}", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                }
                //This code does escorts even if there are no enemies close, currently not implemented

                /*else if (enemyPirates.Count <= 0)
                 * {
                 *  foreach (var pair in game.GetCompleteSailOptions(myPirate, treasurePirate, Terrain.CurrentTreasureLocation, Terrain.EnemyLocation))
                 *  {
                 *      ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), base.Id);
                 *
                 *      double value = 0.8 * (ESCORT_VALUE - Utils.Pow(Game.ManhattanDistance(myPirate, pair.Key), 1.3));
                 *      if (impendingVictory.IsVictoryIncoming)
                 *          value = value * IMPENDING_VICTORY_MULTIPLYER;
                 *      value *= this.treasurePirate.CarriedTreasureValue;
                 *
                 *      ap.BurnInformation("Made in EscortEvent - case: become escort, Value: {0:F3}", value);
                 *
                 *      chooser.AddActionsPack(ap, value);
                 *  }
                 * }*/
            }
        }
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (this.treasure.CarryingPirate == null)
            {
                return;
            }
            Pirate carrying = this.treasure.CarryingPirate;

            double multiplyer = Utils.Pow(1 - ((double)game.GetMyPiratesCount(PirateState.CarryingTreasure)) / game.GetMyPiratesCount(PirateState.Free, PirateState.CarryingTreasure), 2);

            multiplyer *= this.treasure.Value;

            switch (carrying.Owner)
            {
            case Owner.Enemy:
                if (game.GetMyPiratesCount(PirateState.Free) > 0)
                {
                    Pirate myClosestPirate = game.GetMyClosestPirates(carrying, PirateState.Free)[0];

                    foreach (Pirate free in game.GetMyPirates(PirateState.Free))
                    {
                        if (free == myClosestPirate)
                        {
                            continue;
                        }

                        var sailOptions = game.GetCompleteSailOptions(free, treasure.InitialLocation, Terrain.EnemyLocation, Terrain.CurrentTreasureLocation);

                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(free, pair.Key), base.Id);

                                ap.AddTreasure(treasure);

                                double returnDistance = Game.ManhattanDistance(free.InitialLocation, treasure);
                                double maxDistance    = game.Rows + game.Collumns;
                                double value          = (TREASURE_VALUE - Utils.Pow(pair.Value, 0.9)) * multiplyer * ((maxDistance - returnDistance) / (maxDistance));
                                if (myClosestPirate.HasPowerup(SpeedPowerup.NAME))
                                {
                                    value = value * SPEED_POWERUP_MULTIPLYER;
                                }

                                switch (GetDistanceCategory(game, myClosestPirate, Game.EuclideanDistance(carrying, myClosestPirate)))
                                {
                                case DistanceCategory.Close:
                                    value = value * ENEMY_HAS_TREASURE_ALLY_CLOSE;
                                    ap.BurnInformation("Made in GhostTreasureEvent, collecting treasure {0} from {1}, value: {2:F3}, case: close ally", treasure.Id, carrying.Id, value);
                                    break;

                                case DistanceCategory.Medium:
                                    value = value * ENEMY_HAS_TREASURE_ALLY_MEDIUM;
                                    ap.BurnInformation("Made in GhostTreasureEvent, collecting treasure {0} from {1}, value: {2:F3}, case: medium ally", treasure.Id, carrying.Id, value);
                                    break;

                                case DistanceCategory.Far:
                                    value = value * ENEMY_HAS_TREASURE_ALLY_FAR;
                                    ap.BurnInformation("Made in GhostTreasureEvent, collecting treasure {0} from {1}, value: {2:F3}, case: far ally", treasure.Id, carrying.Id, value);
                                    break;

                                default:
                                    continue;
                                }

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                    }
                }
                break;

            case Owner.Me:
                if (game.GetEnemyPiratesCount(PirateState.Free) > 0)
                {
                    Pirate closestEnemy = game.GetEnemyClosestPirates(carrying, PirateState.Free)[0];

                    if (Game.InAttackRange(carrying, closestEnemy, closestEnemy.AttackRadius + closestEnemy.MaxSpeed))
                    {
                        if (game.GetMyPiratesCount(PirateState.Free) > 0)
                        {
                            Pirate closestAlly = game.GetMyClosestPirates(carrying, PirateState.Free)[0];
                            if (Game.InAttackRange(carrying, closestAlly, closestAlly.AttackRadius) || Game.InAttackRange(closestAlly, closestEnemy, closestAlly.AttackRadius))
                            {
                                return;     // is safe by the power of escort
                            }
                            foreach (Pirate free in game.GetMyPirates(PirateState.Free))
                            {
                                var sailOptions = game.GetCompleteSailOptions(free, treasure.InitialLocation, Terrain.EnemyLocation, Terrain.CurrentTreasureLocation);

                                foreach (var pair in sailOptions)
                                {
                                    if (sailOptions[0].Value > pair.Value)     //sail only if it's actually better than staying in place
                                    {
                                        ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(free, pair.Key), base.Id);

                                        ap.AddTreasure(treasure);

                                        double returnDistance = Game.ManhattanDistance(free.InitialLocation, treasure);
                                        double maxDistance    = game.Rows + game.Collumns;
                                        double value          = (TREASURE_VALUE - Utils.Pow(pair.Value, 0.9)) * multiplyer * ((maxDistance - returnDistance) / (maxDistance));
                                        if (free.HasPowerup(SpeedPowerup.NAME))
                                        {
                                            value = value * SPEED_POWERUP_MULTIPLYER;
                                        }

                                        value = value * ALLY_ABOUT_TO_DIE;

                                        ap.BurnInformation("Made in GhostTreasureEvent, collecting treasure {0} from {1}, value: {2:F3}, case: dead ally", treasure.Id, carrying.Id, value);

                                        chooser.AddActionsPack(ap, value);
                                    }
                                }
                            }
                        }
                    }
                }
                break;

            default:
                break;
            }
        }
示例#10
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanDefend || this.myPirate.DefenseDuration > 0)
            {
                return;
            }

            List <Pirate> threats = new List <Pirate>();

            bool isDouche = game.GetPirateSpawnOn(myPirate) != null && game.GetPirateSpawnOn(myPirate).Owner == Owner.Enemy; // If my pirate is a douche, he shouldn't ram the enemy since spawn-blocking is better.

            if (this.myPirate.State != PirateState.CarryingTreasure)
            {
                foreach (Pirate threat in game.GetEnemyDangerousPiratesInAttackRange(this.myPirate))
                {
                    if (game.PredictAttack(threat) == PredictionResult.False)
                    {
                        continue;
                    }

                    threats.Add(threat);
                    foreach (Pirate treasurePirate in game.GetMyPirates(PirateState.CarryingTreasure)) // Assume a pirate prefers to shoot a treasure pirate over a non-treasure pirate if he can
                    {
                        if (Game.InAttackRange(treasurePirate, threat, threat.AttackRadius))
                        {
                            threats.Remove(threat);
                            break;
                        }
                    }
                }
            }
            else
            {
                threats = game.GetEnemyDangerousPiratesInAttackRange(this.myPirate);
                threats.RemoveAll(p => game.PredictAttack(p) == PredictionResult.False);
                foreach (Pirate ally in game.GetMyPirates(PirateState.Free))
                {
                    if (Game.InAttackRange(ally, myPirate, ally.AttackRadius) && ally.CanAttack)
                    {
                        return;
                    }
                }
            }

            if (threats.Count == 0) // I'm safe, yay me!
            {
                return;
            }

            ActionsPack ap = ActionsPack.NewCommandPack(game, new DefendCommand(this.myPirate), base.Id);

            double value = PIRATE_DOESNT_HAVE_TREASURE;

            if (this.myPirate.State == PirateState.CarryingTreasure)
            {
                value = PIRATE_HAS_TREASURE * this.myPirate.CarriedTreasureValue;
            }
            else if (isDouche && this.myPirate.State != PirateState.CarryingTreasure)
            {
                value = PIRATE_IS_DOUCHE;
            }

            ap.BurnInformation("Made in DefendEvent, Value: {0:F3}", value);

            chooser.AddActionsPack(ap, value);
        }
示例#11
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (!this.myPirate.CanMove || this.myPirate.State != PirateState.Free) //If my pirate can't move or isn't free, he can't go to take power ups. If my pirate already has a power up, he shouldn't take another.
            {
                return;
            }

            // Get all the free powerups and sort them by manhattan distance to me
            List <Powerup> freePowerUps = game.GetPowerups().OrderBy(t => Game.ManhattanDistance(t, this.myPirate)).ToList();

            // Get the maximum treasure value
            int maxTreasureValue = 1;

            foreach (Treasure t in game.GetTreasures(TreasureState.FreeToTake, TreasureState.BeingCarried))
            {
                if (t.Value > maxTreasureValue)
                {
                    maxTreasureValue = t.Value;
                }
            }

            // try to sail to each treasure
            foreach (Powerup powerup in freePowerUps)
            {
                if (game.GetPirateOn(powerup) != null) // there is a pirate where the treasure is, most likely a drunk one. Leave it be.
                {
                    continue;
                }

                var sailOptions = game.GetCompleteSailOptions(this.myPirate, powerup, myPirate.DefenseDuration == 0 || Game.ManhattanDistance(myPirate, powerup) <= myPirate.MaxSpeed, Terrain.EnemyLocation, Terrain.CurrentTreasureLocation);

                foreach (var pair in sailOptions)
                {
                    if (sailOptions[0].Value > pair.Value) //sail only if it's actually better than staying in place
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                        double value = -Utils.Pow(pair.Value, 1.5);
                        if (powerup is AttackPowerup)
                        {
                            value += ATTACK_POWERUP_VALUE;
                        }
                        else if (powerup is SpeedPowerup)
                        {
                            value += SPEED_POWERUP_VALUE;
                        }
                        else
                        {
                            value += DEFAULT_POWERUP_VALUE;
                        }
                        if (pair.Value == 0)
                        {
                            value += PICK_UP_VALUE;
                        }
                        value *= Utils.Pow(0.75, myPirate.PowerupCount);

                        // Add a multiplier for maximum treasure value
                        if (powerup is SpeedPowerup)
                        {
                            value *= maxTreasureValue;
                        }

                        ap.AddPowerup(powerup);
                        ap.BurnInformation("Made in PowerUpEvent. Fetching PowerUp: {0}. Value: {1:F3}", powerup.Id, value);

                        chooser.AddActionsPack(ap, value);
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (this.myPirate.State != PirateState.Free)
            {
                return;
            }

            bool inRisk = false; // Is my pirate in risk of shooting right now?

            foreach (Pirate threat in game.GetEnemyPirates(PirateState.Free))
            {
                if (Game.InAttackRange(threat, myPirate, threat.AttackRadius) || Game.ManhattanDistance(threat, myPirate) <= threat.MaxSpeed)
                {
                    inRisk = true;
                    break;
                }
            }

            bool isDouche = game.GetPirateSpawnOn(myPirate) != null && game.GetPirateSpawnOn(myPirate).Owner == Owner.Enemy; // If my pirate is a douche, he shouldn't ram the enemy since spawn-blocking is better.


            // try to attack every enemy pirate which is carrying a treasure / which is free
            foreach (Pirate enemy in game.GetEnemyPirates(PirateState.CarryingTreasure, PirateState.Free, PirateState.Drunk))
            {
                //safe attack a treasure carrier
                if (enemy.State == PirateState.CarryingTreasure)
                {
                    if (Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius - 1) && //in close range - enemy can't escape
                        game.IsAttackPossible(this.myPirate, enemy) && //can fire
                        (!inRisk || isDouche))    // it's safe to shoot (a douche shouldn't care if it's safe or not to shoot - he has nothing to lose)
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new AttackCommand(this.myPirate, enemy), this.Id);

                        double value = ENEMY_HAS_TREASURE * enemy.CarriedTreasureValue;
                        if (myPirate.HasPowerup(AttackPowerup.NAME))
                        {
                            value *= ATTACK_POWERUP_MULTIPLYER;
                        }

                        ap.BurnInformation("Made in AttackEvent, case: shoot treasure. Value: {0:F3}", value);

                        chooser.AddActionsPack(ap, value);
                    }
                    else if ((Game.ManhattanDistance(enemy, enemy.InitialLocation) <= enemy.MaxSpeed || inRisk || !myPirate.CanAttack || myPirate.TurnsToAttackReload > enemy.DefenseDuration) && enemy.MaxSpeed < myPirate.MaxSpeed && !enemy.HasPowerup(SpeedPowerup.NAME))// ram
                    {
                        if (!isDouche || (!myPirate.CanDefend && inRisk && Game.ManhattanDistance(enemy, enemy.InitialLocation) > enemy.MaxSpeed))
                        {
                            // ram his predicted location
                            Location predictedLocation = game.PredictMovement(enemy);

                            // if there is no predicted location, try to ram his current location
                            if (predictedLocation == null)
                            {
                                predictedLocation = enemy.Location;
                            }

                            if (Game.ManhattanDistance(predictedLocation, myPirate) <= myPirate.MaxSpeed) // too far to ram
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, predictedLocation), this.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = ENEMY_HAS_TREASURE * enemy.CarriedTreasureValue - Game.ManhattanDistance(myPirate, enemy);
                                ap.BurnInformation("Made in AttackEvent, case: ram treasure. Value: {0:F3}", value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                    }
                    else if (enemy.DefenseDuration > 0 && myPirate.TurnsToAttackReload < enemy.DefenseDuration &&
                             Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius - 1))
                    {
                        var sailOptions = game.GetCompleteSailOptions(this.myPirate, enemy.InitialLocation, 0, 0, this.myPirate.MaxSpeed, this.myPirate.DefenseDuration == 0, 0, enemy.MaxSpeed, 2, Terrain.EnemyLocation, Terrain.CurrentTreasureLocation);

                        foreach (var pair in sailOptions)
                        {
                            if (sailOptions[0].Value > pair.Value) // sail only if it's actually better than staying in place
                            {
                                ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                                ap.AddEnemyPirate(enemy);

                                double value = GHOST_TREASURE_VAL * enemy.CarriedTreasureValue - Utils.Pow(pair.Value, 1.5) - Game.ManhattanDistance(pair.Key, enemy);
                                if (myPirate.HasPowerup(AttackPowerup.NAME))
                                {
                                    value *= ATTACK_POWERUP_MULTIPLYER;
                                }

                                ap.BurnInformation("Made in AttackEvent, against {0}, value: {1:F3}, case: ghost shielded treasure", enemy.Id, value);

                                chooser.AddActionsPack(ap, value);
                            }
                        }
                    }
                }
                else if (enemy.PowerupCount > 0)
                {
                    /*double multiplier = 2 * game.GetMyPiratesInAttackRange(enemy, PirateState.Free).Count;
                     * multiplier += 4 * game.GetMyPiratesInAttackRange(enemy, PirateState.CarryingTreasure).Count;*/
                    double multiplier = 1;
                    if (game.GetMyPiratesInAttackRange(enemy, PirateState.Free).Count > 1 && game.GetMyPiratesInAttackRange(enemy, PirateState.CarryingTreasure).Count == 0)
                    {
                        multiplier = 8;
                    }

                    if (game.IsAttackPossible(myPirate, enemy) && enemy.TurnToSober == 0) //fire!
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new AttackCommand(this.myPirate, enemy), base.Id);

                        double value = ENEMY_HAS_POWERUP;
                        if (myPirate.HasPowerup(AttackPowerup.NAME))
                        {
                            value = value * ATTACK_POWERUP_MULTIPLYER;
                        }
                        value = value * multiplier;

                        ap.BurnInformation("Made in AttackEvent, case: shoot powerup. Value: {0:F3}", value);

                        chooser.AddActionsPack(ap, value);
                    }
                    else if (Game.ManhattanDistance(myPirate, enemy) <= myPirate.MaxSpeed && myPirate.PowerupCount == 0)// ram
                    {
                        if (!isDouche)
                        {
                            if (!enemy.CanAttack && !enemy.CanDefend)
                            {
                                continue;
                            }
                            // ram his location
                            Location enemyLocation = enemy.Location; // assume enemy will shoot or defend, otherwise ramming is practically impossible

                            ActionsPack ap    = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, enemyLocation), base.Id);
                            double      value = ENEMY_HAS_POWERUP - Game.ManhattanDistance(myPirate, enemy);
                            value = value * multiplier;

                            ap.AddEnemyPirate(enemy);
                            ap.BurnInformation("Made in AttackEvent, case: ram powerup. Value: {0:F3}", value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                }
                //just attack a free pirate
                else if (enemy.State == PirateState.Free && Game.InAttackRange(this.myPirate, enemy, this.myPirate.AttackRadius))
                {
                    if (!myPirate.CanAttack)
                    {
                        continue;
                    }

                    if (enemy.DefenseDuration > 0)
                    {
                        continue;
                    }

                    if (game.IsAttackPossible(this.myPirate, enemy))
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new AttackCommand(this.myPirate, enemy), base.Id);

                        /*double multiplier = 2 * game.GetMyPiratesInAttackRange(enemy, PirateState.Free).Count;
                         * multiplier += 4 * game.GetMyPiratesInAttackRange(enemy, PirateState.CarryingTreasure).Count;*/
                        double multiplier = 1;
                        if (game.GetMyPiratesInAttackRange(enemy, PirateState.Free).Count > 1 && game.GetMyPiratesInAttackRange(enemy, PirateState.CarryingTreasure).Count == 0)
                        {
                            multiplier = 8;
                        }

                        double value = ENEMY_HAS_NO_TREASURE * multiplier;
                        if (myPirate.HasPowerup(AttackPowerup.NAME))
                        {
                            value = value * ATTACK_POWERUP_MULTIPLYER;
                        }

                        ap.BurnInformation("Made in AttackEvent, case: shoot regular. Value: {0:F3}", value);

                        chooser.AddActionsPack(ap, value);
                    }
                }
            }
        }
示例#13
0
 /// <summary>
 /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
 /// </summary>
 public abstract void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser);
        private const double GARBAGE_COLLECTION_VALUE = 120; // - (distanceLeft^1.5), range of values is about 200 to 180


        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (this.myPirate.State != PirateState.Drunk || (game.GetPirateSpawnOn(this.myPirate) != null && game.GetPirateSpawnOn(this.myPirate).Owner == Owner.Enemy)) //If my pirate isn't drunk it doesn't need help
            {
                return;
            }


            // try to sail to "collect" the pirate
            foreach (Pirate free in game.GetMyPirates(PirateState.Free))
            {
                var sailOptions = game.GetCompleteSailOptions(free, this.myPirate, Terrain.CurrentTreasureLocation);

                foreach (var pair in sailOptions)
                {
                    if (sailOptions[0].Value > pair.Value) //sail only if it's actually better than staying in place
                    {
                        ActionsPack ap = ActionsPack.NewCommandPack(game, new RamCommand(free, this.myPirate, pair.Key), base.Id);

                        ap.AddMyPirate(myPirate);

                        double distanceFromSpawnModifier = Utils.Pow(Game.ManhattanDistance(free.InitialLocation, free), 1.5);
                        double timeModifier = Utils.Pow(game.TurnsUntilSober - this.myPirate.TurnToSober, 1.5);
                        double value        = Utils.Max(GARBAGE_COLLECTION_VALUE - timeModifier - distanceFromSpawnModifier - Utils.Pow(pair.Value, 1.5), 35);

                        ap.BurnInformation("Made in GarbageCollection event, saving {0}, Value: {1:F3}", this.myPirate.Id, value);

                        chooser.AddActionsPack(ap, value);
                    }
                }
            }
        }
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            // if the pirate is not carrying treasure OR if he can't move, we cannot do anything
            if (this.myPirate.State != PirateState.CarryingTreasure ||
                !this.myPirate.CanMove)
            {
                return;
            }

            /*
             * bool isEscorted = false;
             * foreach (Pirate ally in game.GetMyFreePirates())
             * {
             *  if (Game.InAttackRange(ally, myPirate, ally.AttackRadius))
             *  {
             *      isEscorted = true;
             *      break;
             *  }
             * }*/

            var sailOptions = game.GetCompleteSailOptions(this.myPirate, this.myPirate.InitialLocation, myPirate.DefenseDuration == 0 && Game.ManhattanDistance(myPirate, myPirate.InitialLocation) > myPirate.MaxSpeed, Terrain.EnemyLocation);

            List <Pirate> closestEnemies = game.GetEnemyClosestPirates(myPirate, PirateState.Free);

            // check all possible destinations for returning home
            foreach (var pair in sailOptions)
            {
                if (sailOptions[0].Value > pair.Value && (game.GetPirateOn(pair.Key) == null || game.GetPirateOn(pair.Key).Owner == Owner.Me))
                {
                    ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(this.myPirate, pair.Key), base.Id);

                    double prioritize = (pair.Value == 0 ? myPirate.CarriedTreasureValue * 65536 : 5.0 * (pair.Value + 1.0) / (pair.Value));

                    double stayAwayPrioritize = 10;

                    if (closestEnemies.Count > 0)
                    {
                        Pirate enemy = closestEnemies[0];
                        if (Game.ManhattanDistance(enemy, myPirate) > enemy.MaxSpeed)
                        {
                            double distanceToEnemy = Game.EuclideanDistance(pair.Key, enemy);
                            stayAwayPrioritize = 5.0 * (distanceToEnemy) / (distanceToEnemy + 1.0);
                        }
                    }

                    double value = (MOVE_TOWARDS_HOME + prioritize + stayAwayPrioritize - Utils.Pow(pair.Value, 1.3)) * myPirate.CarriedTreasureValue;
                    if (myPirate.HasPowerup(SpeedPowerup.NAME))
                    {
                        value = value * SPEED_POWERUP_MULTIPLYER;
                    }
                    if (game.GetAllMyPiratesCount() > game.ActionsPerTurn)
                    {
                        value += ARMADA_BONUS;
                    }

                    ap.BurnInformation("Made in ReturnTreasureEvent, Value: {0:F3}", value);

                    chooser.AddActionsPack(ap, value);
                }
            }
        }
示例#16
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            if (this.myPirate.State != PirateState.Drunk)
            {
                return;
            }

            Pirate enemy = game.GetPirateSpawnOn(this.myPirate);

            if (enemy != null && enemy.Owner == Owner.Enemy)
            {
                ActionsPack ap = ActionsPack.NewCommandPack(game, new DoNothingCommand(), base.Id);

                double value = BLOCKADE_VALUE;

                ap.AddEnemyPirate(enemy);
                ap.AddMyPirate(this.myPirate);
                ap.BurnInformation("Made in DrunkBlockadeEvent for pirate {0} on pirate {1}, Value: {2:F3}", this.myPirate, enemy.Id, value);

                chooser.AddActionsPack(ap, value);
            }
        }
示例#17
0
        /// <summary>
        /// Add possible responses to "chooser", based on the situation in "game" and in "statesManager"
        /// </summary>
        public override void AddResponseOptions(Game game, StatesManager statesManager, ActionsChooser chooser)
        {
            //Counts how many of the pirates in the cluster carry treasure, will be used for event value.
            List <Pirate> treasurePiratesInCluster = this.hotspot.Intersect(game.GetMyPirates(PirateState.CarryingTreasure)).ToList();
            int           valueInCluster           = treasurePiratesInCluster.Sum(pirate => pirate.CarriedTreasureValue);

            if (valueInCluster == 0)
            {
                return;
            }
            // the pirates in the threat zone
            List <Pirate> enemiesInCluster = game.GetEnemyPiratesInAttackRange(this.hotspot, PirateState.Free).Union(
                game.GetEnemyPiratesInAttackRange(this.hotspot, PirateState.Drunk)).ToList();

            //Checks if there is an enemy in the cluster already, if so - sends in the cavalry!
            foreach (Pirate enemy in enemiesInCluster)
            {
                if (enemy.State == PirateState.Drunk && game.GetPirateSpawnOn(enemy.Location) != null && game.GetPirateSpawnOn(enemy.Location).Owner != Owner.Me)
                {
                    continue;
                }

                foreach (Pirate myPirate in game.GetMyPirates(PirateState.Free))
                {
                    var sailOptions = game.GetCompleteSailOptions(myPirate, enemy, myPirate.DefenseDuration == 0 && !Game.InAttackRange(myPirate, enemy, enemy.AttackRadius), Terrain.CurrentTreasureLocation);

                    foreach (var pair in sailOptions)
                    {
                        if (sailOptions[0].Value > pair.Value)  //sail only if it's actually better than staying in place
                        {
                            ActionsPack ap = ActionsPack.NewCommandPack(game, new SailCommand(myPirate, pair.Key), this.Id);

                            ap.AddEnemyPirate(enemy);

                            double value = BASE_VAL + valueInCluster * TREASURE_VAL + (this.hotspot.Count - treasurePiratesInCluster.Count) * NO_TREASURE_VAL + enemiesInCluster.Count * ENEMY_VAL - Utils.Pow(pair.Value, 1.25);
                            if (this.hotspot.Contains(myPirate))
                            {
                                value += IS_HOME_VAL;
                            }
                            if (statesManager.GetState <ImpendingVictoryState>().IsVictoryIncoming)
                            {
                                value *= IMPENDING_VICTORY_MULT;
                            }
                            ap.BurnInformation("Made in AntiTeroristEvent against {0}, Value: {1:F3}", enemy.Id, value);

                            chooser.AddActionsPack(ap, value);
                        }
                    }
                }
            }
        }