示例#1
0
        public void CreateNatural(List <uint> types)
        {
            BoolGrid pathable     = Tyr.Bot.MapAnalyzer.Pathable;
            BoolGrid unPathable   = pathable.Invert();
            Point2D  naturalExit  = Tyr.Bot.BaseManager.NaturalDefensePos;
            BoolGrid naturalWalls = unPathable.GetConnected(new Point2D()
            {
                X = 0, Y = 0
            }).Crop((int)naturalExit.X - 12, (int)naturalExit.Y - 12, (int)naturalExit.X + 12, (int)naturalExit.Y + 12);
            List <BoolGrid>            sides  = naturalWalls.GetGroups();
            Dictionary <BoolGrid, int> counts = new Dictionary <BoolGrid, int>();

            foreach (BoolGrid side in sides)
            {
                counts.Add(side, side.Count());
            }
            sides.Sort((BoolGrid a, BoolGrid b) => counts[b] - counts[a]);

            List <Point2D> building1Positions = Placable(sides[0], Tyr.Bot.MapAnalyzer.Placement, BuildingType.LookUp[types[0]].Size, false);
            List <Point2D> building2Positions = Placable(sides[1], Tyr.Bot.MapAnalyzer.Placement, BuildingType.LookUp[types[3]].Size, false);
            int            naturalHeight      = Tyr.Bot.MapAnalyzer.MapHeight((int)Tyr.Bot.BaseManager.Natural.BaseLocation.Pos.X, (int)Tyr.Bot.BaseManager.Natural.BaseLocation.Pos.Y);

            building1Positions = building1Positions.FindAll((p) => Tyr.Bot.MapAnalyzer.MapHeight((int)p.X, (int)p.Y) == naturalHeight);
            building2Positions = building2Positions.FindAll((p) => Tyr.Bot.MapAnalyzer.MapHeight((int)p.X, (int)p.Y) == naturalHeight);


            FindWall(types, building1Positions, building2Positions, Tyr.Bot.MapAnalyzer.Placement, false);
            //DrawResult(unPathable, naturalWalls, building1Positions, building2Positions);
        }
示例#2
0
        public BoolGrid Invert()
        {
            BoolGrid result = Clone();

            result.inverted = true;
            return(result);
        }
示例#3
0
        private BoolGrid Placable(BoolGrid around, BoolGrid shrunkenStart)
        {
            ArrayBoolGrid result = new ArrayBoolGrid(around.Width(), around.Height());

            for (int x = 0; x < around.Width(); x++)
            {
                for (int y = 0; y < around.Height(); y++)
                {
                    if (around[x, y])
                    {
                        for (int i = -2; i <= 2; i++)
                        {
                            if (shrunkenStart[x + i, y - 2])
                            {
                                result[x + i, y - 2] = true;
                            }
                            if (shrunkenStart[x + i, y + 2])
                            {
                                result[x + i, y + 2] = true;
                            }
                            if (shrunkenStart[x + 2, y + i])
                            {
                                result[x + 2, y + i] = true;
                            }
                            if (shrunkenStart[x - 2, y + i])
                            {
                                result[x - 2, y + i] = true;
                            }
                        }
                    }
                }
            }
            return(result);
        }
示例#4
0
 private void check(BoolGrid pathingData, int[,] distances, Queue <Point2D> q, Point2D pos, int width, int height, int newVal)
 {
     if (check(pathingData, pos, width, height) && distances[(int)pos.X, (int)pos.Y] == 1000000000)
     {
         q.Enqueue(pos);
         distances[(int)pos.X, (int)pos.Y] = newVal;
     }
 }
示例#5
0
 private bool CheckRect(BoolGrid grid, Point2D pos, Point2D size)
 {
     return(CheckRect(grid,
                      pos.X - size.X / 2f + 0.5f,
                      pos.Y - size.Y / 2f + 0.5f,
                      pos.X + size.X / 2f - 0.5f,
                      pos.Y + size.Y / 2f - 0.5f));
 }
示例#6
0
 private bool CheckRect(BoolGrid grid, float minX, float minY, float maxX, float maxY)
 {
     for (float x = minX; x < maxX + 0.1f; x++)
     {
         for (float y = minY; y < maxY + 0.1f; y++)
         {
             if (!grid[(int)x, (int)y])
             {
                 return(false);
             }
         }
     }
     return(true);
 }
示例#7
0
        public BoolGrid GetAdjacent(BoolGrid other)
        {
            ArrayBoolGrid result = new ArrayBoolGrid(Width(), Height());

            for (int x = 0; x < Width(); x++)
            {
                for (int y = 0; y < Height(); y++)
                {
                    result[x, y] = this[x, y] && (other[x + 1, y] || other[x - 1, y] || other[x, y + 1] || other[x, y - 1]);
                }
            }

            return(result);
        }
示例#8
0
        public BoolGrid GetAnd(BoolGrid other)
        {
            ArrayBoolGrid result = new ArrayBoolGrid(Width(), Height());

            for (int x = 0; x < Width(); x++)
            {
                for (int y = 0; y < Height(); y++)
                {
                    result[x, y] = this[x, y] && other[x, y];
                }
            }

            return(result);
        }
示例#9
0
        private void GetPlacableAround(BoolGrid startArea, Point2D pos, Point2D size1, Point2D size2, ICollection <Point2D> result)
        {
            float xOffset = (size1.X + size2.X) / 2f;
            float yOffset = (size1.Y + size2.Y) / 2f;

            for (float i = -xOffset; i < 0.1f + xOffset; i++)
            {
                Point2D checkPos = new Point2D()
                {
                    X = pos.X + i, Y = pos.Y - yOffset
                };
                if (CheckRect(startArea, checkPos, size2))
                {
                    result.Add(checkPos);
                }
                checkPos = new Point2D()
                {
                    X = pos.X + i, Y = pos.Y + yOffset
                };
                if (CheckRect(startArea, checkPos, size2))
                {
                    result.Add(checkPos);
                }
            }
            for (float i = -yOffset; i < 0.1f + yOffset; i++)
            {
                Point2D checkPos = new Point2D()
                {
                    X = pos.X + xOffset, Y = pos.Y + i
                };
                if (CheckRect(startArea, checkPos, size2))
                {
                    result.Add(checkPos);
                }
                checkPos = new Point2D()
                {
                    X = pos.X - xOffset, Y = pos.Y + i
                };
                if (CheckRect(startArea, checkPos, size2))
                {
                    result.Add(checkPos);
                }
            }
        }
示例#10
0
        public BoolGrid GetConnected(BoolGrid connectedTo, int steps)
        {
            ArrayBoolGrid result = new ArrayBoolGrid(Width(), Height());

            Queue <Point2D> q1 = new Queue <Point2D>();

            for (int x = 0; x < Width(); x++)
            {
                for (int y = 0; y < Height(); y++)
                {
                    if (connectedTo[x, y])
                    {
                        q1.Enqueue(SC2Util.Point(x, y));
                    }
                }
            }

            Queue <Point2D> q2 = new Queue <Point2D>();

            for (int i = 0; i < steps; i++)
            {
                while (q1.Count > 0)
                {
                    Point2D cur = q1.Dequeue();
                    if (cur.X < 0 || cur.Y < 0 || cur.X >= Width() || cur.Y >= Height())
                    {
                        continue;
                    }
                    if (Get(cur) && !result[cur])
                    {
                        result[cur] = true;
                        q2.Enqueue(SC2Util.Point(cur.X + 1, cur.Y));
                        q2.Enqueue(SC2Util.Point(cur.X - 1, cur.Y));
                        q2.Enqueue(SC2Util.Point(cur.X, cur.Y + 1));
                        q2.Enqueue(SC2Util.Point(cur.X, cur.Y - 1));
                    }
                }
                q1 = q2;
                q2 = new Queue <Point2D>();
            }
            return(result);
        }
示例#11
0
        public int[,] Distances(BoolGrid start)
        {
            int       width       = Tyr.Bot.GameInfo.StartRaw.MapSize.X;
            int       height      = Tyr.Bot.GameInfo.StartRaw.MapSize.Y;
            ImageData pathingData = Tyr.Bot.GameInfo.StartRaw.PathingGrid;

            int[,] distances = new int[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    distances[x, y] = 1000000000;
                }
            }


            Queue <Point2D> q = new Queue <Point2D>();

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (start[x, y])
                    {
                        distances[x, y] = 0;
                        q.Enqueue(SC2Util.Point(x, y));
                    }
                }
            }

            while (q.Count > 0)
            {
                Point2D cur = q.Dequeue();
                check(pathingData, distances, q, SC2Util.Point(cur.X + 1, cur.Y), width, height, distances[(int)cur.X, (int)cur.Y] + 1);
                check(pathingData, distances, q, SC2Util.Point(cur.X - 1, cur.Y), width, height, distances[(int)cur.X, (int)cur.Y] + 1);
                check(pathingData, distances, q, SC2Util.Point(cur.X, cur.Y + 1), width, height, distances[(int)cur.X, (int)cur.Y] + 1);
                check(pathingData, distances, q, SC2Util.Point(cur.X, cur.Y - 1), width, height, distances[(int)cur.X, (int)cur.Y] + 1);
            }

            return(distances);
        }
示例#12
0
        private bool CheckPlacement(List <uint> types, Point2D start, Point2D end, BoolGrid placable, int i, bool full)
        {
            int spaceBetween = full ? 5 : 4;

            if (CheckPlacement(types, start, end, SC2Util.Point(end.X + i, end.Y + spaceBetween), placable, full))
            {
                return(true);
            }
            if (CheckPlacement(types, start, end, SC2Util.Point(end.X + i, end.Y - spaceBetween), placable, full))
            {
                return(true);
            }
            if (CheckPlacement(types, start, end, SC2Util.Point(end.X + spaceBetween, end.Y + i), placable, full))
            {
                return(true);
            }
            if (CheckPlacement(types, start, end, SC2Util.Point(end.X - spaceBetween, end.Y + i), placable, full))
            {
                return(true);
            }
            return(false);
        }
示例#13
0
        private void DrawRamp(BoolGrid startArea, BoolGrid chokes, BoolGrid ramps)
        {
            if (!Tyr.Debug)
            {
                return;
            }

            int width  = Tyr.Bot.GameInfo.StartRaw.PathingGrid.Size.X;
            int height = Tyr.Bot.GameInfo.StartRaw.PathingGrid.Size.Y;

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (ramps[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Blue);
                    }
                    else if (chokes[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Orange);
                    }
                    else if (startArea[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Black);
                    }
                    else
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.White);
                    }
                }
            }

            bmp.Save(Directory.GetCurrentDirectory() + "/data/Ramp.png");
        }
示例#14
0
        private List <Point2D> Placable(BoolGrid around, BoolGrid startArea, Point2D size)
        {
            Point2D size1x1 = new Point2D()
            {
                X = 1, Y = 1
            };
            List <Point2D> result = new List <Point2D>();

            for (int x = 0; x < around.Width(); x++)
            {
                for (int y = 0; y < around.Height(); y++)
                {
                    if (around[x, y])
                    {
                        GetPlacableAround(startArea, new Point2D()
                        {
                            X = x, Y = y
                        }, size1x1, size, result);
                    }
                }
            }

            return(result);
        }
示例#15
0
        private bool check(BoolGrid pathingData, Point2D pos, int width, int height)
        {
            if (pos.X < 0 || pos.X >= width || pos.Y < 0 || pos.Y >= height)
            {
                return(false);
            }
            if (pathingData[pos])
            {
                return(true);
            }

            foreach (Point2D p in Tyr.Bot.GameInfo.StartRaw.StartLocations)
            {
                if (SC2Util.DistanceGrid(pos, p) <= 3)
                {
                    return(true);
                }
            }
            if (SC2Util.DistanceGrid(pos, StartLocation) <= 3)
            {
                return(true);
            }
            return(false);
        }
示例#16
0
        private void DrawPathing(BoolGrid pathable, BoolGrid placememt)
        {
            if (!Tyr.Debug)
            {
                return;
            }

            int width  = Tyr.Bot.GameInfo.StartRaw.PathingGrid.Size.X;
            int height = Tyr.Bot.GameInfo.StartRaw.PathingGrid.Size.Y;

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (pathable[x, y] && placememt[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Purple);
                    }
                    else if (pathable[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Blue);
                    }
                    else if (placememt[x, y])
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Red);
                    }
                    else
                    {
                        bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Black);
                    }
                }
            }

            bmp.Save(Directory.GetCurrentDirectory() + "/data/Pathing.png");
        }
示例#17
0
 private bool CheckPlacement(List <uint> types, Point2D start, Point2D end, Point2D middle, BoolGrid placable, bool full)
 {
     if (full)
     {
         return(CheckPlacementFull(types, start, end, middle, placable));
     }
     else
     {
         return(CheckPlacement(types, start, end, middle, placable));
     }
 }
示例#18
0
 private void FindWall(List <uint> types, List <Point2D> startPositions, List <Point2D> endPositions, BoolGrid placable, bool full)
 {
     foreach (Point2D start in startPositions)
     {
         foreach (Point2D end in endPositions)
         {
             if (Math.Abs(start.X - end.X) > 7 ||
                 Math.Abs(start.Y - end.Y) > 7)
             {
                 continue;
             }
             for (int i = -1; i <= 1; i++)
             {
                 if (CheckPlacement(types, start, end, placable, i, full))
                 {
                     return;
                 }
             }
         }
     }
     foreach (Point2D start in startPositions)
     {
         foreach (Point2D end in endPositions)
         {
             if (Math.Abs(start.X - end.X) > 7 ||
                 Math.Abs(start.Y - end.Y) > 7)
             {
                 continue;
             }
             if (CheckPlacement(types, start, end, placable, -2, full))
             {
                 return;
             }
             if (CheckPlacement(types, start, end, placable, 2, full))
             {
                 return;
             }
         }
     }
 }
示例#19
0
        public void Analyze(Tyr tyr)
        {
            // Determine the start location.
            foreach (Unit unit in tyr.Observation.Observation.RawData.Units)
            {
                if (unit.Owner == tyr.PlayerId && UnitTypes.ResourceCenters.Contains(unit.UnitType))
                {
                    StartLocation = unit.Pos;
                }
            }

            List <MineralField> mineralFields = new List <MineralField>();

            foreach (Unit mineralField in tyr.Observation.Observation.RawData.Units)
            {
                if (UnitTypes.MineralFields.Contains(mineralField.UnitType))
                {
                    mineralFields.Add(new MineralField()
                    {
                        Pos = mineralField.Pos, Tag = mineralField.Tag
                    });
                }
            }

            Dictionary <ulong, int>     mineralSetIds = new Dictionary <ulong, int>();
            List <List <MineralField> > mineralSets   = new List <List <MineralField> >();
            int currentSet = 0;

            foreach (MineralField mineralField in mineralFields)
            {
                if (mineralSetIds.ContainsKey(mineralField.Tag))
                {
                    continue;
                }
                BaseLocation baseLocation = new BaseLocation();
                BaseLocations.Add(baseLocation);
                mineralSetIds.Add(mineralField.Tag, currentSet);
                baseLocation.MineralFields.Add(mineralField);

                for (int i = 0; i < baseLocation.MineralFields.Count; i++)
                {
                    MineralField mineralFieldA = baseLocation.MineralFields[i];
                    foreach (MineralField closeMineralField in mineralFields)
                    {
                        if (mineralSetIds.ContainsKey(closeMineralField.Tag))
                        {
                            continue;
                        }

                        if (SC2Util.DistanceGrid(mineralFieldA.Pos, closeMineralField.Pos) <= 5)
                        {
                            mineralSetIds.Add(closeMineralField.Tag, currentSet);
                            baseLocation.MineralFields.Add(closeMineralField);
                        }
                    }
                }
                currentSet++;
            }

            List <Gas> gasses = new List <Gas>();

            foreach (Unit unit in tyr.Observation.Observation.RawData.Units)
            {
                if (UnitTypes.GasGeysers.Contains(unit.UnitType))
                {
                    gasses.Add(new Gas()
                    {
                        Pos = unit.Pos, Tag = unit.Tag
                    });
                }
            }

            foreach (BaseLocation loc in BaseLocations)
            {
                float x = 0;
                float y = 0;
                foreach (MineralField field in loc.MineralFields)
                {
                    x += (int)field.Pos.X;
                    y += (int)field.Pos.Y;
                }
                x /= loc.MineralFields.Count;
                y /= loc.MineralFields.Count;

                // Round to nearest half position. Nexii are 5x5 and therefore always centered in the middle of a tile.
                x = (int)(x) + 0.5f;
                y = (int)(y) + 0.5f;

                // Temporary position, we still need a proper position.
                loc.Pos = SC2Util.Point(x, y);

                MineralField closest  = null;
                float        distance = 10000;
                foreach (MineralField field in loc.MineralFields)
                {
                    if (SC2Util.DistanceGrid(field.Pos, loc.Pos) < distance)
                    {
                        distance = SC2Util.DistanceGrid(field.Pos, loc.Pos);
                        closest  = field;
                    }
                }

                // Move the estimated base position slightly away from the closest mineral.
                // This ensures that the base location will not end up on the far side of the minerals.
                if (closest.Pos.X < loc.Pos.X)
                {
                    loc.Pos.X += 2;
                }
                else if (closest.Pos.X > loc.Pos.X)
                {
                    loc.Pos.X -= 2;
                }
                if (closest.Pos.Y < loc.Pos.Y)
                {
                    loc.Pos.Y += 2;
                }
                else if (closest.Pos.Y > loc.Pos.Y)
                {
                    loc.Pos.Y -= 2;
                }

                for (int i = 0; i < gasses.Count; i++)
                {
                    if (SC2Util.DistanceGrid(loc.Pos, gasses[i].Pos) <= 24)
                    {
                        loc.Gasses.Add(gasses[i]);
                        gasses[i] = gasses[gasses.Count - 1];
                        gasses.RemoveAt(gasses.Count - 1);
                        i--;
                    }
                }

                float closestDist = 1000000;
                for (int i = 0; i < 20; i++)
                {
                    for (int j = 0; j == 0 || j < i; j++)
                    {
                        float   maxDist;
                        Point2D newPos;
                        newPos  = SC2Util.Point(loc.Pos.X + i - j, loc.Pos.Y + j);
                        maxDist = checkPosition(newPos, loc);
                        if (maxDist < closestDist)
                        {
                            loc.Pos     = newPos;
                            closestDist = maxDist;
                        }

                        newPos  = SC2Util.Point(loc.Pos.X + i - j, loc.Pos.Y - j);
                        maxDist = checkPosition(newPos, loc);
                        if (maxDist < closestDist)
                        {
                            loc.Pos     = newPos;
                            closestDist = maxDist;
                        }

                        newPos  = SC2Util.Point(loc.Pos.X - i + j, loc.Pos.Y + j);
                        maxDist = checkPosition(newPos, loc);
                        if (maxDist < closestDist)
                        {
                            loc.Pos     = newPos;
                            closestDist = maxDist;
                        }

                        newPos  = SC2Util.Point(loc.Pos.X - i + j, loc.Pos.Y - j);
                        maxDist = checkPosition(newPos, loc);
                        if (maxDist < closestDist)
                        {
                            loc.Pos     = newPos;
                            closestDist = maxDist;
                        }
                    }
                }

                if (closestDist >= 999999)
                {
                    System.Console.WriteLine("Unable to find proper base placement: " + loc.Pos);
                }
            }

            if (tyr.GameInfo.MapName.Contains("Blueshift"))
            {
                foreach (BaseLocation loc in BaseLocations)
                {
                    if (SC2Util.DistanceSq(loc.Pos, SC2Util.Point(141.5f, 112.5f)) <= 5 * 5 && (loc.Pos.X != 141.5 || loc.Pos.Y != 112.5))
                    {
                        System.Console.WriteLine("Incorrect base location, fixing: " + loc.Pos);
                        loc.Pos = SC2Util.Point(141.5f, 112.5f);
                    }
                    else if (SC2Util.DistanceSq(loc.Pos, SC2Util.Point(34.5f, 63.5f)) <= 5 * 5 && (loc.Pos.X != 34.5 || loc.Pos.Y != 63.5))
                    {
                        System.Console.WriteLine("Incorrect base location, fixing: " + loc.Pos);
                        loc.Pos = SC2Util.Point(34.5f, 63.5f);
                    }
                }
            }

            Stopwatch stopWatch = Stopwatch.StartNew();

            int width  = Tyr.Bot.GameInfo.StartRaw.MapSize.X;
            int height = Tyr.Bot.GameInfo.StartRaw.MapSize.Y;

            Placement = new ImageBoolGrid(tyr.GameInfo.StartRaw.PlacementGrid);
            StartArea = Placement.GetConnected(SC2Util.To2D(StartLocation));

            ArrayBoolGrid startLocations = new ArrayBoolGrid(Placement.Width(), Placement.Height());

            foreach (Point2D startLoc in Tyr.Bot.GameInfo.StartRaw.StartLocations)
            {
                for (int x = -2; x <= 2; x++)
                {
                    for (int y = -2; y <= 2; y++)
                    {
                        startLocations[(int)startLoc.X + x, (int)startLoc.Y + y] = true;
                    }
                }
            }
            for (int x = -2; x <= 2; x++)
            {
                for (int y = -2; y <= 2; y++)
                {
                    startLocations[(int)StartLocation.X + x, (int)StartLocation.Y + y] = true;
                }
            }

            BoolGrid unPathable = new ImageBoolGrid(Tyr.Bot.GameInfo.StartRaw.PathingGrid).GetAnd(startLocations.Invert());
            BoolGrid pathable   = unPathable.Invert();

            BoolGrid chokes    = Placement.Invert().GetAnd(pathable);
            BoolGrid mainExits = chokes.GetAdjacent(StartArea);

            enemyDistances = EnemyDistances;
            int     dist     = 1000;
            Point2D mainRamp = null;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (mainExits[x, y])
                    {
                        int newDist = enemyDistances[x, y];
                        if (newDist < dist)
                        {
                            dist     = newDist;
                            mainRamp = SC2Util.Point(x, y);
                        }
                    }
                }
            }

            BoolGrid ramp = chokes.GetConnected(mainRamp);

            BoolGrid pathingWithoutRamp = pathable.GetAnd(ramp.Invert());

            MainAndPocketArea = pathingWithoutRamp.GetConnected(SC2Util.To2D(StartLocation));

            if (Tyr.Bot.MyRace == Race.Protoss)
            {
                DetermineWall(ramp, unPathable);
            }

            WallDistances = Distances(unPathable);

            stopWatch.Stop();
            System.Console.WriteLine("Total time to find wall: " + stopWatch.ElapsedMilliseconds);


            /*
             * System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
             * for (int x = 0; x < width; x++)
             *  for (int y = 0; y < height; y++)
             *  {
             *      if (WallDistances[x, y] == 0)
             *          bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Red);
             *      else if (WallDistances[x, y] >= 25)
             *          bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.Green);
             *      else
             *          bmp.SetPixel(x, height - 1 - y, System.Drawing.Color.FromArgb(WallDistances[x, y] * 10, WallDistances[x, y] * 10, WallDistances[x, y] * 10));
             *  }
             * foreach (BaseLocation loc in BaseLocations)
             *  for (int dx = -2; dx <= 2; dx++)
             *      for (int dy = -2; dy <= 2; dy++)
             *          bmp.SetPixel((int)loc.Pos.X + dx, height - 1 - (int)loc.Pos.Y - dy, System.Drawing.Color.Blue);
             *
             * foreach (Unit unit in tyr.Observation.Observation.RawData.Units)
             * {
             *  if (UnitTypes.GasGeysers.Contains(unit.UnitType))
             *      for (int dx = -1; dx <= 1; dx++)
             *          for (int dy = -1; dy <= 1; dy++)
             *              bmp.SetPixel((int)unit.Pos.X + dx, height - 1 - (int)unit.Pos.Y - dy, System.Drawing.Color.Cyan);
             *  if (UnitTypes.MineralFields.Contains(unit.UnitType))
             *      for (int dx = 0; dx <= 1; dx++)
             *          bmp.SetPixel((int)(unit.Pos.X - 0.5f) + dx, height - 1 - (int)(unit.Pos.Y - 0.5f), System.Drawing.Color.Cyan);
             * }
             * bmp.Save(@"C:\Users\Simon\Desktop\WallDistances.png");
             */
        }
示例#20
0
        private void DetermineWall(BoolGrid ramp, BoolGrid unPathable)
        {
            BoolGrid        rampAdjacent = unPathable.GetAdjacent(ramp);
            BoolGrid        rampSides    = unPathable.GetConnected(rampAdjacent, 5);
            List <BoolGrid> sides        = rampSides.GetGroups();

            BoolGrid shrunkenStart = StartArea.Shrink();

            List <Point2D> building1Positions = Placable(sides[0], shrunkenStart).ToList();
            List <Point2D> building2Positions = Placable(sides[1], shrunkenStart).ToList();

            float wallScore = 1000;


            foreach (Point2D p1 in building1Positions)
            {
                foreach (Point2D p2 in building2Positions)
                {
                    if (System.Math.Abs(p1.X - p2.X) < 3 && System.Math.Abs(p1.Y - p2.Y) < 3)
                    {
                        continue;
                    }

                    float newScore = SC2Util.DistanceGrid(p1, p2);
                    if (newScore >= wallScore)
                    {
                        continue;
                    }

                    for (float i = -2.5f; i < 3; i++)
                    {
                        if (CheckPylon(SC2Util.Point(p1.X + 2.5f, p1.Y + i), p1, p2))
                        {
                            wallScore = newScore;
                            building1 = p1;
                            building2 = p2;
                            building3 = SC2Util.Point(p1.X + 2.5f, p1.Y + i);
                        }
                        if (CheckPylon(SC2Util.Point(p1.X - 2.5f, p1.Y + i), p1, p2))
                        {
                            wallScore = newScore;
                            building1 = p1;
                            building2 = p2;
                            building3 = SC2Util.Point(p1.X - 2.5f, p1.Y + i);
                        }
                        if (CheckPylon(SC2Util.Point(p1.X + i, p1.Y + 2.5f), p1, p2))
                        {
                            wallScore = newScore;
                            building1 = p1;
                            building2 = p2;
                            building3 = SC2Util.Point(p1.X + i, p1.Y + 2.5f);
                        }
                        if (CheckPylon(SC2Util.Point(p1.X + i, p1.Y - 2.5f), p1, p2))
                        {
                            wallScore = newScore;
                            building1 = p1;
                            building2 = p2;
                            building3 = SC2Util.Point(p1.X + i, p1.Y - 2.5f);
                        }
                    }
                }
            }
        }
示例#21
0
        private bool CheckPlacement(List <uint> types, Point2D start, Point2D end, Point2D middle, BoolGrid placable)
        {
            if (!CheckRect(placable, middle.X - 1, middle.Y - 1, middle.X + 1, middle.Y + 1))
            {
                return(false);
            }

            if (Math.Abs(start.X - middle.X) == 3)
            {
                if (Math.Abs(start.Y - middle.Y) >= 3)
                {
                    return(false);
                }
            }
            else if (Math.Abs(start.Y - middle.Y) == 3)
            {
                if (Math.Abs(start.X - middle.X) >= 3)
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }

            Point2D zealotPos = SC2Util.Point(end.X, end.Y);

            zealotPos = SC2Util.TowardCardinal(zealotPos, middle, 2);
            zealotPos = SC2Util.TowardCardinal(zealotPos, Tyr.Bot.BaseManager.Natural.BaseLocation.Pos, 0.5f);

            /*
             * if (end.X - middle.X == 4)
             *  zealotPos.X -= 2;
             * else if (end.X - middle.X == -4)
             *  zealotPos.X += 2;
             * else if (end.Y - middle.Y == 4)
             *  zealotPos.Y -= 2;
             * else
             *  zealotPos.Y += 2;
             */
            Point2D[] pylonPositions = new Point2D[2];
            Point2D   natural        = Tyr.Bot.BaseManager.Natural.BaseLocation.Pos;

            if (Math.Abs(natural.X - middle.X) >= Math.Abs(natural.Y - middle.Y))
            {
                if (natural.X > middle.X)
                {
                    pylonPositions[0] = SC2Util.Point(middle.X + 2.5f, middle.Y + 0.5f);
                    pylonPositions[1] = SC2Util.Point(middle.X + 2.5f, middle.Y - 0.5f);
                }
                else
                {
                    pylonPositions[0] = SC2Util.Point(middle.X - 2.5f, middle.Y + 0.5f);
                    pylonPositions[1] = SC2Util.Point(middle.X - 2.5f, middle.Y - 0.5f);
                }

                /*
                 * if (natural.Y > middle.Y)
                 * {
                 *  pylonPositions[2] = SC2Util.Point(middle.X + 0.5f, middle.Y + 2.5f);
                 *  pylonPositions[3] = SC2Util.Point(middle.X - 0.5f, middle.Y + 2.5f);
                 * }
                 * else
                 * {
                 *  pylonPositions[2] = SC2Util.Point(middle.X + 0.5f, middle.Y - 2.5f);
                 *  pylonPositions[3] = SC2Util.Point(middle.X - 0.5f, middle.Y - 2.5f);
                 * }
                 */
            }
            else
            {
                if (natural.Y > middle.Y)
                {
                    pylonPositions[0] = SC2Util.Point(middle.X + 0.5f, middle.Y + 2.5f);
                    pylonPositions[1] = SC2Util.Point(middle.X - 0.5f, middle.Y + 2.5f);
                }
                else
                {
                    pylonPositions[0] = SC2Util.Point(middle.X + 0.5f, middle.Y - 2.5f);
                    pylonPositions[1] = SC2Util.Point(middle.X - 0.5f, middle.Y - 2.5f);
                }

                /*
                 * if (natural.X > middle.X)
                 * {
                 *  pylonPositions[2] = SC2Util.Point(middle.X + 2.5f, middle.Y + 0.5f);
                 *  pylonPositions[3] = SC2Util.Point(middle.X + 2.5f, middle.Y - 0.5f);
                 * }
                 * else
                 * {
                 *  pylonPositions[2] = SC2Util.Point(middle.X - 2.5f, middle.Y + 0.5f);
                 *  pylonPositions[3] = SC2Util.Point(middle.X - 2.5f, middle.Y - 0.5f);
                 * }
                 */
            }

            Point2D pylonPos = null;

            foreach (Point2D pos in pylonPositions)
            {
                if (ProtossBuildingPlacement.IsBuildingInPowerField(start, SC2Util.Point(3, 3), pos) &&
                    ProtossBuildingPlacement.IsBuildingInPowerField(end, SC2Util.Point(3, 3), pos) &&
                    Tyr.Bot.buildingPlacer.CheckDistanceClose(pos, UnitTypes.PYLON, start, types[0]) &&
                    Tyr.Bot.buildingPlacer.CheckDistanceClose(pos, UnitTypes.PYLON, end, types[3]))
                {
                    pylonPos = pos;
                }
            }
            if (pylonPos == null)
            {
                return(false);
            }

            Wall = new List <WallBuilding>();
            Wall.Add(new WallBuilding()
            {
                Pos = start, Type = types[0]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = middle, Type = types[1]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = zealotPos, Type = types[2]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = end, Type = types[3]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = pylonPos, Type = UnitTypes.PYLON
            });

            return(true);
        }
示例#22
0
        private bool CheckPlacementFull(List <uint> types, Point2D start, Point2D end, Point2D middle, BoolGrid placable)
        {
            if (!CheckRect(placable, middle.X - 1, middle.Y - 1, middle.X + 1, middle.Y + 1))
            {
                return(false);
            }

            if (Math.Abs(start.X - middle.X) == 3)
            {
                if (Math.Abs(start.Y - middle.Y) >= 3)
                {
                    return(false);
                }
            }
            else if (Math.Abs(start.Y - middle.Y) == 3)
            {
                if (Math.Abs(start.X - middle.X) >= 3)
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }

            Point2D pylonPos = SC2Util.Point(end.X, end.Y);

            pylonPos = SC2Util.TowardCardinal(pylonPos, middle, 2.5f);

            Wall = new List <WallBuilding>();
            Wall.Add(new WallBuilding()
            {
                Pos = start, Type = types[0]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = middle, Type = types[1]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = pylonPos, Type = types[2]
            });
            Wall.Add(new WallBuilding()
            {
                Pos = end, Type = types[3]
            });

            return(true);
        }
示例#23
0
        public void Create(List <uint> types)
        {
            foreach (uint type in types)
            {
                Wall.Add(new WallBuilding()
                {
                    Type = type
                });
            }


            BoolGrid unPathable = Tyr.Bot.MapAnalyzer.UnPathable;
            BoolGrid ramp       = Tyr.Bot.MapAnalyzer.Ramp;

            BoolGrid        rampAdjacent = unPathable.GetAdjacent(ramp);
            BoolGrid        rampSides    = unPathable.GetConnected(rampAdjacent, 5);
            List <BoolGrid> sides        = rampSides.GetGroups();

            List <Point2D> building1Positions = Placable(sides[0], Tyr.Bot.MapAnalyzer.StartArea, BuildingType.LookUp[types[0]].Size);
            List <Point2D> building2Positions = Placable(sides[1], Tyr.Bot.MapAnalyzer.StartArea, BuildingType.LookUp[types[2]].Size);

            float wallScore = 1000;

            foreach (Point2D p1 in building1Positions)
            {
                foreach (Point2D p2 in building2Positions)
                {
                    if (System.Math.Abs(p1.X - p2.X) < 0.1f + (BuildingType.LookUp[types[0]].Size.X + BuildingType.LookUp[types[2]].Size.X) / 2f &&
                        System.Math.Abs(p1.Y - p2.Y) < 0.1f + (BuildingType.LookUp[types[0]].Size.Y + BuildingType.LookUp[types[2]].Size.Y) / 2f)
                    {
                        continue;
                    }

                    float newScore = SC2Util.DistanceGrid(p1, p2);
                    if (newScore >= wallScore)
                    {
                        continue;
                    }

                    Wall[0].Pos = p1;
                    Wall[2].Pos = p2;
                    wallScore   = newScore;
                }
            }

            HashSet <Point2D> around1 = new HashSet <Point2D>();

            GetPlacableAround(Tyr.Bot.MapAnalyzer.StartArea, Wall[0].Pos, Wall[0].Size, Wall[1].Size, around1);
            HashSet <Point2D> around2 = new HashSet <Point2D>();

            GetPlacableAround(Tyr.Bot.MapAnalyzer.StartArea, Wall[2].Pos, Wall[2].Size, Wall[1].Size, around2);
            around1.IntersectWith(around2);

            foreach (Point2D pos in around1)
            {
                Wall[1].Pos = new Point2D()
                {
                    X = pos.X + 0.5f, Y = pos.Y + 0.5f
                };
                break;
            }
        }
示例#24
0
        public void Analyze(Tyr tyr)
        {
            // Determine the start location.
            foreach (Unit unit in tyr.Observation.Observation.RawData.Units)
            {
                if (unit.Owner == tyr.PlayerId && UnitTypes.ResourceCenters.Contains(unit.UnitType))
                {
                    StartLocation = unit.Pos;
                }
            }

            List <MineralField> mineralFields = new List <MineralField>();

            foreach (Unit mineralField in tyr.Observation.Observation.RawData.Units)
            {
                if (UnitTypes.MineralFields.Contains(mineralField.UnitType))
                {
                    mineralFields.Add(new MineralField()
                    {
                        Pos = mineralField.Pos, Tag = mineralField.Tag
                    });
                }
            }

            // The Units provided in our observation are not guaranteed to be in the same order every game.
            // To ensure the base finding algorithm finds the same base location every time we sort the mineral fields by position.
            mineralFields.Sort((a, b) => (int)(2 * (a.Pos.X + a.Pos.Y * 10000 - b.Pos.X - b.Pos.Y * 10000)));

            Dictionary <ulong, int>     mineralSetIds = new Dictionary <ulong, int>();
            List <List <MineralField> > mineralSets   = new List <List <MineralField> >();
            int currentSet = 0;

            foreach (MineralField mineralField in mineralFields)
            {
                if (mineralSetIds.ContainsKey(mineralField.Tag))
                {
                    continue;
                }
                BaseLocation baseLocation = new BaseLocation();
                BaseLocations.Add(baseLocation);
                mineralSetIds.Add(mineralField.Tag, currentSet);
                baseLocation.MineralFields.Add(mineralField);

                for (int i = 0; i < baseLocation.MineralFields.Count; i++)
                {
                    MineralField mineralFieldA = baseLocation.MineralFields[i];
                    foreach (MineralField closeMineralField in mineralFields)
                    {
                        if (mineralSetIds.ContainsKey(closeMineralField.Tag))
                        {
                            continue;
                        }

                        if (SC2Util.DistanceSq(mineralFieldA.Pos, closeMineralField.Pos) <= 4 * 4)
                        {
                            mineralSetIds.Add(closeMineralField.Tag, currentSet);
                            baseLocation.MineralFields.Add(closeMineralField);
                        }
                    }
                }
                currentSet++;
            }

            List <Gas> gasses = new List <Gas>();

            foreach (Unit unit in tyr.Observation.Observation.RawData.Units)
            {
                if (UnitTypes.GasGeysers.Contains(unit.UnitType))
                {
                    gasses.Add(new Gas()
                    {
                        Pos = unit.Pos, Tag = unit.Tag
                    });
                }
            }

            // The Units provided in our observation are not guaranteed to be in the same order every game.
            // To ensure the base finding algorithm finds the same base location every time we sort the gasses by position.
            gasses.Sort((a, b) => (int)(2 * (a.Pos.X + a.Pos.Y * 10000 - b.Pos.X - b.Pos.Y * 10000)));

            foreach (BaseLocation loc in BaseLocations)
            {
                DetermineFinalLocation(loc, gasses);
            }

            if (tyr.GameInfo.MapName.Contains("Blueshift"))
            {
                foreach (BaseLocation loc in BaseLocations)
                {
                    if (SC2Util.DistanceSq(loc.Pos, SC2Util.Point(141.5f, 112.5f)) <= 5 * 5 && (loc.Pos.X != 141.5 || loc.Pos.Y != 112.5))
                    {
                        DebugUtil.WriteLine("Incorrect base location, fixing: " + loc.Pos);
                        loc.Pos = SC2Util.Point(141.5f, 112.5f);
                    }
                    else if (SC2Util.DistanceSq(loc.Pos, SC2Util.Point(34.5f, 63.5f)) <= 5 * 5 && (loc.Pos.X != 34.5 || loc.Pos.Y != 63.5))
                    {
                        DebugUtil.WriteLine("Incorrect base location, fixing: " + loc.Pos);
                        loc.Pos = SC2Util.Point(34.5f, 63.5f);
                    }
                }
            }

            Stopwatch stopWatch = Stopwatch.StartNew();

            int width  = Tyr.Bot.GameInfo.StartRaw.MapSize.X;
            int height = Tyr.Bot.GameInfo.StartRaw.MapSize.Y;

            Placement = new ImageBoolGrid(tyr.GameInfo.StartRaw.PlacementGrid);
            StartArea = Placement.GetConnected(SC2Util.To2D(StartLocation));

            ArrayBoolGrid startLocations = new ArrayBoolGrid(Placement.Width(), Placement.Height());

            foreach (Point2D startLoc in Tyr.Bot.GameInfo.StartRaw.StartLocations)
            {
                for (int x = -2; x <= 2; x++)
                {
                    for (int y = -2; y <= 2; y++)
                    {
                        startLocations[(int)startLoc.X + x, (int)startLoc.Y + y] = true;
                    }
                }
            }
            for (int x = -2; x <= 2; x++)
            {
                for (int y = -2; y <= 2; y++)
                {
                    startLocations[(int)StartLocation.X + x, (int)StartLocation.Y + y] = true;
                }
            }

            BoolGrid unPathable;

            if (Tyr.Bot.OldMapData)
            {
                unPathable = new ImageBoolGrid(Tyr.Bot.GameInfo.StartRaw.PathingGrid).GetAnd(startLocations.Invert());
                Pathable   = unPathable.Invert();
            }
            else
            {
                Pathable   = new ImageBoolGrid(Tyr.Bot.GameInfo.StartRaw.PathingGrid).GetOr(startLocations);
                unPathable = Pathable.Invert();
            }

            BoolGrid chokes    = Placement.Invert().GetAnd(Pathable);
            BoolGrid mainExits = chokes.GetAdjacent(StartArea);

            enemyDistances = EnemyDistances;

            int     dist     = 1000;
            Point2D mainRamp = null;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (mainExits[x, y])
                    {
                        int newDist = enemyDistances[x, y];
                        if (newDist < dist)
                        {
                            dist     = newDist;
                            mainRamp = SC2Util.Point(x, y);
                        }
                    }
                }
            }

            Ramp = chokes.GetConnected(mainRamp);

            BoolGrid pathingWithoutRamp = Pathable.GetAnd(Ramp.Invert());

            MainAndPocketArea = pathingWithoutRamp.GetConnected(SC2Util.To2D(StartLocation));

            if (Tyr.Bot.MyRace == Race.Protoss)
            {
                DetermineWall(Ramp, unPathable);
            }

            WallDistances = Distances(unPathable);

            stopWatch.Stop();
            DebugUtil.WriteLine("Total time to find wall: " + stopWatch.ElapsedMilliseconds);
        }
示例#25
0
        public Point2D GetEnemyRamp()
        {
            if (EnemyRamp != null)
            {
                return(EnemyRamp);
            }
            if (Tyr.Bot.TargetManager.PotentialEnemyStartLocations.Count != 1)
            {
                return(null);
            }

            int width  = Tyr.Bot.GameInfo.StartRaw.MapSize.X;
            int height = Tyr.Bot.GameInfo.StartRaw.MapSize.Y;

            Point2D  start          = Tyr.Bot.TargetManager.PotentialEnemyStartLocations[0];
            BoolGrid enemyStartArea = Placement.GetConnected(start);


            BoolGrid chokes    = Placement.Invert().GetAnd(Pathable);
            BoolGrid mainExits = chokes.GetAdjacent(enemyStartArea);

            int[,] startDistances = Distances(SC2Util.To2D(StartLocation));

            int     dist     = 1000;
            Point2D mainRamp = null;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (mainExits[x, y])
                    {
                        int newDist = startDistances[x, y];
                        FileUtil.Debug("Ramp distance: " + newDist);
                        if (newDist < dist)
                        {
                            dist     = newDist;
                            mainRamp = SC2Util.Point(x, y);
                        }
                    }
                }
            }

            BoolGrid enemyRamp = chokes.GetConnected(mainRamp);

            float totalX = 0;
            float totalY = 0;
            float count  = 0;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (enemyRamp[x, y])
                    {
                        totalX += x;
                        totalY += y;
                        count++;
                    }
                }
            }

            EnemyRamp = new Point2D()
            {
                X = totalX / count, Y = totalY / count
            };
            return(EnemyRamp);
        }