private Command GetBestNavigateCommand(Ship ship, Position drop) { // new logic, path of least resistance var polr = Navigation.CalculatePathOfLeastResistance(ship.position, drop); if (Safety.IsCompletelySafeMove(ship, polr[0].position.GetDirectionTo(ship.position))) { var best = polr[0].position.GetDirectionTo(ship.position); return(ship.Move(best, "Moving from path of least resistance2")); } // old logic, pick any safe direction List <Direction> directions = drop.GetAllDirectionsTo(ship.position); if (directions.All(x => Map.At(ship, x).IsOccupiedByOpponent || (Map.At(ship, x).IsThreatened) && !Map.At(ship, x).IsMyStructure)) { directions = DirectionExtensions.ALL_DIRECTIONS.ToList(); // add all } directions = directions.OrderBy(d => Map.At(ship, d).IsOpponentsStructure&& Map.At(ship, d).IsThreatened ? ship.halite * 3 : Map.At(ship, d).IsThreatened || Map.At(ship, d).IsOccupiedByOpponent ? ship.halite - Map.At(ship, d).SmallestEnemyValue : Map.At(ship, d).IsOccupiedByMe ? Map.At(ship, d).halite * .45 : ship.CellHalite * .1).ToList(); foreach (var d in directions) { if (Safety.IsSafeMove(ship, d)) { return(ship.Move(d, "moving to dropoff")); } } if (Safety.IsCompletelySafeMove(ship, Direction.STILL)) { return(ship.StayStill("staying still because nothing else available...")); } return(null); }
public override void CommandShips() { // see if we can disrupt an opponent foreach (var s in Fleet.AvailableShips) { var occupiedNeighbors = s.CurrentMapCell.Neighbors.Where(n => n.IsOccupiedByOpponent && !EnemyFleet.IsReturningHome(n.ship)); MapCell bestMove = null; double best = 0.0; foreach (var n in occupiedNeighbors) { var zone = new Zone(n.position, 5); if (zone.SafetyRatio < MyBot.HParams[Parameters.SAFETY_RATIO]) { continue; } if (GameInfo.MyShipsCount * 1.1 < GameInfo.OpponentShipsCount) { continue; } if (n.halite < s.CellHalite) { continue; } if (GameInfo.LowestNeighboringOpponentHalite(n) < s.halite) { continue; } if (Safety.IsSafeMove(s, n)) { var val = (n.halite * .25 + n.ship.halite) - (s.CellHalite * .25 + s.halite); if (val > best) { bestMove = n; best = val; } } } if (bestMove != null) { Fleet.AddMove(s.Move(bestMove, "trying to disrupt opponent from Combat logic")); } } }
public override void CommandShips() { var list = new List <Projection>(); Fleet.AvailableShips.ForEach(s => list.Add(new Projection(s))); list = list.OrderBy(p => p.numTurns).ToList(); while (list.Count > 0) { // switch next to a ship on a dropoff if it's surrounded var next = list[0]; foreach (var proj in list.Where(l => l.ship.OnDropoff)) { if (proj.ship.Neighbors.All(n => Fleet.CollisionCells.Contains(n) || n.IsOccupied())) { next = proj; break; } } var s = next.ship; if (next.valuer.TurnsToFill(s, ValueMapping.IsPreviousTarget(s.Id, next.valuer.Target.position)) != next.numTurns) { list[list.IndexOf(next)] = new Projection(s); list.OrderBy(p => p.numTurns); continue; } Command move; if (!s.CanMove) { move = s.StayStill("Ship cannot move, forcing it to stay still... Target " + next.valuer.Target.position.ToString() + "... Expected Turns: " + next.numTurns); } else if (!(s.CurrentMapCell.Neighbors.Any(n => n.halite > GameInfo.UpperThirdAverage && n.halite > s.CellHalite * MyBot.HParams[Parameters.STAY_MULTIPLIER])) && s.CellHalite > GameInfo.UpperThirdAverage && Safety.IsSafeMove(s, Direction.STILL)) { move = s.StayStill("Forcing ship to sit still... Target " + next.valuer.Target.position.ToString() + "... Expected Turns: " + next.numTurns); } else { move = next.GetMove(); } DoMove(move, next.valuer.Target, next.ship.Id); list.Remove(next); } }
public bool ShouldMineInsteadOfDropoff(Ship ship, List <Ship> bucket, Dictionary <Position, List <Ship> > buckets) { // verified... if (ship.CellHalite < 10) { return(false); } if (ship.CellHalite * .15 + ship.halite > 1000) { return(false); } if (ship.CurrentMapCell.IsThreatened) { return(false); } if (!Safety.IsSafeMove(ship, Direction.STILL)) { return(false); } if (!MyBot.ShouldSpawnShip(0) && MyBot.ShouldSpawnShip(ship.halite) /* and not 2 ships same dist from drop */) { return(false); } if (bucket.Count > 1 && bucket[1].DistanceToMyDropoff - 1 <= ship.DistanceToMyDropoff) { return(false); } foreach (var b in buckets.Where(x => x.Value != bucket)) { if (b.Value.First().DistanceToMyDropoff <= ship.DistanceToMyDropoff) { return(false); } } return(true); }
public override void CommandShips() { var prevShipAssignments = ShipAssignments; var prevPointAssignments = PointAssignments; ShipAssignments = new Dictionary <Ship, Assignment>(); PointAssignments = new Dictionary <Point, Assignment>(); // stay still... foreach (var s in Fleet.AvailableShips.Where(s => !s.CanMove)) { Fleet.AddMove(s.StayStill("Ship cannot move, forcing it to stay still...")); } // select targets Queue <Ship> queue = new Queue <Ship>(); Fleet.AvailableShips.ForEach(s => queue.Enqueue(s)); while (queue.Count > 0) { var s = queue.Dequeue(); var xLayers = GameInfo.RateLimitXLayers(15); var cells = GameInfo.Map.GetXLayers(s.position, xLayers); MapCell target = s.CurrentMapCell; int maxVal = GetCellValue(s, target); do { foreach (var c in cells) { var otherAssign = PointAssignments.ContainsKey(c.position.AsPoint) ? PointAssignments[c.position.AsPoint] : null; if (otherAssign != null && GameInfo.Distance(s, c.position) >= otherAssign.Distance) { continue; } // value calculation... int val = GetCellValue(s, c); if (prevPointAssignments.ContainsKey(c.position.AsPoint) && prevPointAssignments[c.position.AsPoint].Ship.Id == s.Id) { val = (int)(val * 1.1); } int distDiff = GameInfo.Distance(s, c.position) - GameInfo.Distance(s, target.position); int oppCost = distDiff < 0 ? distDiff * (int)(c.halite * .125) : // cell is closet to ship than curTarget distDiff * (int)(target.halite * .125); // distDiff is 0/positive, cell is further than curTarget if (val - oppCost > maxVal && Navigation.IsAccessible(s.position, c.position)) { maxVal = val; target = c; } } xLayers++; cells = GameInfo.GetXLayersExclusive(s.position, xLayers); } while(target == null && xLayers <= Math.Min(GameInfo.Map.width, GameInfo.RateLimitXLayers(xLayers))); if (target != null) { var otherTarget = AssignAndReturnPrevAssignIfAny(s, target); if (otherTarget != null) { queue.Enqueue(otherTarget.Ship); } } } var vals = ShipAssignments.Values.OrderBy(a => a.Distance); foreach (var a in vals) { var dirs = a.Target.position.GetAllDirectionsTo(a.Ship.position); dirs = dirs.OrderBy(d => GameInfo.CellAt(a.Ship, d).halite).ToList(); if (dirs.Any(d => Safety.IsSafeMove(a.Ship, d))) { var dir = dirs.First(d => Safety.IsSafeMove(a.Ship, d)); Fleet.AddMove(a.Ship.Move(dir, $"Moving to best target {a.Target.position.ToString()} End Game Collect Logic")); } } }
public override void CommandShips() { // go through buckets and move the ships... var dropoffBuckets = GetBuckets(AvailableShipsMovingToBase); var ShipPositions = new List <List <Ship> >(); for (int i = 0; i < GameInfo.Map.width * 2; i++) { ShipPositions.Add(new List <Ship>()); } if (dropoffBuckets.Any(kvp => kvp.Key.Equals(GameInfo.Me.shipyard.position))) { var yardDrop = dropoffBuckets.Single(kvp => kvp.Key.Equals(GameInfo.Me.shipyard.position)); foreach (var s in yardDrop.Value) { var dist = GameInfo.Distance(s, yardDrop.Key); ShipPositions[dist].Add(s); } // iterate.... bool frontOccupied = false; for (int i = 0; i < ShipPositions.Count; i++) { if (ShipPositions[i].Count >= 1) { var ships = ShipPositions[i]; ships = ships.OrderByDescending(s => s.halite).ToList(); foreach (var s in ships) { if (frontOccupied && !s.IsFull() && s.CellHalite >= 10) { Fleet.AddMove(s.StayStill("Mining halite because I can")); Safety.TwoTurnAvoider.Add(s, s.CurrentMapCell, yardDrop.Key.GetAllDirectionsTo(s.CurrentMapCell)); } else { var cmd = GetBestNavigateCommand(s, yardDrop.Key); if (cmd != null) { Fleet.AddMove(cmd); Safety.TwoTurnAvoider.Add(s, cmd.TargetCell, yardDrop.Key.GetAllDirectionsTo(cmd.TargetCell)); } } frontOccupied = true; } } frontOccupied = ShipPositions[i].Count > 0; } // remove the key dropoffBuckets.Remove(yardDrop.Key); } foreach (var drop in dropoffBuckets.Keys) { var ships = dropoffBuckets[drop].OrderBy(s => Map.CalculateDistance(s.position, drop) * 10000 - s.halite).ToList(); int maxDist = 0; foreach (var ship in ships) { int thisDist = Map.CalculateDistance(ship.position, drop); if (ShouldMineInsteadOfDropoff(ship, ships, dropoffBuckets)) { Fleet.AddMove(ship.StayStill("Mining halite because I can")); Safety.TwoTurnAvoider.Add(ship, ship.CurrentMapCell, drop.GetAllDirectionsTo(ship.CurrentMapCell)); } else if (thisDist > maxDist || ship.CellHalite < 10 || !Safety.IsSafeMove(ship, Direction.STILL)) { var cmd = GetBestNavigateCommand(ship, drop); if (cmd != null) { Fleet.AddMove(cmd); Safety.TwoTurnAvoider.Add(ship, cmd.TargetCell, drop.GetAllDirectionsTo(cmd.TargetCell)); } } else { Fleet.AddMove(ship.StayStill($"Staying still to stagger ships")); Safety.TwoTurnAvoider.Add(ship, ship.CurrentMapCell, drop.GetAllDirectionsTo(ship.CurrentMapCell)); } maxDist = Math.Max(maxDist, thisDist); } } }