private static void SetBuildUnitAction(Entity entity, Vec2Int approxTarget, EntityType buildUnit, int unitCost, Dictionary <int, EntityAction> entityActions) { Vec2Int?target = null; int minDistance = int.MaxValue; var neighbors = entity.Position.Neighbors(5); foreach (var position in neighbors) { if (ScoreMap.Passable(position)) { int distance = position.Distance(approxTarget); if (distance < minDistance) { target = position; minDistance = distance; } } } if (target != null) { var buildAction = new BuildAction(buildUnit, target.Value); entityActions.Add(entity.Id, new EntityAction(null, buildAction, null, null)); ScoreMap.Build(target.Value, 1); ScoreMap.MyResource -= unitCost; } }
public override void ViewDidLoad() { base.ViewDidLoad(); for (int i = 0; i < choices.Count; i++) { score += Location.CalculateDistance(choices[i].location, answers[i].location, DistanceUnits.Miles); } Score.Text = score + " Miles off"; Answers.Source = new TableSource(answers, ScoreMap); ScoreMap.MapType = MapKit.MKMapType.Satellite;//Hybrid; ScoreMap.ZoomEnabled = true; ScoreMap.ScrollEnabled = true; ScoreMap.Delegate = new MapActions(Answers); foreach (Option curOpt in answers) { ScoreMap.AddAnnotations(new MapKit.MKPointAnnotation() { Title = curOpt.title, Coordinate = new CoreLocation.CLLocationCoordinate2D(curOpt.location.Latitude, curOpt.location.Longitude) }); //pin annotaition code, need to override function //NSObject temp2 = new NSObject(); //temp2.Equals(curOpt); //NSCoder temp = new NSCoder(); //temp.Encode(0 , curOpt.title); //GameMap.AddAnnotations(new MapKit.MKPinAnnotationView(temp); //{Title=curOpt.title, Coordinate= new CoreLocation.CLLocationCoordinate2D(curOpt.location.Latitude, curOpt.location.Longitude) }); } ScoreMap.SetRegion(new MapKit.MKCoordinateRegion(new CoreLocation.CLLocationCoordinate2D(0, 0), new MapKit.MKCoordinateSpan(180, 360)), true); }
private static void SetAttack(Entity entity, EntityType attackedEntityType, int attackedEntitySize, HashSet <Entity> enemiesUnderAttack, Dictionary <int, EntityAction> entityActions) { if (entityActions.ContainsKey(entity.Id)) { return; } Entity?bestEnemy = null; var enemies = enemiesUnderAttack.Where(e => e.EntityType == attackedEntityType).ToList(); foreach (var enemy in enemies) { if (bestEnemy == null || enemy.Health < bestEnemy.Value.Health) { bestEnemy = enemy; } if (enemy.Health == bestEnemy.Value.Health && entity.Position.Distance(enemy.Position) > entity.Position.Distance(bestEnemy.Value.Position)) { bestEnemy = enemy; } } if (bestEnemy != null) { var attackAction = new AttackAction(bestEnemy.Value.Id, null); entityActions.Add(entity.Id, new EntityAction(null, null, attackAction, null)); var newEnemyEntity = bestEnemy.Value.Health > 5 ? new Entity { Active = bestEnemy.Value.Active, EntityType = bestEnemy.Value.EntityType, Health = bestEnemy.Value.Health - 5, Id = bestEnemy.Value.Id, Position = bestEnemy.Value.Position, PlayerId = bestEnemy.Value.PlayerId } : (Entity?)null; if (attackedEntitySize > 1) { for (int y = 0; y < attackedEntitySize; y++) { for (int x = 0; x < attackedEntitySize; x++) { ScoreMap.Set(bestEnemy.Value.Position.X + x, bestEnemy.Value.Position.Y + y, newEnemyEntity); } } } else { ScoreMap.Set(bestEnemy.Value.Position, newEnemyEntity); } } }
public static void SetAttack(Entity entity, int attackRange, int size, Dictionary <int, EntityAction> entityActions) { if (entityActions.ContainsKey(entity.Id)) { return; } if (entity.EntityType == EntityType.RangedUnit && ScoreMap.Get(entity.Position).MeleeDamage > 0) { return; } List <Vec2Int> range = new List <Vec2Int>(); if (size > 1) { for (int y = entity.Position.Y; y < entity.Position.Y + size; y++) { for (int x = entity.Position.X; x < entity.Position.X + size; x++) { var position = new Vec2Int(x, y); range.AddRange(position.Range(attackRange)); } } range = range.Distinct().ToList(); } else { range = entity.Position.Range(attackRange); } var enemiesUnderAttack = new HashSet <Entity>(); foreach (var position in range) { var cell = ScoreMap.Get(position); if (cell.Entity != null && cell.Entity?.EntityType != EntityType.Resource && cell.Entity?.PlayerId != ScoreMap.MyId && !enemiesUnderAttack.Contains(cell.Entity.Value)) { enemiesUnderAttack.Add(cell.Entity.Value); } } SetAttack(entity, EntityType.RangedUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.BuilderUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.MeleeUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.Turret, 2, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.RangedBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.MeleeBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.BuilderBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.House, 3, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.Wall, 1, enemiesUnderAttack, entityActions); }
public static void SetRepair(PlayerView playerView, Entity entity, Dictionary <int, EntityAction> entityActions) { if (entityActions.ContainsKey(entity.Id)) { return; } if (ScoreMap.Get(entity.Position).AllDamage > 0) { return; } Entity?builder = null; Entity?repairEntity = null; int maxHealth = int.MinValue; var neighbors = entity.Position.Neighbors(); foreach (var target in neighbors) { var targetEntity = ScoreMap.Get(target).Entity; if (targetEntity == null) { continue; } var entityProperties = playerView.EntityProperties[targetEntity.Value.EntityType]; if (targetEntity.Value.PlayerId == ScoreMap.MyId && targetEntity.Value.Health < entityProperties.MaxHealth && (targetEntity.Value.EntityType == EntityType.BuilderBase || targetEntity.Value.EntityType == EntityType.MeleeBase || targetEntity.Value.EntityType == EntityType.RangedBase || targetEntity.Value.EntityType == EntityType.House || targetEntity.Value.EntityType == EntityType.Turret)) { if (targetEntity.Value.Health > maxHealth) { builder = entity; repairEntity = targetEntity; maxHealth = targetEntity.Value.Health; } } } if (builder != null && repairEntity != null) { var repairAction = new RepairAction(repairEntity.Value.Id); entityActions.Add(builder.Value.Id, new EntityAction(null, null, null, repairAction)); } }
private static void DrawScoreMap(DebugInterface debugInterface) { if (!Params.IsDebug) { return; } for (int x = 0; x < 80; x++) { for (int y = 0; y < 80; y++) { var scoreCell = ScoreMap.Get(x, y); if (scoreCell.ResourceScore > 0) { DrawRegion(x, y, Green, debugInterface); } if (scoreCell.RepairScore > 0) { DrawRegion(x, y, Green, debugInterface); } //if (scoreCell.MeleeAttack > 0) //{ // DrawRegion(x, y, Blue, debugInterface); //} //if (scoreCell.RangedAttack > 0) //{ // DrawRegion(x, y, Blue, debugInterface); //} if (scoreCell.MeleeDamage > 0) { DrawRegion(x, y, Red, debugInterface); } if (scoreCell.TurretDamage > 0) { DrawRegion(x, y, Red, debugInterface); } if (scoreCell.RangedDamage > 0) { DrawRegion(x, y, Blue, debugInterface); } } } }
private static void SetMoveAction(Entity entity, Vec2Int approxTarget, Dictionary <int, EntityAction> entityActions, DebugInterface debugInterface) { if (entityActions.ContainsKey(entity.Id)) { return; } var bestTarget = ASearchMove(entity, approxTarget, out var cameFrom, out var costSoFar); Vec2Int moveTarget = GetMoveTarget(entity.Position, bestTarget, cameFrom, Blue, debugInterface); ScoreMap.Set(entity.Position, null); ScoreMap.Set(moveTarget, entity); var moveAction = new MoveAction(moveTarget, false, false); entityActions.Add(entity.Id, new EntityAction(moveAction, null, null, null)); }
private double CalculateRelativeScore(double x, double y) { double angle = CalculateAngleInDegrees(x, y); ScoreMap scoreMap = new ScoreMap(); if (x > 0 && y > 0) // 1st quadrant { return(scoreMap.DetermineScoreInFirstQuadrant(angle)); } if (x < 0 && y > 0) // 2nd quandrant { return(scoreMap.DetermineScoreInSecondQuadrant(angle)); } if (x < 0 && y < 0) // 3rd quadrant { return(scoreMap.DetermineScoreInThirdQuadrant(angle)); } // therefore 4th quadrant return(scoreMap.DetermineScoreInFourthQuadrant(angle)); }
public static void SetAttack(Entity entity, Dictionary <int, EntityAction> entityActions) { if (entityActions.ContainsKey(entity.Id)) { return; } if (ScoreMap.Get(entity.Position).AllDamage > 0) { return; } Entity?resource = null; int minHealth = int.MaxValue; var neighbors = entity.Position.Neighbors(); foreach (var target in neighbors) { var targetEntity = ScoreMap.Get(target).Entity; if (targetEntity?.EntityType == EntityType.Resource) { if (targetEntity.Value.Health < minHealth) { resource = targetEntity; minHealth = targetEntity.Value.Health; } } } if (resource != null) { var attackAction = new AttackAction(resource.Value.Id, null); entityActions.Add(entity.Id, new EntityAction(null, null, attackAction, null)); } }
public static void SetBuild(EntityType buildEntityType, int size, Dictionary <int, EntityAction> entityActions, DebugInterface debugInterface) { Entity? builder = null; Vec2Int?buildPosition = null; int minDistance = int.MaxValue; foreach (Entity entity in ScoreMap.MyBuilderUnits) { if (entityActions.ContainsKey(entity.Id)) { continue; } var range = entity.Position.Range(10); if (range.Any(e => ScoreMap.Get(e).AllDamage > 0)) { continue; } if (buildEntityType == EntityType.Turret) { if (range.Count(e => ScoreMap.Get(e).Entity?.EntityType == EntityType.Resource) < 25 || range.Any(e => ScoreMap.Get(e).Entity?.EntityType == EntityType.Turret)) { continue; } } if (buildEntityType == EntityType.House) { var range2 = entity.Position.Range(5); if (range2.Count(e => ScoreMap.Get(e).Entity?.EntityType == EntityType.BuilderUnit) == 0) { continue; } } var buildPositions = entity.Position.BuildPositions(size); foreach (var position in buildPositions) { if (buildEntityType == EntityType.RangedBase && position.X <= 15 && position.Y <= 15) { continue; } var diagonals = position.Diagonals(size); if (ScoreMap.Passable(position, size) && diagonals.All(ScoreMap.PassableInFutureOrResource)) { int distance = buildEntityType == EntityType.House ? position.Distance(ScoreMap.MyHouseBase) : position.Distance(ScoreMap.EnemyBase); if (distance < minDistance) { builder = entity; buildPosition = position; minDistance = distance; } } } } if (buildEntityType == EntityType.House && builder == null && buildPosition == null) { foreach (Entity entity in ScoreMap.MyBuilderUnits) { if (entityActions.ContainsKey(entity.Id)) { continue; } var buildPositions = entity.Position.BuildPositions(size); foreach (var position in buildPositions) { var diagonals = position.Diagonals(size); if (ScoreMap.Passable(position, size) && diagonals.All(ScoreMap.PassableInFutureOrResource)) { int distance = position.Distance(ScoreMap.MyHouseBase); if (distance < minDistance) { builder = entity; buildPosition = position; minDistance = distance; } } } } } if (builder != null && buildPosition != null) { var buildAction = new BuildAction(buildEntityType, buildPosition.Value); entityActions.Add(builder.Value.Id, new EntityAction(null, buildAction, null, null)); ScoreMap.Build(buildPosition.Value, size); if (Params.IsDebug) { MyStrategy.DrawRegion(buildPosition.Value.X, buildPosition.Value.Y, MyStrategy.Lemon, debugInterface); } } }
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); }
public Action GetAction(PlayerView playerView, DebugInterface debugInterface) { if (Params.IsDebug) { debugInterface.Send(new DebugCommand.SetAutoFlush(true)); } if (playerView.CurrentTick == 10 && playerView.Players.Length == 2) { Params.RangedBaseBuildingLimit = 35; Params.MaxBuilderUnitsCount += 30; Params.MaxRangedUnitsCount += 20; Params.MaxHouseCount += 10; } var entityActions = new Dictionary <int, EntityAction>(); ScoreMap.InitMap(playerView); DrawScoreMap(debugInterface); IsDanger = DangerCheck(); // repairing Entity? builder = null; Vec2Int?moveTarget = null; int minDistance = int.MaxValue; foreach (Entity entity in playerView.Entities) { if (entity.PlayerId != ScoreMap.MyId || entity.EntityType != EntityType.BuilderUnit) { continue; } BuilderUnitActions.SetRepair(playerView, entity, entityActions); if (!ScoreMap.AnyRepairScoreMoreThanOne || entityActions.ContainsKey(entity.Id)) { continue; } var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions); var bestTarget = ASearchMove(entity, approxTarget, out var cameFrom, out var costSoFar); var cell = ScoreMap.Get(bestTarget); if (cell.RepairScore > 1 && costSoFar[bestTarget] < minDistance) { builder = entity; moveTarget = GetMoveTarget(builder.Value.Position, bestTarget, cameFrom, Blue, debugInterface); minDistance = costSoFar[bestTarget]; } } if (builder != null && moveTarget != null) { ScoreMap.Set(builder.Value.Position, null); ScoreMap.Set(moveTarget.Value, builder.Value); var moveAction = new MoveAction(moveTarget.Value, false, false); entityActions.Add(builder.Value.Id, new EntityAction(moveAction, null, null, null)); } // building turret if ((playerView.Players.Length > 2 || playerView.CurrentTick >= 300) && ScoreMap.MyActiveRangedBases.Count > 0 && (ScoreMap.Limit >= Params.TurretBuildingLimit || playerView.CurrentTick >= 300) && ScoreMap.MyResource >= ScoreMap.TurretProperties.InitialCost && ScoreMap.MyNotActiveTurrets.Count <= 1) { BuilderUnitActions.SetBuild(EntityType.Turret, ScoreMap.TurretProperties.Size, entityActions, debugInterface); ScoreMap.MyResource -= ScoreMap.TurretProperties.InitialCost; } // building ranged base if (ScoreMap.MyActiveRangedBases.Count == 0 && ScoreMap.MyResource >= ScoreMap.RangedBaseProperties.InitialCost && ScoreMap.MyNotActiveRangedBases.Count == 0) { BuilderUnitActions.SetBuild(EntityType.RangedBase, ScoreMap.RangedBaseProperties.Size, entityActions, debugInterface); ScoreMap.MyResource -= ScoreMap.RangedBaseProperties.InitialCost; } // building house if (((ScoreMap.MyActiveRangedBases.Count == 0 && ScoreMap.Limit >= Params.RangedBaseBuildingLimit && ScoreMap.MyResource >= ScoreMap.RangedBaseProperties.InitialCost + ScoreMap.HouseProperties.InitialCost) || ((ScoreMap.MyActiveRangedBases.Count > 0 || ScoreMap.MyNotActiveRangedBases.Count > 0 || ScoreMap.Limit < Params.RangedBaseBuildingLimit) && ScoreMap.MyResource >= ScoreMap.HouseProperties.InitialCost) ) && ScoreMap.Limit + 10 >= ScoreMap.AvailableLimit && ScoreMap.MyNotActiveHouses.Count <= 1 && ScoreMap.MyNotActiveHouses.Count + ScoreMap.MyActiveHouses.Count < Params.MaxHouseCount) { BuilderUnitActions.SetBuild(EntityType.House, ScoreMap.HouseProperties.Size, entityActions, debugInterface); ScoreMap.MyResource -= ScoreMap.HouseProperties.InitialCost; } foreach (Entity entity in playerView.Entities) { if (entity.PlayerId != ScoreMap.MyId) { continue; } switch (entity.EntityType) { case EntityType.BuilderUnit: { BuilderUnitActions.SetAttack(entity, entityActions); var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions); SetMoveAction(entity, approxTarget, entityActions, debugInterface); continue; } case EntityType.MeleeUnit: { CombatUnitAction.SetAttack(entity, 1, 1, entityActions); var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions); SetMoveAction(entity, approxTarget, entityActions, debugInterface); continue; } case EntityType.RangedUnit: { CombatUnitAction.SetAttack(entity, 5, 1, entityActions); var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions); SetMoveAction(entity, approxTarget, entityActions, debugInterface); continue; } case EntityType.Turret: { if (!entity.Active) { continue; } CombatUnitAction.SetAttack(entity, 5, 2, entityActions); continue; } case EntityType.BuilderBase: { int unitCost = ScoreMap.BuilderUnitProperties.InitialCost + ScoreMap.MyBuilderUnits.Count; if ((IsDanger && ScoreMap.MyResource >= unitCost * 2 || !IsDanger && ScoreMap.MyResource >= unitCost) && ScoreMap.MyBuilderUnits.Count < ScoreMap.BuilderUnitTargets.Count && ScoreMap.MyBuilderUnits.Count < Params.MaxBuilderUnitsCount) { var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions); SetBuildUnitAction(entity, approxTarget, EntityType.BuilderUnit, unitCost, entityActions); } if (!entityActions.ContainsKey(entity.Id)) { entityActions.Add(entity.Id, new EntityAction(null, null, null, null)); } continue; } case EntityType.MeleeBase: { int unitCost = ScoreMap.MeleeUnitProperties.InitialCost + ScoreMap.MyMeleeUnits.Count; if ((IsDanger && ScoreMap.MyResource >= unitCost || !IsDanger && ScoreMap.MyResource >= unitCost * 2) && ScoreMap.MyRangedUnits.Count * 2 >= Params.MaxRangedUnitsCount && ScoreMap.MyMeleeUnits.Count < Params.MaxMeleeUnitsCount) { var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions); SetBuildUnitAction(entity, approxTarget, EntityType.MeleeUnit, unitCost, entityActions); } if (!entityActions.ContainsKey(entity.Id)) { entityActions.Add(entity.Id, new EntityAction(null, null, null, null)); } continue; } case EntityType.RangedBase: { if (!entity.Active) { continue; } int unitCost = ScoreMap.RangedUnitProperties.InitialCost + ScoreMap.MyRangedUnits.Count; if ((IsDanger && ScoreMap.MyResource >= unitCost || !IsDanger && ScoreMap.MyResource >= unitCost * 3) && ScoreMap.MyRangedUnits.Count < Params.MaxRangedUnitsCount) { var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions); SetBuildUnitAction(entity, approxTarget, EntityType.RangedUnit, unitCost, entityActions); } if (!entityActions.ContainsKey(entity.Id)) { entityActions.Add(entity.Id, new EntityAction(null, null, null, null)); } continue; } } } return(new Action(entityActions)); }