Exemple #1
0
        private ResolvedProfit <T> FindMostProfitableItem <T>(RoundData data, IProfitResolver <T> resovler)
        {
            IList <T> items = resovler.ResolveAccessibleItems(data);

            if (items.Count == 0)
            {
                return(null);
            }

            T          bestItem   = items.First();
            ProfitData bestProfit = resovler.CalculateProfit(data, bestItem);

            for (int i = 1; i < items.Count; i++)
            {
                // TODO multiple best items
                T          item   = items[i];
                ProfitData profit = resovler.CalculateProfit(data, item);
                if (profit.CompareTo(bestProfit) > 0)
                {
                    bestItem   = item;
                    bestProfit = profit;
                }
            }

            return(new ResolvedProfit <T>(bestItem, bestProfit));
        }
 public IList <EnergyStation> ResolveAccessibleItems(RoundData data)
 {
     return(DistanceUtils.FilterByAccessibleRange(
                data.MyPosition,
                data.Map.Stations,
                new Func <EnergyStation, Position>(station => station.Position)
                ));
 }
 public IList <Robot> ResolveAccessibleItems(RoundData data)
 {
     return(DistanceUtils.FilterByAccessibleRange(
                data.MyPosition,
                data.Robots,
                new Func <Robot, Position>(robot => robot.Position)
                ).FilterForeignRobots());
 }
Exemple #4
0
        public RobotCommand DoStep(IList <Robot> robots, int robotToMoveIndex, Map map)
        {
            FileLogger.Log("\n\nMY MOVE\n\n");

            Robot myRobot = robots[robotToMoveIndex];

            if (CanClone(myRobot))
            {
                FileLogger.Log("Decided to clone");
                robotsCount++;
                return(new CreateNewRobotCommand());
            }

            RoundData data = new RoundData(map, robots, myRobot);

            ResolvedProfit <EnergyStation> bestStation = FindMostProfitableItem(data, stationProfitResolver);
            ResolvedProfit <Robot>         bestRobot   = FindMostProfitableItem(data, robotProfitResolver);

            FileLogger.Log($"Round {currentRound}, Robot #{robotToMoveIndex} - {myRobot.Format()}");
            FileLogger.Log($"Best station: {bestStation.Item.Format()} with profit {bestStation.Profit}");
            FileLogger.Log($"Best robot: {bestRobot.Item.Format()} with profit {bestRobot.Profit}");

            if (bestStation == null && bestRobot == null)
            {
                return new MoveCommand()
                       {
                           NewPosition = data.MyPosition
                       }
            }
            ;

            int accessibleEnergy = ResolveAccessibleStationEnergy(data.MyPosition, data.Map.Stations);

            if (accessibleEnergy > bestStation?.Profit?.Profit && accessibleEnergy > bestRobot?.Profit?.Profit)
            {
                FileLogger.Log("Decided to collect energy now");

                return(new CollectEnergyCommand());
            }

            if (bestStation?.Profit?.CompareTo(bestRobot.Profit) > 0)
            {
                FileLogger.Log("Decided to work with station");
                return(stationProfitResolver.ProcessStep(data, bestStation.Item, bestStation.Profit));
            }
            else
            {
                FileLogger.Log("Decided to work with robot");
                return(robotProfitResolver.ProcessStep(data, bestRobot.Item, bestRobot.Profit));
            }
        }
 public RobotCommand ProcessStep(RoundData data, EnergyStation station, ProfitData profit)
 {
     if (DistanceUtils.DistanceFromStation(data.MyPosition, station.Position) <= Constants.CollectingRadius)
     {
         FileLogger.Log("Collecting energy from stations nearby");
         return(new CollectEnergyCommand());
     }
     else
     {
         FileLogger.Log($"Moving to station {station.Format()} at position {profit.MovePosition}");
         return(new MoveCommand()
         {
             NewPosition = profit.MovePosition
         });
     }
 }
        public RobotCommand ProcessStep(RoundData data, Robot robot, ProfitData profit)
        {
            if (data.MyPosition == robot.Position)
            {
                FileLogger.Log($"Attacking robot: {robot.Format()} at position {profit.MovePosition}");
            }
            else
            {
                FileLogger.Log($"Moving to robot {robot} at position {profit.MovePosition}");
            }

            return(new MoveCommand()
            {
                NewPosition = profit.MovePosition
            });
        }
        private int CalculateBestMoveStepsCount(RoundData data, Robot robot, float distance)
        {
            float instEnergy = robot.Energy * Constants.StoleRateEnergyAtAttack - Constants.AttackEnergyLoss;

            int stepsCount = 1;
            int energyToMove;

            while (distance / stepsCount > Constants.AttackMoveDistance)
            {
                energyToMove = DistanceUtils.ResolveMoveEnergy(data.MyPosition, robot.Position, stepsCount, data.Map, data.Robots);
                if (instEnergy > energyToMove && energyToMove < data.MyEnergy - Constants.MinEnegryAfterMove)
                {
                    return(stepsCount);
                }
                stepsCount++;
            }
            return(stepsCount);
        }
        public ProfitData CalculateProfit(RoundData data, Robot robot)
        {
            float distance = DistanceUtils.DistanceBetweenPoints(robot.Position, data.MyPosition);

            int   stepsCount = CalculateBestMoveStepsCount(data, robot, distance);
            float speed      = distance / stepsCount;

            int profit = ResolveTotalRobotProfit(robot, stepsCount);

            Position movePosition;

            if (stepsCount == 1)
            {
                movePosition = robot.Position;
            }
            else
            {
                movePosition = DistanceUtils.ResolveMovePosition(
                    data.MyPosition,
                    robot.Position,
                    stepsCount,
                    data.Map,
                    data.Robots
                    );
            }

            float moveDistance = DistanceUtils.DistanceBetweenPoints(data.MyPosition, movePosition);
            float maxMoveDistanceWithDisplacement = speed + Constants.MaxMovementDisplacement;

            if (moveDistance > maxMoveDistanceWithDisplacement && movePosition != robot.Position)
            {
                movePosition = data.MyPosition;
            }

            return(new ProfitData(
                       profit - DistanceUtils.ResolveMoveEnergy(data.MyPosition, robot.Position, stepsCount, data.Map, data.Robots),
                       distance,
                       stepsCount,
                       movePosition
                       ));
        }
        public ProfitData CalculateProfit(RoundData data, EnergyStation station)
        {
            float distance = DistanceUtils.DistanceBetweenPoints(data.MyPosition, station.Position);

            KeyValuePair <float, int> bestStepDistanceToProfit = AverageStepDistances.ToDictionary(
                stepDitance => stepDitance,
                stepDistance => ResolveProfitWithAverageStepDistance(station, distance, stepDistance)
                )
                                                                 .ToList()
                                                                 .MaxBy(entry => entry.Value);

            float averageStepDistance = bestStepDistanceToProfit.Key;
            int   stepsCount          = (int)Math.Ceiling(distance / averageStepDistance);

            if (stepsCount == 0)
            {
                stepsCount = 1;
            }

            int profit = bestStepDistanceToProfit.Value;

            Position positionToCollectEnergy = PositionHelper.FindNearestStationPositon(
                data.MyPosition,
                station.Position,
                data.Robots.FilterForeignRobots()
                );
            Position movePosition;

            if (positionToCollectEnergy == null)
            {
                movePosition = data.MyPosition;
            }
            else
            {
                movePosition = DistanceUtils.ResolveMovePosition(
                    data.MyPosition,
                    positionToCollectEnergy,
                    stepsCount,
                    data.Map,
                    data.Robots
                    );
            }

            if (movePosition == null)
            {
                FileLogger.Log("Failed to find move position");
                movePosition = data.MyPosition;
            }

            float moveDistance = DistanceUtils.DistanceBetweenPoints(data.MyPosition, movePosition);
            float maxMoveDistanceWithDisplacement = distance / stepsCount + Constants.MaxMovementDisplacement;

            if (moveDistance > maxMoveDistanceWithDisplacement && movePosition != positionToCollectEnergy)
            {
                FileLogger.Log("Availabel move position is too far");
                movePosition = data.MyPosition;
            }

            return(new ProfitData(
                       profit - DistanceUtils.ResolveMoveEnergy(data.MyPosition, station.Position, stepsCount, data.Map, data.Robots),
                       distance,
                       stepsCount,
                       movePosition
                       ));
        }