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 }); } }
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 )); }
public static Position FindNearestStationPositon(Position currentPosition, Position stationPosition, IList <Position> blockedPositions) { return(ResolveAccessibleStationPositions(stationPosition, blockedPositions) .MinBy(position => DistanceUtils.DistanceBetweenPoints(currentPosition, position))); }