private static bool ResolveMultiShot(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets) { List <DamageMap> damageMap = BuildDamageMap(units, unitTargets); foreach (DamageMap map in damageMap) { Entity enemy = map.Enemy; int enemyHealth = enemy.Health; if (enemy.CanAttack && enemyHealth < map.Damage) { int damage = 0; foreach (Entity unit in map.Units) { results.Add(new AttackTarget(unit, enemy)); damage += unit.AttackDamage; if (damage >= enemyHealth) { return(true); } } } } return(false); }
private static bool ResolveSimple(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets) { foreach (Entity unit in units) { EntityTarget bestTarget = null; List <EntityTarget> targets = unitTargets[unit.Id]; foreach (EntityTarget target in targets) { Entity enemy = target.Entity; if (bestTarget == null || (enemy.CanAttack && enemy.Health < bestTarget.Entity.Health)) { bestTarget = target; } } if (bestTarget != null) { results.Add(new AttackTarget(unit, bestTarget.Entity)); return(true); } } return(false); }
private static bool TryGetClosestFacility(Entity builder, out Entity facility) { Point position = builder.Position; if (position.X > 0 && TryGetClosestFacility(position.Left, out facility) || position.Y > 0 && TryGetClosestFacility(position.Down, out facility) || position.X + 1 < World.Size && TryGetClosestFacility(position.Right, out facility) || position.Y + 1 < World.Size && TryGetClosestFacility(position.Up, out facility)) { return(true); } facility = null; return(false); }
private static bool TryGetClosestFacility(Point position, out Entity facility) { Entity entity = World.Get(position).Entity; if (entity == null) { facility = default; return(false); } if (entity.My && entity.Facility && entity.Health < entity.MaxHealth) { facility = entity; return(true); } facility = default; return(false); }
private static bool ResolveOneShot(List <AttackTarget> results, List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets) { List <DamageMap> damageMap = BuildDamageMap(units, unitTargets); foreach (DamageMap map in damageMap) { Entity enemy = map.Enemy; if (enemy.CanAttack && map.Units.Count == 1) // attacked only single unit { Entity unit = map.Units[0]; if (enemy.Health <= unit.AttackDamage) { results.Add(new AttackTarget(unit, enemy)); return(true); } } } return(false); }
private static void MineClosestMineral(List <Entity> builders) { foreach (Entity builder in builders.Clone()) { Point position = builder.Position; List <Entity> resources = Helper .GetNeighbors(position) .AsEntities() .Where(e => e.Mineral) .ToList(); if (resources.Count == 0) { continue; } Entity mineral = Dice.Roll(resources); builder.Action = Actions.Attack(mineral); builders.Remove(builder); } }
private static List <DamageMap> BuildDamageMap(List <Entity> units, Dictionary <int, List <EntityTarget> > unitTargets) { Dictionary <int, DamageMap> damages = new Dictionary <int, DamageMap>(); foreach (Entity unit in units) { List <EntityTarget> targets = unitTargets[unit.Id]; foreach (EntityTarget target in targets) { Entity enemy = target.Entity; if (!damages.TryGetValue(enemy.Id, out var damage)) { damage = new DamageMap(enemy); damages.Add(enemy.Id, damage); } damage.Add(unit); } } return(damages.Values.ToList()); }
private static void ProduceUnit(Entity factory) { if (!factory.Active) { return; // not ready } EntityType unitType = GetProduceEntityType(factory.Type); EntityInfo info = World.Info[unitType]; if (World.Money < info.Cost) { return; // no money } if (World.Population + World.PopulationUse == World.MaxPopulation) { return; // no living space } List <Point> spawns = Helper.GetFacilityTerritory(factory, IsFree); if (spawns.Count == 0) { return; } Point spawn = Dice.Roll(spawns); factory.Action = Actions.Build(unitType, spawn); World.Get(spawn).ReservedForEntity = factory; World.Money -= info.Cost; World.PopulationUse += info.PopulationUse; World.PopulationProvide += info.PopulationProvide; }
private static void ApplyAttack(List <AttackTarget> targets, List <Entity> units, List <Entity> enemies, Dictionary <int, List <EntityTarget> > unitTargets) { foreach (AttackTarget target in targets) { Entity enemy = target.Enemy; Entity unit = target.Unit; enemy.AcceptedDamage += unit.AttackDamage; if (enemy.AcceptedDamage >= enemy.Health) { enemies.Remove(enemy); // die on next tick foreach (List <EntityTarget> tmp in unitTargets.Values) { tmp.RemoveAll(x => x.Entity.Id == enemy.Id); } } unit.Action = Actions.Attack(enemy); units.Remove(unit); } targets.Clear(); }
public void Add(Entity unit) { Units.Add(unit); Damage += unit.AttackDamage; }
public DamageMap(Entity enemy) { Enemy = enemy; Units = new List <Entity>(); }
public AttackTarget(Entity unit, Entity enemy) { Unit = unit; Enemy = enemy; }
private static bool IsFacility(Point point) { Entity entity = World.Get(point).Entity; return(entity != null && entity.Facility); }
public static void Build(List <Entity> builders, EntityType type) { EntityInfo info = World.Info[type]; if (World.Money < info.Cost) { return; // no money } int size = info.Size; Entity bestBuilder = null; Point bestSpawn = new Point(); int minDistance = int.MaxValue; foreach (Entity builder in builders) { int x = builder.Position.X; int y = builder.Position.Y; for (int i = 0; i < size; i++) { var left = new Point(x - size, y - i); // left side if (CheckSpawn(type, left, size, ref minDistance, ref bestSpawn)) { bestBuilder = builder; } var right = new Point(x + 1, y - i); // right side if (CheckSpawn(type, right, size, ref minDistance, ref bestSpawn)) { bestBuilder = builder; } var top = new Point(x - i, y + 1); // top side if (CheckSpawn(type, top, size, ref minDistance, ref bestSpawn)) { bestBuilder = builder; } var bottom = new Point(x - i, y - size); // bottom size if (CheckSpawn(type, bottom, size, ref minDistance, ref bestSpawn)) { bestBuilder = builder; } } } if (bestBuilder == null) { return; } bestBuilder.Action = Actions.Build(type, bestSpawn); builders.Remove(bestBuilder); for (int x = bestSpawn.X; x < bestSpawn.X + size; x++) { for (int y = bestSpawn.Y; y < bestSpawn.Y + size; y++) { World.Get(x, y).ReservedForEntity = bestBuilder; } } World.Money -= info.Cost; World.PopulationProvide += info.PopulationProvide; World.PopulationUse += info.PopulationUse; }