public void SetLastTask(GroupTask task) { task.tick += tick; lastTask = task; ISquad squad; if (task.action != ActionType.TacticalNuclearStrike && task.action != ActionType.SetupVehicleProduction && task.group > 0 && Squads.TryGetValue(task.group, out squad)) { squad.LastTask = task; } }
private GroupTask FormTacticalDefenseTask(ArmyInfo opponent) { var squadsUnderNuclearAttack = Squads.Where(s => s.Value.IsUnderNuclearAttack).ToArray(); if (!squadsUnderNuclearAttack.Any()) { return(null); } var scaleInTask = new GroupTask { priority = 0, order = 0, duration = 30, action = ActionType.Scale, factor = 0.1, X = opponent.strike.target.X, Y = opponent.strike.target.Y }; var scaleOutTask = new GroupTask { priority = 0, order = 0, duration = 30, action = ActionType.Scale, factor = 10, next = (opp, strat) => scaleInTask, X = opponent.strike.target.X, Y = opponent.strike.target.Y }; var task = squadsUnderNuclearAttack.Length > 1 ? new GroupTask { action = ActionType.ClearAndSelect, top = squadsUnderNuclearAttack.Min(s => s.Value.Vehicles.Min(v => (int)v.Value.Y)), bottom = squadsUnderNuclearAttack.Min(s => s.Value.Vehicles.Max(v => (int)v.Value.Y)), left = squadsUnderNuclearAttack.Min(s => s.Value.Vehicles.Min(v => (int)v.Value.X)), right = squadsUnderNuclearAttack.Min(s => s.Value.Vehicles.Max(v => (int)v.Value.X)), next = (opp, strat) => scaleOutTask } : !squadsUnderNuclearAttack.First().Value.Vehicles.All(v => v.Value.IsSelected) ? new GroupTask { action = ActionType.ClearAndSelect, group = squadsUnderNuclearAttack.First().Value.Id, next = (opp, strat) => scaleOutTask } : scaleOutTask; return(task); }
public GroupTask GetTask(ArmyInfo opponent) { Analyze(opponent); GroupTask task = null; ISquad squad = null; if (lastTask != null && Squads.TryGetValue(lastTask.group, out squad) && squad.Target != null && (lastTask.tick + lastTask.duration > tick && lastTask.action != ActionType.Scale || lastTask.tick + lastTask.duration > tick && lastTask.factor > 0 && lastTask.factor < 1 && !squad.IsCollapsed)) { return(new GroupTask { action = ActionType.None }); } if (lastTask != null && lastTask.next != null && squad != null && squad.Target != null) { task = lastTask.next(opponent, strategy); } if (task != null) { return(task); } task = GetInitializationTask(); if (task != null) { return(task); } task = FormTacticalDefenseTask(opponent); if (task != null) { return(task); } task = FormTacticalAttackTask(opponent); if (task != null) { return(task); } task = Squads.Select(s => s.Value.FormTask(opponent, strategy)).Where(t => t != null) .Where(t => !NotInitializedGroups.Any() || Squads[t.group].LastTask == null) .OrderBy(t => t.priority).ThenBy(t => t.order) .ThenBy(t => Squads[t.group].LastTask != null ? Squads[t.group].LastTask.tick : int.MinValue) .ThenByDescending(t => (int)t.action).FirstOrDefault(); return(task); }
private GroupTask GetInitializationTask() { if (!NotInitializedGroups.Any()) { return(null); } var nextGroup = NotInitializedGroups.Peek(); var groupedVehicles = ByType[nextGroup.type].Select(v => v.Value) .Where(v => v.X <nextGroup.right && v.X> nextGroup.left && v.Y <nextGroup.bottom && v.Y> nextGroup.top).ToArray(); var isGroupSelected = groupedVehicles.All(v => v.IsSelected && !v.Groups.Any()); if (isGroupSelected) { var scaleTask = new GroupTask { group = nextGroup.id, action = ActionType.Scale, factor = 0.1, duration = 30, X = nextGroup.scaleLocation.X, Y = nextGroup.scaleLocation.Y }; return(new GroupTask { action = ActionType.Assign, group = nextGroup.id, next = (opp, strat) => scaleTask }); } else { return(new GroupTask { action = ActionType.ClearAndSelect, left = nextGroup.left, top = nextGroup.top, right = nextGroup.right, bottom = nextGroup.bottom, }); } }
public GroupTask FormTask(ArmyInfo opponent, StrategyType strategy) { var task = GetTaskByStrategy(opponent, strategy); GroupTask scaleTask = null; if (task != null && Target != null && Target.variance > 1.5 * initVariance) { var scaletask2 = CreateScaleTask(0.1, (opp, strat) => GetTaskByStrategy(opp, strat), task.priority, task.order, 10); var rotatetask = CreateRotateTask(-PI / 4, (opp, strat) => scaletask2, task.priority, task.order, 10); var scaletask1 = CreateScaleTask(0.1, (opp, strat) => rotatetask, task.priority, task.order, 10); scaleTask = CreateMoveTask(new Coordinate(), (opp, strat) => scaletask1, task.priority, task.order); //scaleTask = CreateScaleTask(0.1, (opp, strat) => GetTaskByStrategy(opp, strat), task.priority, task.order, (int)Min(10, Max(60, Target.variance / initVariance * 10d))); } if (task != null && Vehicles.Any(v => !v.Value.IsSelected)) { return(CreateSelectTask((opp, strat) => scaleTask ?? GetTaskByStrategy(opponent, strategy), task.priority, task.order)); } return(scaleTask ?? task); }
private GroupTask FormTacticalAttackTask(ArmyInfo opponent) { if (!canTacticalNuclearAttack) { return(null); } GroupTask task = null; if (opponent.Squads.Any()) { var target = opponent.Squads.Select(s => s.Value.Target).Where(t => t != null) .Where(t => All.Any(v => { var range = v.Value.GetDistanceTo(t.center.X, t.center.Y); return(range < 0.9 * v.Value.VisionRange && range > 0.7 * v.Value.VisionRange); })).OrderByDescending(t => (int)(t.groundDamage / 10)) .ThenBy(t => All.Where(a => a.Value.GetDistanceTo(t.center.X, t.center.Y) < 50) .Sum(a => 99d - 99d / 50 * a.Value.GetDistanceTo(t.center.X, t.center.Y)) / 10) .ThenBy(t => t.type == VehicleType.Tank ? 0 : t.type == VehicleType.Ifv ? 1 : t.type == VehicleType.Helicopter ? 2 : t.type == VehicleType.Fighter ? 3 : 4).FirstOrDefault(); if (target != null) { task = new GroupTask { action = ActionType.TacticalNuclearStrike, order = 1, priority = 0, X = target.center.X, Y = target.center.Y, vehicleId = GetVehicleForNuclearAttack(target.center.X, target.center.Y).Id, duration = 30 }; } } var nearestVehicle = opponent.All.Where(v => All.Any(s => { var range = s.Value.GetDistanceTo(v.Value.X, v.Value.Y); return(range < 0.9 * s.Value.VisionRange && range > 0.7 * s.Value.VisionRange); })).OrderByDescending(v => opponent.All.Where(a => a.Value.GetDistanceTo(v.Value) < 50).Sum(a => a.Value.GroundDamage) / 10) .ThenBy(v => All.Where(a => a.Value.GetDistanceTo(v.Value) < 50).Sum(a => 99d - 99d / 50 * a.Value.GetDistanceTo(v.Value)) / 10) .ThenBy(v => v.Value.Type == VehicleType.Tank ? 0 : v.Value.Type == VehicleType.Ifv ? 1 : v.Value.Type == VehicleType.Helicopter ? 2 : v.Value.Type == VehicleType.Fighter ? 3 : 4).FirstOrDefault(); task = nearestVehicle.Value != null ? new GroupTask { action = ActionType.TacticalNuclearStrike, order = 1, priority = 0, X = nearestVehicle.Value.X, Y = nearestVehicle.Value.Y, vehicleId = GetVehicleForNuclearAttack(nearestVehicle.Value.X, nearestVehicle.Value.Y).Id, duration = 30 } : null; if (task == null) { return(null); } var squad = Squads.First(s => s.Value.Vehicles.ContainsKey(task.vehicleId)).Value; var stopTask = new GroupTask { action = ActionType.Move, X = 0, Y = 0, group = squad.Id, next = (opp, strat) => task }; return(squad.Vehicles.Any(v => !v.Value.IsSelected) ? new GroupTask { action = ActionType.ClearAndSelect, group = squad.Id, next = (opp, strat) => stopTask } : stopTask); }
void ExecuteTask(GroupTask task, Move move) { move.Action = task.action; if (task.group > 0) { move.Group = task.group; } switch (task.action) { case ActionType.Move: move.X = task.X; move.Y = task.Y; if (task.maxSpeed > 0) { move.MaxSpeed = task.maxSpeed; } break; case ActionType.ClearAndSelect: if (task.top > 0) { move.Top = task.top; } if (task.bottom > 0) { move.Bottom = task.bottom; } if (task.left > 0) { move.Left = task.left; } if (task.right > 0) { move.Right = task.right; } break; case ActionType.Scale: move.Factor = task.factor; move.X = task.X; move.Y = task.Y; break; case ActionType.Rotate: move.Angle = task.angle; move.X = task.X; move.Y = task.Y; break; case ActionType.TacticalNuclearStrike: move.VehicleId = task.vehicleId; move.X = task.X; move.Y = task.Y; break; case ActionType.SetupVehicleProduction: move.VehicleType = task.vehicleType; move.FacilityId = task.facilityId; break; default: break; } if (task.action != ActionType.None) { Mine.SetLastTask(task); } }