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); }
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); }