public override void OnFrame()
        {
            KnownBuildings = new List <Unit>();
            KnownArmy      = new List <Unit>();
            var enemyUnits = Controller.GetEnemyUnits();

            foreach (Unit u in enemyUnits)
            {
                if (Units.Structures.Contains(u.UnitType))
                {
                    KnownBuildings.Add(u);
                }
                else
                {
                    KnownArmy.Add(u);
                }
            }


            if (KnownBuildings.Count > 0)
            {
                VBot.Bot.Map.TargetAttackLocation = Sc2Util.To2D(KnownBuildings[0].Pos);
            }
            else if (KnownArmy.Count > 2)  // set to 2 to avoid chasing single workers that are scouting
            {
                VBot.Bot.Map.TargetAttackLocation = Sc2Util.To2D(KnownArmy[0].Pos);
            }
            else
            {
                if (VBot.Bot.Map.TargetAttackLocation != VBot.Bot.Map.EnemyStartLocations[0])
                {
                    VBot.Bot.Map.TargetAttackLocation = VBot.Bot.Map.EnemyStartLocations[0];
                }
            }
        }
Beispiel #2
0
        public List <Point2D> GetScoutLocations()
        {
            List <Point2D> baseLocations = BaseLocations
                                           .Select(b => Sc2Util.To2D(b.Location))
                                           .OrderBy(b => WalkingDistanceFromEnemy(b))
                                           .ToList();

            return(baseLocations);
        }
Beispiel #3
0
        /// <summary>
        /// Get the agent from a collection of units that is nearest to the agent with the given tag
        /// </summary>
        /// <param name="units">a collection of agents to check</param>
        /// <param name="tag">the unit tag of the desired unit. MUST BE AN AGENT</param>
        /// <returns>the agent that is nearest to the unit with the matching tag, or null if the tag is invalid, or the unit collection is empty</returns>
        public static Agent GetAgentNear(IEnumerable <Unit> units, ulong tag)
        {
            Agent a = GetAgentByTag(tag);

            if (a == null)
            {
                return(null);
            }
            return(GetAgentNear(units, Sc2Util.To2D(a.Unit.Pos)));
        }
Beispiel #4
0
        /// <summary>
        /// A function that gets a valid location for a structure of the type specified in the main base
        /// </summary>
        /// <param name="unitType">the type for a gas geyser</param>
        /// <returns>the tag of the unbuild geyser to build a gas on, 0 if none are found</returns>
        public static ulong FindGasPlacement()
        {
            List <Point> gasLocations    = GetGasLocations();
            ulong        constructionTag = 0;

            foreach (var rc in GetAgents(Units.ResourceCenters))
            {
                foreach (var gas in GetUnits(Units.GasGeysers))
                {
                    if (!IsInRange(Sc2Util.To2D(gas.Pos), gasLocations, 4) && DistanceBetweenSq(rc.Unit.Pos, gas.Pos) < 81)
                    {
                        constructionTag = gas.Tag;
                        return(constructionTag);
                    }
                }
            }
            return(constructionTag);
        }
        public override void OnFrame()
        {
            // queen logic
            if (Queen.Unit.Energy >= 25)
            {
                Queen.Order(Abilities.SPREAD_CREEP_QUEEN, Controller.GetTumorLocation(Sc2Util.To2D(Queen.Unit.Pos), 12)); // Acts as EXECUTE statement
            }
            // add active tumors to tumor list
            foreach (Agent t in Controller.GetAgents(Units.CREEP_TUMOR_BURROWED))
            {
                if (t.Command == null)
                {
                    if (!ActiveTumors.ContainsKey(t))
                    {
                        ActiveTumors.Add(t, VBot.Bot.Observation.Observation.GameLoop);
                    }
                }
            }

            List <Agent> removeTumors = new List <Agent>();

            // tumor logic
            foreach (var tumor in ActiveTumors)
            {
                if ((VBot.Bot.Observation.Observation.GameLoop - tumor.Value) < 400)
                {
                    continue;
                }
                else
                {
                    tumor.Key.Order(Abilities.SPREAD_CREEP_TUMOR, Controller.GetTumorLocation(Sc2Util.To2D(tumor.Key.Unit.Pos), 7)); // acts as EXECUTE statement
                    removeTumors.Add(tumor.Key);
                }
            }

            foreach (var tumor in removeTumors)
            {
                ActiveTumors.Remove(tumor);
            }
        }
Beispiel #6
0
        /// <summary>
        /// This function ensures drones are harvesting optimally across different bases
        /// </summary>
        public static void DistributeWorkers()
        {
            List <Agent> resourceCenters = GetAgents(Units.ResourceCenters);
            List <Agent> Geysers         = GetAgents(Units.GasGeysers);
            List <Agent> Workers         = GetAgents(Units.Workers).ToList();
            List <Unit>  mineralPatches  = GetUnits(Units.MineralFields);

            bool oversaturatedGases = false;
            // step 1 - add drones to gas
            int workersOnGas    = 0;
            int maxGasPotential = 0;

            foreach (var gas in Geysers)
            {
                if (gas.Unit.AssignedHarvesters > gas.Unit.IdealHarvesters)
                {
                    oversaturatedGases = true;
                }

                workersOnGas    += gas.Unit.AssignedHarvesters;
                maxGasPotential += gas.Unit.IdealHarvesters;
            }
            if (workersOnGas < VBot.Bot.Build.IdealGasWorkers && workersOnGas < maxGasPotential)
            {
                int idealWorkerCount = maxGasPotential < VBot.Bot.Build.IdealGasWorkers
                    ? maxGasPotential
                    : VBot.Bot.Build.IdealGasWorkers;

                int           workersToTransfer = idealWorkerCount - workersOnGas;
                Queue <Agent> agentsForGas      = new Queue <Agent>();
                for (int i = 0; i < workersToTransfer; i++)
                {
                    var newWorker = GetWorker();
                    if (newWorker == null)
                    {
                        continue;
                    }
                    agentsForGas.Enqueue(newWorker);
                    newWorker.Busy = true;
                }

                foreach (Agent gas in Geysers)
                {
                    int transfers = gas.Unit.IdealHarvesters - gas.Unit.AssignedHarvesters;
                    for (int i = 0; i < transfers; i++)
                    {
                        if (agentsForGas.Count > 0)
                        {
                            agentsForGas.Dequeue().Order(Abilities.SMART, gas.Unit.Tag);
                        }
                    }
                }
            }

            // step 2 - remove drones from oversaturated gas
            if (oversaturatedGases)
            {
                foreach (var gas in Geysers)
                {
                    if (gas.Unit.IdealHarvesters < gas.Unit.AssignedHarvesters)
                    {
                        List <Agent> workersToRemove = new List <Agent>();
                        for (int i = 0; i < gas.Unit.AssignedHarvesters - gas.Unit.IdealHarvesters; i++)
                        {
                            Agent worker = Workers
                                           .Where(w => w.Unit.Orders.Count() > 0)
                                           .Where(w => w.Unit.Orders[0].TargetUnitTag == gas.Unit.Tag).FirstOrDefault();
                            worker.Busy = false;
                            workersToRemove.Add(worker);
                        }

                        ulong mineralTag = GetUnits(Units.MineralFields)
                                           .Where(m => DistanceBetweenSq(m.Pos, gas.Unit.Pos) < 100)
                                           .FirstOrDefault().Tag;
                        var action = new ActionRawUnitCommand
                        {
                            AbilityId     = (int)Abilities.SMART,
                            TargetUnitTag = mineralTag,
                        };
                        action.UnitTags.AddRange(workersToRemove.Select(w => w.Unit.Tag));
                        VBot.Bot.AddAction(action);
                        return;
                    }
                }
            }

            // step 3 - remove drones if over ideal drone count
            if (workersOnGas > VBot.Bot.Build.IdealGasWorkers)
            {
                int          workersToRemoveCount = workersOnGas - VBot.Bot.Build.IdealGasWorkers;
                List <Agent> workersToRemove      = new List <Agent>();
                ulong        mineralTag           = 0;
                while (workersToRemoveCount > 0)
                {
                    workersToRemoveCount--;
                    foreach (Agent gas in Geysers)
                    {
                        if (gas.Unit.AssignedHarvesters == 0)
                        {
                            continue;
                        }

                        Agent worker = Workers
                                       .Where(w => w.Unit.Orders.Count() > 0)
                                       .Where(w => w.Unit.Orders[0].TargetUnitTag == gas.Unit.Tag).FirstOrDefault();
                        if (worker == null)
                        {
                            return;
                        }
                        workersToRemove.Add(worker);
                        mineralTag = GetUnits(Units.MineralFields)
                                     .Where(m => DistanceBetweenSq(m.Pos, gas.Unit.Pos) < 100)
                                     .FirstOrDefault().Tag;
                    }
                }
                ActionRawUnitCommand action = new ActionRawUnitCommand
                {
                    AbilityId     = (int)Abilities.SMART,
                    TargetUnitTag = mineralTag,
                };
                action.UnitTags.AddRange(workersToRemove.Select(w => w.Unit.Tag));
                VBot.Bot.AddAction(action);
            }

            // step 4 - move idle works to mineral patches
            if (VBot.Bot.Observation.Observation.PlayerCommon.IdleWorkerCount > 0)
            {
                var   idleWorkers = GetAgents(Units.Workers).Where(a => a.Unit.Orders.Count == 0);
                Agent desiredRc   = null;
                foreach (Agent rc in resourceCenters)
                {
                    if (rc.Unit.AssignedHarvesters < rc.Unit.IdealHarvesters)
                    {
                        desiredRc = rc;
                        break;
                    }
                }
                if (desiredRc == null)
                {
                    desiredRc = resourceCenters[0];
                }

                var mineralPatch             = GetAgentNear(mineralPatches, Sc2Util.To2D(desiredRc.Unit.Pos));
                ActionRawUnitCommand command = new ActionRawUnitCommand();
                command.UnitTags.Add(idleWorkers.Select(w => w.Unit.Tag));
                command.AbilityId     = (int)Abilities.SMART;
                command.TargetUnitTag = mineralPatch.Unit.Tag;
                VBot.Bot.AddAction(command);
            }

            // step 5 - transfer workers around minerals
            Agent fromRC = null;
            Agent toRC   = null;

            foreach (Agent rc in resourceCenters)
            {
                if (rc.Unit.AssignedHarvesters == rc.Unit.IdealHarvesters)
                {
                    continue;
                }
                if (rc.Unit.AssignedHarvesters > rc.Unit.IdealHarvesters)
                {
                    fromRC = rc;
                }
                else
                {
                    toRC = rc;
                }
            }
            if (fromRC != null && toRC != null)
            {
                Agent workerToTransfer = Workers
                                         .Where(w => w.Unit.Orders.Count > 0 &&
                                                Abilities.MiningMinerals.Contains(w.Unit.Orders[0].AbilityId) &&
                                                DistanceBetweenSq(w.Unit.Pos, fromRC.Unit.Pos) < 100)
                                         .FirstOrDefault();
                Agent mineralPatch          = GetAgentNear(mineralPatches, toRC.Unit.Tag);
                ActionRawUnitCommand action = new ActionRawUnitCommand();
                action.UnitTags.Add(workerToTransfer.Unit.Tag);
                action.TargetUnitTag = mineralPatch.Unit.Tag;
                action.AbilityId     = (int)Abilities.SMART;
                VBot.Bot.AddAction(action);
            }
        }