/// <summary>
        /// Get the core of the opponent base
        /// </summary>
        public static void SetCore()
        {
            var maxRedPointX = (GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Max(point => point.X) ?? GameGrid.MaxX);
            var minRedPointX = (GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Min(point => point.X) ?? GameGrid.MinX);
            var maxRedPointY = (GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Max(point => point.Y) ?? GameGrid.MaxY);
            var minRedPointY = (GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Min(point => point.Y) ?? GameGrid.MinY);

            // Build a box around the base
            var left   = new PointFT(minRedPointX, maxRedPointY);
            var top    = new PointFT(maxRedPointX, maxRedPointY);
            var right  = new PointFT(maxRedPointX, minRedPointY);
            var bottom = new PointFT(minRedPointX, minRedPointY);

            // Draw border around the base
            var border = new RectangleT((int)minRedPointX, (int)maxRedPointY, (int)(maxRedPointX - minRedPointX), (int)(minRedPointY - maxRedPointY));

            // Core is center of the box
            SmartFourFingersDeploy.Core = border.GetCenter();
        }
        /// <summary>
        /// create depoly points for troops and spells
        /// </summary>
        private void CreateDeployPoints()
        {
            float getOutRedArea = 0.25f;

            // don't include corners in case build huts are there
            float maxRedPointX = (GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Max(point => point.X) + 1 ?? GameGrid.RedZoneExtents.MaxX) + getOutRedArea;
            float minRedPointX = (GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Min(point => point.X) - 1 ?? GameGrid.RedZoneExtents.MinX) - getOutRedArea;
            float maxRedPointY = (GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Max(point => point.Y) + 1 ?? GameGrid.RedZoneExtents.MaxY) + getOutRedArea;
            float minRedPointY = (GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Min(point => point.Y) - 1 ?? GameGrid.RedZoneExtents.MinY) - getOutRedArea;
            // build a box around the base
            PointFT left   = new PointFT(minRedPointX, maxRedPointY);
            PointFT top    = new PointFT(maxRedPointX, maxRedPointY);
            PointFT right  = new PointFT(maxRedPointX, minRedPointY);
            PointFT bottom = new PointFT(minRedPointX, minRedPointY);


            // border around the base
            _border = new RectangleT((int)minRedPointX, (int)maxRedPointY, (int)(maxRedPointX - minRedPointX), (int)(minRedPointY - maxRedPointY));

            // core is center of the box
            _core = _border.GetCenter();

            PointFT[] orginPoints = new[]
            {
                new PointFT(maxRedPointX, _core.Y),
                new PointFT(minRedPointX, _core.Y),
                new PointFT(_core.X, maxRedPointY),
                new PointFT(_core.X, minRedPointY)
            };

            _orgin = new Container <PointFT> {
                Item = orginPoints.OrderBy(point => point.DistanceSq(_target)).First()
            };
            #region top right
            if (_orgin.Item.X > _core.X)
            {
                Log.Info("[Goblin Knife] Attacking from the top right");

                _attackLine = new Tuple <PointFT, PointFT>(top, right);

                _earthQuakePoint = new PointFT(_target.X + 5.5f, _core.Y);
                _jumpPoint       = new PointFT(_target.X + 5f, _core.Y);
                _healPoint       = new PointFT(_orgin.Item.X - 13f, _core.Y);
                _ragePoint       = new PointFT(_orgin.Item.X - 9f, _core.Y);
            }
            #endregion

            #region bottom left
            else if (_orgin.Item.X < _core.X)
            {
                Log.Info("[Goblin Knife] Attacking from the bottom left");

                _attackLine = new Tuple <PointFT, PointFT>(bottom, left);

                _earthQuakePoint = new PointFT(_target.X - 5.5f, _core.Y);
                _jumpPoint       = new PointFT(_target.X - 5f, _core.Y);
                _healPoint       = new PointFT(_orgin.Item.X + 13f, _core.Y);
                _ragePoint       = new PointFT(_orgin.Item.X + 9f, _core.Y);
            }
            #endregion

            #region top left
            else if (_orgin.Item.Y > _core.Y)
            {
                Log.Info("[Goblin Knife] Attacking from the top left");

                _attackLine = new Tuple <PointFT, PointFT>(left, top);

                _earthQuakePoint = new PointFT(_core.X, _target.Y + 5.5f);
                _jumpPoint       = new PointFT(_core.X, _target.Y + 5f);
                _healPoint       = new PointFT(_core.X, _orgin.Item.Y - 13f);
                _ragePoint       = new PointFT(_core.X, _orgin.Item.Y - 9f);
            }
            #endregion

            #region bottom right
            else // (orgin.Y < core.Y)
            {
                Log.Info("[Goblin Knife] Attacking from the bottom right");

                _attackLine = new Tuple <PointFT, PointFT>(right, bottom);

                _earthQuakePoint = new PointFT(_core.X, _target.Y - 5.5f);
                _jumpPoint       = new PointFT(_core.X, _target.Y - 5f);
                _healPoint       = new PointFT(_core.X, _orgin.Item.Y + 13f);
                _ragePoint       = new PointFT(_core.X, _orgin.Item.Y + 9f);
            }
            #endregion
        }
        private void CreateDeployPoints(bool qw)
        {
            var target = TownHall.Find()?.Location.GetCenter() ??
                         DarkElixirStorage.Find().FirstOrDefault()?.Location.GetCenter() ??
                         new PointFT(0, 0);

            // don't include corners in case build huts are there
            var maxRedPointX = GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Max(point => point.X) + 1 ?? GameGrid.RedZoneExtents.MaxX;
            var minRedPointX = GameGrid.RedPoints.Where(p => - 18 < p.Y && p.Y < 18)?.Min(point => point.X) - 1 ?? GameGrid.RedZoneExtents.MinX;
            var maxRedPointY = GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Max(point => point.Y) + 1 ?? GameGrid.RedZoneExtents.MaxY;
            var minRedPointY = GameGrid.RedPoints.Where(p => - 18 < p.X && p.X < 18)?.Min(point => point.Y) - 1 ?? GameGrid.RedZoneExtents.MinY;

            // build a box around the base
            var left   = new PointFT(minRedPointX, maxRedPointY);
            var top    = new PointFT(maxRedPointX, maxRedPointY);
            var right  = new PointFT(maxRedPointX, minRedPointY);
            var bottom = new PointFT(minRedPointX, minRedPointY);

            // border around the base
            _border = new RectangleT((int)minRedPointX, (int)maxRedPointY, (int)(maxRedPointX - minRedPointX), (int)(minRedPointY - maxRedPointY));

            // core is center of the box
            _core = _border.GetCenter();

            var orginPoints = new[]
            {
                new PointFT(maxRedPointX, _core.Y),
                new PointFT(minRedPointX, _core.Y),
                new PointFT(_core.X, maxRedPointY),
                new PointFT(_core.X, minRedPointY)
            };

            _orgin = new Container <PointFT> {
                Item = orginPoints.OrderBy(point => point.DistanceSq(target)).First()
            };

            if (_orgin.Item.X > _core.X)
            {
                Log.Info("[Breakthrough] Attacking from the top right");

                var redLinePoint = GameGrid.RedPoints
                                   .Where(point => point.Y > -10 && point.Y < 10)?
                                   .Max(point => point.X) ?? GameGrid.RedZoneExtents.MaxX;

                if (qw)
                {
                    _qwPoint        = right;
                    _queenRagePoint = new PointFT(right.X - 5, right.Y + 5);
                    _healerPoint    = new PointFT(24f, -24f);
                    _attackLine     = new Tuple <PointFT, PointFT>(top, _orgin.Item.Midpoint(right));
                }
                else
                {
                    _attackLine  = new Tuple <PointFT, PointFT>(top, right);
                    _healerPoint = new PointFT(24f, _core.Y);
                }
                _healPoint = new PointFT(redLinePoint - 12f, _core.Y);
                _ragePoint = new PointFT(redLinePoint - 9f, _core.Y);
            }
            else if (_orgin.Item.X < _core.X)
            {
                Log.Info("[Breakthrough] Attacking from the bottom left");

                var redLinePoint = GameGrid.RedPoints
                                   .Where(point => point.Y > -10 && point.Y < 10)?
                                   .Min(point => point.X) ?? GameGrid.RedZoneExtents.MinX;

                if (qw)
                {
                    _qwPoint        = left;
                    _queenRagePoint = new PointFT(left.X + 5, left.Y - 5);
                    _healerPoint    = new PointFT(-24f, 24f);
                    _attackLine     = new Tuple <PointFT, PointFT>(bottom, _orgin.Item.Midpoint(left));
                }
                else
                {
                    _healerPoint = new PointFT(-24f, _core.Y);
                    _attackLine  = new Tuple <PointFT, PointFT>(bottom, left);
                }
                _healPoint = new PointFT(redLinePoint + 12, _core.Y);
                _ragePoint = new PointFT(redLinePoint + 9, _core.Y);
            }
            else if (_orgin.Item.Y > _core.Y)
            {
                Log.Info("[Breakthrough] Attacking from the top left");

                var redLinePoint = GameGrid.RedPoints
                                   .Where(point => point.X > -10 && point.X < 10)?
                                   .Max(point => point.Y) ?? GameGrid.RedZoneExtents.MaxY;

                if (qw)
                {
                    _qwPoint        = left;
                    _queenRagePoint = new PointFT(left.X + 5f, left.Y - 5f);
                    _healerPoint    = new PointFT(-24f, 24f);
                    _attackLine     = new Tuple <PointFT, PointFT>(top, _orgin.Item.Midpoint(left));
                }
                else
                {
                    _healerPoint = new PointFT(_core.X, 24f);
                    _attackLine  = new Tuple <PointFT, PointFT>(left, top);
                }
                _healPoint = new PointFT(_core.X, redLinePoint - 12f);
                _ragePoint = new PointFT(_core.X, redLinePoint - 9f);
            }
            else // (orgin.Y < core.Y)
            {
                Log.Info("[Breakthrough] Attacking from the bottom right");

                var redLinePoint = GameGrid.RedPoints
                                   .Where(point => point.X > -10 && point.X < 10)?
                                   .Min(point => point.Y) ?? GameGrid.RedZoneExtents.MinY;

                if (qw)
                {
                    _qwPoint        = right;
                    _queenRagePoint = new PointFT(right.X - 5, right.Y + 5);
                    _healerPoint    = new PointFT(24f, -24f);
                    _attackLine     = new Tuple <PointFT, PointFT>(bottom, _orgin.Item.Midpoint(right));
                }
                else
                {
                    _healerPoint = new PointFT(_core.X, -24f);
                    _attackLine  = new Tuple <PointFT, PointFT>(right, bottom);
                }
                _healPoint = new PointFT(_core.X, redLinePoint + 12);
                _ragePoint = new PointFT(_core.X, redLinePoint + 9);
            }
        }