예제 #1
0
        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);
        }
예제 #2
0
 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"));
         }
     }
 }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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"));
                }
            }
        }
예제 #6
0
        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);
                }
            }
        }