public virtual Coordinate GetBackMoveTarget(ArmyInfo opponent) { var target = opponent.Squads.Values.Where(FilterSquad).Select(s => s.Target).Where(t => t != null) .OrderBy(t => (int)(Pow(t.center.X - Target.center.X, 2) + Pow(t.center.Y - Target.center.Y, 2)) / rangePortionOrdering) .ThenBy(OrderByTargetType) .FirstOrDefault(); Coordinate apoint; if (target != null && target.variance < 2 * initVariance) { return(FindAttackingPoint(target.center.X, target.center.Y, Target.center.X, Target.center.Y, VisionRange)); } var nearest = opponent.All.Values.Where(FilterVehicle) .OrderBy(v => (int)v.GetDistanceTo(Target.center.X, Target.center.Y) / rangePortionOrdering).ThenBy(OrderByVehicleType).FirstOrDefault(); if (nearest != null) { return(FindAttackingPoint(nearest.X, nearest.Y, Target.center.X, Target.center.Y, VisionRange)); } var tacticalTarget = opponent.All.Values.Where(FilterTactical) .OrderBy(v => (int)v.GetDistanceTo(Target.center.X, Target.center.Y) / rangePortionOrdering).ThenBy(OrderByVehicleType).FirstOrDefault(); if (tacticalTarget != null) { return(FindAttackingPoint(tacticalTarget.X, tacticalTarget.Y, Target.center.X, Target.center.Y, VisionRange)); } return(null); }
public GroupTask GetTaskByStrategy(ArmyInfo opponent, StrategyType strategy) { if (Target == null) { return(null); } Coordinate coordinate = null; if (strategy == StrategyType.Brave) { coordinate = GetBraveMoveTarget(opponent); } else if (strategy == StrategyType.Back) { coordinate = GetBackMoveTarget(opponent); } else { coordinate = GetCarefullMoveTarget(opponent); } if (coordinate == null) { return(null); } var task = CreateMoveTask(coordinate); return(task); }
public void Analyze(ArmyInfo opponent) { strategy = (lastScore - score) * lossScoreFactor <(opponent.lastScore - opponent.score) || (opponent.All.Count > All.Count * 1.5) ? StrategyType.Back : (lastScore - score)> (opponent.lastScore - opponent.score) * lossScoreFactor ? StrategyType.Brave : StrategyType.Normal; foreach (var squad in Squads) { squad.Value.Target = null; squad.Value.IsUnderNuclearAttack = opponent.strike != null && squad.Value.Vehicles .Any(v => v.Value.GetDistanceTo(opponent.strike.target.X, opponent.strike.target.Y) < 50); } lastScore = score; var opponentVehicles = opponent.All.ToArray(); var opponentVehiclesCoordinates = opponent.All.Select(v => new Coordinate(v.Value.X, v.Value.Y)).ToArray(); int optimalClusters = 5; int[] clusteredIndices; var minVariance = double.MaxValue; for (var i = Min(5, opponentVehiclesCoordinates.Length); i > 0; i--) { opponent.Squads.Clear(); clusteredIndices = Clusterization.Cluster(opponentVehiclesCoordinates, i); for (var j = 0; j < clusteredIndices.Length; j++) { ISquad squad; if (!opponent.Squads.TryGetValue(clusteredIndices[j], out squad)) { opponent.Squads.Add(clusteredIndices[j], squad = new Squad(clusteredIndices[j], opponent.All, opponent.Squads)); } squad.AddOrUpdateVehicle(opponentVehicles[j].Value); } var sumVariance = opponent.Squads.Sum(s => s.Value.Target.variance) / opponent.Squads.Count; if (minVariance > sumVariance) { minVariance = sumVariance; optimalClusters = i; } } opponent.Squads.Clear(); clusteredIndices = Clusterization.Cluster(opponentVehiclesCoordinates, optimalClusters); for (var j = 0; j < clusteredIndices.Length; j++) { ISquad squad; if (!opponent.Squads.TryGetValue(clusteredIndices[j], out squad)) { opponent.Squads.Add(clusteredIndices[j], squad = new Squad(clusteredIndices[j], opponent.All, opponent.Squads)); } squad.AddOrUpdateVehicle(opponentVehicles[j].Value); } }
public void FormArmy(World world) { Mine = new ArmyInfo { isMine = true, playerId = Me.Id }; Opponent = new ArmyInfo { playerId = world.Players.First(p => p.Id != Me.Id).Id }; Mine.Init(world); Opponent.Init(world); }
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); }
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 Coordinate GetArrvTask(ArmyInfo opponent) { var target = Squads.Values.Where(FilterSquad).Select(s => s.Target) .OrderBy(t => (int)(Pow(t.center.X - Target.center.X, 2) + Pow(t.center.Y - Target.center.Y, 2)) / rangePortionOrdering) .ThenBy(OrderByTargetType) .FirstOrDefault(); if (target != null) { return(new Coordinate(target.center.X - Target.center.X, target.center.Y - Target.center.Y)); } var tacticalTarget = opponent.All.Values.Where(FilterTactical) .OrderBy(v => (int)v.GetDistanceTo(Target.center.X, Target.center.Y) / rangePortionOrdering).ThenBy(OrderByVehicleType).FirstOrDefault(); if (tacticalTarget != null) { var apoint = FindAttackingPoint(tacticalTarget.X, tacticalTarget.Y, Target.center.X, Target.center.Y, VisionRange); return(new Coordinate(apoint.X, apoint.Y)); } return(null); }
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); }
public override Coordinate GetBackMoveTarget(ArmyInfo opponent) { return(GetArrvTask(opponent)); }