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