public AMove NuclearStrategy() { AMove result = null; if (Me.RemainingNuclearStrikeCooldownTicks == 0) { Logger.CumulativeOperationStart("NuclearStrategy"); result = _nuclearStrategy(); Logger.CumulativeOperationEnd("NuclearStrategy"); } return(result); }
private static void _selectIfNotSelected(Sandbox env, AMove move) { if (move.Action != ActionType.ClearAndSelect) { throw new Exception("Invalid arguments for _selectIfNotSelected"); } var selHash = Utility.UnitsHash(env.MyVehicles.Where(x => move.Rect.ContainsPoint(x) && (move.VehicleType == null || move.VehicleType == x.Type) && (move.Group == 0 || x.HasGroup(move.Group)))); var curHash = Utility.UnitsHash(env.MyVehicles.Where(x => x.IsSelected)); if (curHash != selHash) { MoveQueue.Add(move); } }
public static void Add(AMove move) { _queue.Add(new MoveItem { Move = move }); }
private Tuple <double, AMove> _nuclearFindMove(Sandbox env, double selTotalDamage, bool checkOnly) { AMove selMove = null; for (var s = 0; s < GroupsManager.MyGroups.Count + MyUngroupedClusters.Count; s++) { var vehicles = s < GroupsManager.MyGroups.Count ? env.GetVehicles(true, GroupsManager.MyGroups[s]) : MyUngroupedClusters[s - GroupsManager.MyGroups.Count]; var myAvg = Utility.Average(vehicles); var vrg = G.VisionRange[(int)VehicleType.Fighter] + G.MaxTacticalNuclearStrikeDamage; var oppGroups = OppClusters .Where(cl => cl.Avg.GetDistanceTo(myAvg) < vrg && cl.Any(x => env.VehicleById.ContainsKey(x.Id)))// пропускать полностью фантомные группы .OrderBy(cl => cl.Avg.GetDistanceTo(myAvg)) .Take(3) .ToArray(); foreach (var veh in vehicles) { if (!veh.IsSelected && MoveObserver.AvailableActions < 3) { continue; } if (veh.IsSelected && MoveObserver.AvailableActions < 2) { continue; } var vr = veh.ActualVisionRange * 0.9; foreach ( var oppGroup in new[] { env.GetOpponentNeighbours(veh.X, veh.Y, vr + G.TacticalNuclearStrikeRadius) }.Concat(oppGroups)) { ANuclear nuclear; var totalDamage = _nuclearGetDamage(veh, env, selTotalDamage, oppGroup, out nuclear); if (totalDamage <= selTotalDamage) { continue; } var vehNextMove = new AVehicle(veh); for (var t = 0; t < 3; t++) { vehNextMove.Move(); } if (vehNextMove.GetDistanceTo2(nuclear) + Const.Eps >= Geom.Sqr(vehNextMove.ActualVisionRange)) { continue; } const int n = 10; if (vehicles.Count > n) { var myDist2 = veh.GetDistanceTo2(nuclear); var myNearestCount = vehicles.Count(x => x.GetDistanceTo2(nuclear) <= myDist2); if (myNearestCount < n) { continue; } } selTotalDamage = totalDamage; selMove = new AMove { Action = ActionType.TacticalNuclearStrike, VehicleId = veh.Id, Point = nuclear, }; if (checkOnly) { return(new Tuple <double, AMove>(selTotalDamage, selMove)); } } } } if (selMove == null) { return(null); } return(new Tuple <double, AMove>(selTotalDamage, selMove)); }
public void Move(Player me, World world, Game game, Move move) { World = world; Me = me; Opp = world.GetOpponentPlayer(); ResultingMove = new AMove(); _myLastScore = Me.Score; _oppLastScore = Opp.Score; #if DEBUG while (Visualizer.Visualizer.Pause) { // pause here Thread.Sleep(20); } #endif Logger.TimerStart(); if (Me.NextNuclearStrikeVehicleId != -1) { Logger.TimerStart(); } _move(game); Logger.CumulativeOperationPrintAndReset(2); if (world.TickIndex % 500 == 0) { Logger.CumulativeOperationSummary(); } ResultingMove.ApplyTo(move); if (Me.NextNuclearStrikeVehicleId != -1) { Logger.TimerEndLog("AllN", 1); } Logger.TimerEndLog("All", 0); #if DEBUG Visualizer.Visualizer.CreateForm(); if (World.TickIndex == 0) { Visualizer.Visualizer.LookAt = new Point(0, 0); Visualizer.Visualizer.Zoom = 0.5; } Visualizer.Visualizer.SegmentsDrawQueue.AddRange(VisualSegments); Visualizer.Visualizer.Draw(); if (world.TickIndex >= Visualizer.Visualizer.DrawSince) { var timer = new Stopwatch(); timer.Start(); while (!Visualizer.Visualizer.Done /* || timer.ElapsedMilliseconds < 13*/) { Thread.Sleep(10); } timer.Stop(); } #endif MoveObserver.Update(); }
private void _move(Game game) { Const.Initialize(World, game); Initialize(); GroupsManager.Update(Environment); if (World.TickIndex == 0) { MoveFirstTicks(); } ActionsQueue.Process(); var ret = !MoveQueue.Free; MoveQueue.Run(); if (ret) { return; } if (Me.RemainingActionCooldownTicks > 0) { return; } if (GroupsManager.MyGroups.Count == 0) { return; } var actionsBaseInterval = MoveObserver.ActionsBaseInterval; if (MyUngroupedClusters.Any(x => x.Count >= NewGroupMinSize)) { actionsBaseInterval++; } if (World.TickIndex % actionsBaseInterval == 0 || MoveObserver.AvailableActions >= 4 && FirstMovesCompleted && World.TickIndex >= _noMoveLastTick + actionsBaseInterval || Environment.Nuclears.Any(x => x.RemainingTicks >= G.TacticalNuclearStrikeDelay - 2)) { var nuclearMove = NuclearStrategy(); if (nuclearMove != null) { ResultingMove = nuclearMove; return; } Logger.CumulativeOperationStart("Unstuck"); var unstuckMove = UnstuckStrategy(); Logger.CumulativeOperationEnd("Unstuck"); if (unstuckMove != null) { Console.WriteLine("Unstuck"); ResultingMove = unstuckMove[0]; for (var i = 1; i < unstuckMove.Length; i++) { MoveQueue.Add(unstuckMove[i]); } return; } var mainMove = MainLoopStrategy(true); _doMainsCount++; _doMainLastGroup = mainMove.Item2; foreach (var move in mainMove.Item1) { if (move.Action == ActionType.Scale && move.Factor > 1) { _doMainLastUnscale[mainMove.Item2.Group] = new Tuple <int, AMove>(World.TickIndex, move); } } foreach (var groupId in _doMainLastUnscale.Keys.ToArray()) { if (_doMainLastUnscale[groupId].Item1 + 10 + G.TacticalNuclearStrikeDelay < World.TickIndex) { _doMainLastUnscale.Remove(groupId); } } if (mainMove.Item1[0].Action == null || mainMove.Item1[0].Action == ActionType.None) { _noMoveLastTick = World.TickIndex; } ResultingMove = mainMove.Item1[0]; for (var i = 1; i < mainMove.Item1.Length; i++) { var mv = mainMove.Item1[i]; MoveQueue.Add(mv); if (mv.Action == ActionType.Assign && mainMove.Item1[0].VehicleType != null) { GroupsManager.AddPendingGroup(new MyGroup(mv.Group, mainMove.Item1[0].VehicleType.Value)); } } if (mainMove.Item1.Length >= 3) { var nearestFacility = Environment.Facilities.ArgMin( f => f.Center.GetDistanceTo2(ResultingMove.Rect.Center)); var changeProdMove = ChangeFactoryProduction(nearestFacility); if (changeProdMove != null) { MoveQueue.Add(changeProdMove); } } } if (ResultingMove == null || ResultingMove.Action == null || ResultingMove.Action == ActionType.None) { if (FirstMovesCompleted) { var facilitiesMove = FacilitiesStrategy(); if (facilitiesMove != null) { ResultingMove = facilitiesMove; } } } }