/// <summary>
        /// Tests to see whether or not we can easily reach the town hall to snipe it or not.
        /// </summary>
        /// <param name="townHall"></param>
        /// <returns></returns>
        public static bool CanSnipe(this TownHall townHall)
        {
            if (townHall != null)
            {
                Target target = townHall.GetTownHallPoints();

                Log.Debug($"[Berts Agorithms] Town Hall Center Location: X:{target.Center.X} Y:{target.Center.Y}");
                Log.Debug($"[Berts Agorithms] Town Hall Outer Edge Location: X:{target.Edge.X} Y:{target.Edge.Y}");
                Log.Debug($"[Berts Agorithms] DistanceSq from Town Hall to closest outer red point: {target.EdgeToRedline.ToString("F1")}");

#if DEBUG
                //Get a screen Capture...
                using (Bitmap canvas = Screenshot.Capture())
                {
                    //Draw some stuff on it.
                    Visualize.Target(canvas, Origin, 40, Color.White);
                    Visualize.Target(canvas, target.Center, 40, Color.Orange);
                    Visualize.Target(canvas, target.Edge, 40, Color.Red);

                    //Save the Image to the Debug Folder...
                    var d = DateTime.UtcNow;
                    Screenshot.Save(canvas, $"CanSnipe TownHall {d.Year}-{d.Month}-{d.Day} {d.Hour}-{d.Minute}-{d.Second}-{d.Millisecond}");
                }
                Log.Debug("[Berts Algorithms] Snipe Townhall Debug Image Saved!");
#endif

                if (target.EdgeToRedline < _townHallToRedZoneMinDistance)  // means there is no wall or building between us and the OUTSIDE of the Town Hall
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Check to see how many collector and mine near to the redline by user defined distance
        /// </summary>
        /// <param name="userDistance">Minimum distance for exposed colloctors and mines</param>
        /// <param name="minCollectors">minimum exposed collectors</param>
        /// <param name="minMines">minimum exposed mines</param>
        /// <param name="AttackName">Attack name for logs and debugging</param>
        /// <param name="debug">debug mode in advanced settings</param>
        /// <returns>true if matches user defined min collectores and mines</returns>
        public static bool IsBaseMinCollectorsAndMinesOutside(int userDistance, int minCollectors, int minMines, string AttackName, int debug)
        {
            var distance = userDistance * userDistance;

            var redPoints = GameGrid.RedPoints.Where(
                point =>
                !(point.X > 18 && point.Y > 18 || point.X > 18 && point.Y < -18 || point.X < -18 && point.Y > 18 ||
                  point.X < -18 && point.Y < -18));

            collectors = ElixirCollector.Find().Where(c => c.Location.GetCenter()
                                                      .DistanceSq(redPoints.OrderBy(p => p.DistanceSq(c.Location.GetCenter()))
                                                                  .FirstOrDefault()) <= distance);

            mines = GoldMine.Find().Where(c => c.Location.GetCenter()
                                          .DistanceSq(redPoints.OrderBy(p => p.DistanceSq(c.Location.GetCenter()))
                                                      .FirstOrDefault()) <= distance);

            drills = DarkElixirDrill.Find().Where(c => c.Location.GetCenter()
                                                  .DistanceSq(redPoints.OrderBy(p => p.DistanceSq(c.Location.GetCenter()))
                                                              .FirstOrDefault()) <= distance);

            int collectorsCount = collectors != null?collectors.Count() : 0;

            int minesCount = mines != null?mines.Count() : 0;

            int drillsCount = drills != null?drills.Count() : 0;

            // Set total count of targets
            SmartFourFingersDeploy.TotalTargetsCount = collectorsCount + minesCount + drillsCount;

            // four corners
            var top    = new PointFT((float)GameGrid.DeployExtents.MaxX + 1, GameGrid.DeployExtents.MaxY + 4);
            var right  = new PointFT((float)GameGrid.DeployExtents.MaxX + 1, GameGrid.DeployExtents.MinY - 4);
            var bottom = new PointFT((float)GameGrid.DeployExtents.MinX - 1, GameGrid.DeployExtents.MinY - 4);
            var left   = new PointFT((float)GameGrid.DeployExtents.MinX - 1, GameGrid.DeployExtents.MaxY + 4);

            SetCore();

            var corners = new List <Tuple <PointFT, PointFT> >
            {
                new Tuple <PointFT, PointFT>(top, right),
                new Tuple <PointFT, PointFT>(bottom, right),
                new Tuple <PointFT, PointFT>(bottom, left),
                new Tuple <PointFT, PointFT>(top, left)
            };

            // loop throw the 4 sides and count targets on each side
            var targetsAtLine = new List <int>();

            foreach (var l in corners)
            {
                var colCount = collectors.Where(t => t.Location.GetCenter().
                                                IsInTri(SmartFourFingersDeploy.Core, l.Item1, l.Item2))?.Count() ?? 0;
                var minCount = mines.Where(t => t.Location.GetCenter().
                                           IsInTri(SmartFourFingersDeploy.Core, l.Item1, l.Item2))?.Count() ?? 0;
                var drillCount = drills.Where(t => t.Location.GetCenter().
                                              IsInTri(SmartFourFingersDeploy.Core, l.Item1, l.Item2))?.Count() ?? 0;
                var total = colCount + minCount + drillCount;

                targetsAtLine.Add(total);
            }

            SmartFourFingersDeploy.TargetsAtLine = targetsAtLine;

            var op = new Opponent(0);

            //if (!op.IsForcedAttack )
            {
                Log.Info($"{AttackName} NO. of Colloctors & mines near from red line:");
                Log.Info($"elixir colloctors is {collectorsCount}");
                Log.Info($"gold mines is {minesCount}");
                Log.Info($"----------------------------");
                Log.Info($"sum of all is {collectorsCount + minesCount}");

                if (debug == 1)
                {
                    using (Bitmap bmp = Screenshot.Capture())
                    {
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
                            foreach (var c in collectors)
                            {
                                var point = c.Location.GetCenter();
                                Visualize.Target(bmp, point, 30, Color.Purple);
                            }

                            foreach (var c in mines)
                            {
                                var point = c.Location.GetCenter();
                                Visualize.Target(bmp, point, 30, Color.Gold);
                            }

                            foreach (var c in drills)
                            {
                                var point = c.Location.GetCenter();
                                Visualize.Target(bmp, point, 30, Color.Black);
                            }
                            DrawLine(bmp, Color.Red, SmartFourFingersDeploy.Core, top);
                            DrawLine(bmp, Color.Red, SmartFourFingersDeploy.Core, right);
                            DrawLine(bmp, Color.Red, SmartFourFingersDeploy.Core, bottom);
                            DrawLine(bmp, Color.Red, SmartFourFingersDeploy.Core, left);
                        }
                        var d = DateTime.UtcNow;
                        Screenshot.Save(bmp, "Collectors and Mines {d.Year}-{d.Month}-{d.Day} {d.Hour}-{d.Minute}-{d.Second}-{d.Millisecond}");
                    }
                }
            }
            if (collectorsCount >= minCollectors && minesCount >= minMines)
            {
                return(true);
            }
            else
            {
                Log.Warning($"{AttackName} this base doesn't meets Collocetors & Mines requirements");
                return(false);
            }
        }
        void CreateDebugImages()
        {
            List <InfernoTower>  infernos       = InfernoTower.Find(CacheBehavior.Default).ToList();
            List <WizardTower>   wizTowers      = WizardTower.Find(CacheBehavior.Default).ToList();
            List <ArcherTower>   archerTowers   = ArcherTower.Find(CacheBehavior.Default).ToList();
            List <ElixirStorage> elixirStorages = ElixirStorage.Find(CacheBehavior.Default).ToList();
            EagleArtillery       eagle          = EagleArtillery.Find(CacheBehavior.Default);

            var d             = DateTime.UtcNow;
            var debugFileName = $"Dragon Deploy {d.Year}-{d.Month}-{d.Day} {d.Hour}-{d.Minute}-{d.Second}-{d.Millisecond}";

            using (Bitmap canvas = Screenshot.Capture())
            {
                Screenshot.Save(canvas, $"{debugFileName}_1");

                //Draw some stuff on it.
                Visualize.Axes(canvas);
                Visualize.Grid(canvas, redZone: true);
                Visualize.Target(canvas, mainTarget.Center, 40, Color.Red);
                Visualize.Target(canvas, deFunnelPoints[0], 40, Color.White);
                Visualize.Target(canvas, deFunnelPoints[1], 40, Color.White);
                Visualize.Target(canvas, balloonFunnelPoints[0], 40, Color.Pink);
                Visualize.Target(canvas, balloonFunnelPoints[1], 40, Color.Pink);

                for (int i = 0; i < infernos.Count(); i++)
                {
                    Visualize.Target(canvas, infernos.ElementAt(i).Location.GetCenter(), 30, Color.Orange);
                }

                for (int i = 0; i < airDefenses.Count(); i++)
                {
                    Visualize.Target(canvas, airDefenses.ElementAt(i).Location.GetCenter(), 30, Color.Cyan);
                }

                for (int i = 0; i < wizTowers.Count(); i++)
                {
                    Visualize.Target(canvas, wizTowers.ElementAt(i).Location.GetCenter(), 30, Color.Purple);
                }

                for (int i = 0; i < archerTowers.Count(); i++)
                {
                    Visualize.Target(canvas, archerTowers.ElementAt(i).Location.GetCenter(), 30, Color.RosyBrown);
                }

                if (eagle != null)
                {
                    Visualize.Target(canvas, eagle.Location.GetCenter(), 30, Color.YellowGreen);
                }

                Visualize.Target(canvas, mainTarget.DeployGrunts, 40, Color.Beige);

                Screenshot.Save(canvas, $"{debugFileName}_2");
            }

            //Write a text file that goes with all images that shows what is in the image.
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < airDefenses.Count(); i++)
            {
                sb.AppendLine($"Air Defense {i + 1} - Level:{airDefenses.ElementAt(i).Level}");
            }

            for (int i = 0; i < infernos.Count(); i++)
            {
                sb.AppendLine($"Inferno Tower {i + 1} - Level:{infernos.ElementAt(i).Level}");
            }

            for (int i = 0; i < wizTowers.Count(); i++)
            {
                sb.AppendLine($"Wizard Tower {i + 1} - Level:{wizTowers.ElementAt(i).Level}");
            }

            for (int i = 0; i < archerTowers.Count(); i++)
            {
                sb.AppendLine($"Archer Tower {i + 1} - Level:{archerTowers.ElementAt(i).Level}");
            }

            if (eagle != null)
            {
                sb.AppendLine($"Eagle Artillery 1 - Level:{eagle.Level}");
            }

            //System.IO.File.WriteAllText($@"C:\RaccoonBot\Debug Screenshots\{debugFileName}_3.txt", sb.ToString());

            Log.Info($"{Tag} Deploy Debug Image Saved!");
        }
예제 #4
0
        private static void OutputDebugImage(string algorithmName, List <Building> buildings, List <Target> targetList, string AttackId)
        {
            var d             = DateTime.UtcNow;
            var debugFileName = $"{algorithmName} {d.Year}-{d.Month}-{d.Day} {d.Hour}-{d.Minute}-{d.Second}-{d.Millisecond}[{AttackId}]".GetSafeFilename();

            //Get a screen Capture of all targets we found...
            using (Bitmap canvas = Screenshot.Capture())
            {
                Screenshot.Save(canvas, $"{debugFileName}_1");

                Visualize.Axes(canvas);
                Visualize.Grid(canvas, redZone: true);

                //Draw the Max Outside Boundry For Deployment...
                for (int i = -35; i <= 35; i++)
                {
                    var color = Color.Magenta;
                    if (i % 2 == 0)
                    {
                        color = Color.LightPink;
                    }

                    float max = 30f;
                    DrawLine(canvas, color, SafePoint(max, i), SafePoint(max, i + 1));   //Top Left Side
                    DrawLine(canvas, color, SafePoint(i, max), SafePoint(i + 1, max));   //Top Right Side
                    DrawLine(canvas, color, SafePoint(i + 1, -max), SafePoint(i, -max)); //Bottom Left Side
                    DrawLine(canvas, color, SafePoint(-max, i + 1), SafePoint(-max, i)); //Bottom Right Side
                }

                //Temporary Draw all the Redpoints.
                foreach (var point in GameGrid.RedPoints)
                {
                    DrawPoint(canvas, Color.Red, point);
                }

                //Temporary Draw all the Greenpoints.
                foreach (var point in GreenPoints)
                {
                    DrawPoint(canvas, Color.Green, point);
                }

                foreach (var building in buildings)
                {
                    var color = Color.White;
                    if (building.GetType() == typeof(ElixirCollector) || building.GetType() == typeof(ElixirStorage))
                    {
                        color = Color.Violet;
                    }
                    if (building.GetType() == typeof(GoldMine) || building.GetType() == typeof(GoldStorage))
                    {
                        color = Color.Gold;
                    }
                    if (building.GetType() == typeof(DarkElixirDrill) || building.GetType() == typeof(DarkElixirStorage))
                    {
                        color = Color.Brown;
                    }

                    //Draw a target on each building.
                    Visualize.Target(canvas, building.Location.GetCenter(), 40, color);
                }
                //Save the Image to the Debug Folder...
                Screenshot.Save(canvas, $"{debugFileName}_2");
            }

            //Get a screen Capture of all targets we found...
            using (Bitmap canvas = Screenshot.Capture())
            {
                foreach (var target in targetList)
                {
                    var color = Color.White;
                    if (target.TargetBuilding.GetType() == typeof(ElixirCollector) || target.TargetBuilding.GetType() == typeof(ElixirStorage))
                    {
                        color = Color.Violet;
                    }
                    if (target.TargetBuilding.GetType() == typeof(GoldMine) || target.TargetBuilding.GetType() == typeof(GoldStorage))
                    {
                        color = Color.Gold;
                    }
                    if (target.TargetBuilding.GetType() == typeof(DarkElixirDrill) || target.TargetBuilding.GetType() == typeof(DarkElixirStorage))
                    {
                        color = Color.Brown;
                    }

                    //Draw a target on each building.
                    Visualize.Target(canvas, target.TargetBuilding.Location.GetCenter(), 40, color);
                    Visualize.Target(canvas, target.DeployGrunts, 20, color);
                    Visualize.Target(canvas, target.DeployRanged, 20, color);
                }
                //Save the Image to the Debug Folder...
                Screenshot.Save(canvas, $"{debugFileName}_3");
            }

            Log.Debug("[Berts Algorithms] Collector/Storage & Target Debug Images Saved!");
        }
        public static Target[] GenerateTargets(float minimumDistance, bool ignoreGold, bool ignoreElixir, CacheBehavior behavior = CacheBehavior.Default, bool outputDebugImage = false)
        {
            // Find all Collectors & storages just sitting around...
            List <Building> buildings = new List <Building>();

            if (!ignoreGold)
            {
                //User has Gold min set to ZERO - which means Dont include Gold Targets
                buildings.AddRange(GoldMine.Find(behavior));
                buildings.AddRange(GoldStorage.Find(behavior));
            }

            if (!ignoreElixir)
            {
                //User has Elixir min set to ZERO - which means Dont include Elixir Targets
                buildings.AddRange(ElixirCollector.Find(behavior));
                buildings.AddRange(ElixirStorage.Find(behavior));
            }

            //We always includ DarkElixir - Because who doesnt love dark Elixir?
            buildings.AddRange(DarkElixirDrill.Find(behavior));
            buildings.AddRange(DarkElixirStorage.Find(behavior));

            List <Target> targetList = new List <Target>();

            foreach (Building building in buildings)
            {
                Target current = new Target();

                current.TargetBuilding  = building;
                current.Center          = building.Location.GetCenter();
                current.NearestRedLine  = GameGrid.RedPoints.OrderBy(p => p.DistanceSq(current.Center)).First();
                current.CenterToRedline = current.Center.DistanceSq(current.NearestRedLine);
                Log.Debug($"[Berts Algorithms] DistanceSq from {current.Name} to red point: {current.CenterToRedline.ToString("F1")}");
                if (current.CenterToRedline < minimumDistance)                                                                              //Compare distance to Redline to the Minimum acceptable distance Passed in
                {
                    current.DeployGrunts = current.Center.PointOnLineAwayFromEnd(current.NearestRedLine, _gruntDeployDistanceFromRedline);  //Barbs & Goblins
                    current.DeployRanged = current.Center.PointOnLineAwayFromEnd(current.NearestRedLine, _rangedDeployDistanceFromRedline); //Archers & Minions

                    targetList.Add(current);
                }
            }

            if (outputDebugImage)
            {
                var d             = DateTime.UtcNow;
                var debugFileName = $"Human Barch {d.Year}-{d.Month}-{d.Day} {d.Hour}-{d.Minute}-{d.Second}-{d.Millisecond}";
                //Get a screen Capture of all targets we found...
                using (Bitmap canvas = Screenshot.Capture())
                {
                    Screenshot.Save(canvas, $"{debugFileName}_1");

                    foreach (var building in buildings)
                    {
                        var color = Color.White;
                        if (building.GetType() == typeof(ElixirCollector) || building.GetType() == typeof(ElixirStorage))
                        {
                            color = Color.Violet;
                        }
                        if (building.GetType() == typeof(GoldMine) || building.GetType() == typeof(GoldStorage))
                        {
                            color = Color.Gold;
                        }
                        if (building.GetType() == typeof(DarkElixirDrill) || building.GetType() == typeof(DarkElixirStorage))
                        {
                            color = Color.Brown;
                        }

                        //Draw a target on each building.
                        Visualize.Target(canvas, building.Location.GetCenter(), 40, color);
                    }
                    //Save the Image to the Debug Folder...
                    Screenshot.Save(canvas, $"{debugFileName}_2");
                }

                //Get a screen Capture of all targets we found...
                using (Bitmap canvas = Screenshot.Capture())
                {
                    foreach (var target in targetList)
                    {
                        var color = Color.White;
                        if (target.TargetBuilding.GetType() == typeof(ElixirCollector) || target.TargetBuilding.GetType() == typeof(ElixirStorage))
                        {
                            color = Color.Violet;
                        }
                        if (target.TargetBuilding.GetType() == typeof(GoldMine) || target.TargetBuilding.GetType() == typeof(GoldStorage))
                        {
                            color = Color.Gold;
                        }
                        if (target.TargetBuilding.GetType() == typeof(DarkElixirDrill) || target.TargetBuilding.GetType() == typeof(DarkElixirStorage))
                        {
                            color = Color.Brown;
                        }

                        //Draw a target on each building.
                        Visualize.Target(canvas, target.TargetBuilding.Location.GetCenter(), 40, color);
                        Visualize.Target(canvas, target.DeployGrunts, 20, color);
                        Visualize.Target(canvas, target.DeployRanged, 20, color);
                    }
                    //Save the Image to the Debug Folder...
                    Screenshot.Save(canvas, $"{debugFileName}_3");
                }

                Log.Debug("[Berts Algorithms] Collector/Storage & Target Debug Images Saved!");
            }

            Log.Debug($"[Berts Algorithms] Found {targetList.Count} deploy points");

            return(targetList.ToArray());
        }