示例#1
0
        public static List <Vec2Int> Range(this Vec2Int p, int size, int minSize)
        {
            var radius = new List <Vec2Int>();

            for (int x = p.X - size; x <= p.X + size; x++)
            {
                for (int y = p.Y - size; y <= p.Y + size; y++)
                {
                    if (!InBounds(x, y))
                    {
                        continue;
                    }

                    int distance = p.Distance(x, y);
                    if (distance > minSize && distance <= size)
                    {
                        radius.Add(new Vec2Int(x, y));
                    }
                }
            }

            return(radius);
        }
示例#2
0
        private static Vec2Int ASearchMove(
            Entity entity,
            Vec2Int approxTarget,
            out Dictionary <Vec2Int, Vec2Int> cameFrom,
            out Dictionary <Vec2Int, int> costSoFar)
        {
            Vec2Int distantTarget   = approxTarget;
            Vec2Int?bestTarget      = null;
            int     minDistanceCost = int.MaxValue;

            var frontier = new PriorityQueue <Vec2Int>(true);

            frontier.Enqueue(0, entity.Position);

            cameFrom  = new Dictionary <Vec2Int, Vec2Int>();
            costSoFar = new Dictionary <Vec2Int, int>();

            cameFrom[entity.Position]  = entity.Position;
            costSoFar[entity.Position] = 0;

            for (int i = 0; i < Params.MaxSearchMove && frontier.Count > 0; i++)
            {
                var current     = frontier.Dequeue();
                var currentCell = ScoreMap.Get(current);

                if (entity.EntityType == EntityType.BuilderUnit &&
                    (
                        currentCell.RepairScore > 1 ||
                        currentCell.ResourceScore > 1
                    )
                    )
                {
                    bestTarget = current;
                    break;
                }

                if (bestTarget == null &&
                    entity.EntityType == EntityType.BuilderUnit &&
                    (
                        currentCell.RepairScore > 0 ||
                        currentCell.ResourceScore > 0
                    )
                    )
                {
                    bestTarget = current;
                }

                if (bestTarget != null &&
                    costSoFar[current] - costSoFar[bestTarget.Value] > 5)
                {
                    break;
                }

                if (entity.EntityType == EntityType.MeleeUnit &&
                    currentCell.MeleeAttack > 0)
                {
                    bestTarget = current;
                    break;
                }

                if (entity.EntityType == EntityType.RangedUnit &&
                    currentCell.RangedAttack > 0)
                {
                    bestTarget = current;
                    break;
                }

                var distanceCost = approxTarget.Distance(current);
                if (distanceCost < minDistanceCost)
                {
                    distantTarget   = current;
                    minDistanceCost = distanceCost;
                }

                var neighbors = current.Neighbors();
                foreach (Vec2Int next in neighbors)
                {
                    var nextCell = ScoreMap.Get(next);
                    if (nextCell.Entity != null &&
                        (entity.EntityType == EntityType.BuilderUnit ||
                         nextCell.Entity?.EntityType != EntityType.Resource))
                    {
                        // todo учесть юнитов
                        continue;
                    }

                    int nextCost = costSoFar[current] + 1;
                    if (entity.EntityType == EntityType.BuilderUnit)
                    {
                        nextCost += nextCell.AllDamage;
                    }

                    if (entity.EntityType == EntityType.RangedUnit)
                    {
                        nextCost += nextCell.AllDamage;
                    }

                    if (entity.EntityType == EntityType.MeleeUnit)
                    {
                        nextCost += nextCell.TurretDamage;
                    }

                    if (entity.EntityType != EntityType.BuilderUnit &&
                        nextCell.Entity?.EntityType == EntityType.Resource)
                    {
                        nextCost += 2;
                    }

                    if (!costSoFar.ContainsKey(next) ||
                        nextCost < costSoFar[next])
                    {
                        costSoFar[next] = nextCost;

                        frontier.Enqueue(nextCost, next);
                        cameFrom[next] = current;
                    }
                }
            }

            return(bestTarget ?? distantTarget);
        }