예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 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);
 }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
 public override Coordinate GetBackMoveTarget(ArmyInfo opponent)
 {
     return(GetArrvTask(opponent));
 }