Example #1
0
        private void expandQueue(Queue <Point2D> queue, Point2D point, ImageData map, int[,] distances, int newVal)
        {
            int            x            = (int)point.X;
            int            y            = (int)point.Y;
            List <Point2D> nearbyPoints = new List <Point2D>();

            nearbyPoints.Add(new Point2D {
                X = x + 1, Y = y
            });
            nearbyPoints.Add(new Point2D {
                X = x - 1, Y = y
            });
            nearbyPoints.Add(new Point2D {
                X = x, Y = y + 1
            });
            nearbyPoints.Add(new Point2D {
                X = x, Y = y - 1
            });

            foreach (Point2D p in nearbyPoints)
            {
                if (p.X < 0 || p.X > map.Size.X - 1 || p.Y < 0 || p.Y > map.Size.Y - 1)
                {
                    continue;
                }
                if (Sc2Util.ReadTile(map, (int)p.X, map.Size.Y - (int)p.Y - 1) && distances[(int)p.X, (int)p.Y] == 100000000)
                {
                    queue.Enqueue(p);
                    distances[(int)p.X, (int)p.Y] = newVal;
                }
            }
        }
        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];
                }
            }
        }
Example #3
0
        public List <Point2D> GetScoutLocations()
        {
            List <Point2D> baseLocations = BaseLocations
                                           .Select(b => Sc2Util.To2D(b.Location))
                                           .OrderBy(b => WalkingDistanceFromEnemy(b))
                                           .ToList();

            return(baseLocations);
        }
Example #4
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)));
        }
Example #5
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);
        }
Example #6
0
        /// <summary>
        /// Get a location to place a creep tumor
        /// </summary>
        /// <param name="startPoint">the location of the queen or tumor that spreads the creep. MUST BE A PATHABLE TILE</param>
        /// <param name="towards">the direction of the desired creepspread</param>
        /// <param name="range">how far from the startpoint it can spread to.</param>
        /// <returns>a location that is valid for a tumor to be placed. Null if none can be found</returns>
        public static Point2D GetTumorLocation(Point2D startPoint, Point2D towards, int range)
        {
            int[,] distances;
            if (towards == VBot.Bot.Map.EnemyStartLocations[0])
            {
                distances = VBot.Bot.Map.DistancesToEnemy;
            }
            else
            {
                distances = VBot.Bot.Map.GenerateDistances(towards);
            }

            Point2D closestPoint = null;
            int     minDist      = 100000000;

            List <Point> tumorLocations = GetAgents(Units.AllCreep).Select(a => a.Unit.Pos).ToList();

            for (int i = -range; i <= range; i++)
            {
                for (int j = -range; j < range + 1; j++)
                {
                    // check if it is creep
                    var     creepMap = VBot.Bot.Observation.Observation.RawData.MapState.Creep;
                    Point2D testLoc  = new Point2D {
                        X = startPoint.X + i, Y = startPoint.Y + j
                    };
                    if (!Sc2Util.ReadTile(creepMap, testLoc))
                    {
                        continue;
                    }

                    if (distances[(int)testLoc.X, (int)testLoc.Y] < minDist && !IsInRange(testLoc, tumorLocations, 5))
                    {
                        minDist      = distances[(int)testLoc.X, (int)testLoc.Y];
                        closestPoint = testLoc;
                    }
                }
            }
            if (closestPoint == null)
            {
                return(null);
            }
            return(closestPoint);
        }
Example #7
0
        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);
            }
        }
Example #8
0
 /// <summary>
 /// checks if the bot has vision of a tile on the map.
 /// </summary>
 /// <param name="loc">A Point2D that you want to check the vision of</param>
 /// <returns>true if the bot actively has vision of the location, false otherwise</returns>
 public static bool HasVision(Point2D loc)
 {
     return(Sc2Util.ReadTile(VBot.Bot.Observation.Observation.RawData.MapState.Visibility, loc));
 }
Example #9
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);
            }
        }