예제 #1
0
        public Boolean Step(IRover rover)
        {
            if (!Actions.MoveNext())
            {
                return(true);
            }

            RoverAction action = Actions.Current;

            switch (action.Instruction)
            {
            case Instruction.CollectPower:
                rover.CollectPower();
                break;

            case Instruction.CollectSample:
                rover.CollectSample();
                break;

            case Instruction.ProcessSamples:
                rover.ProcessSamples();
                break;

            case Instruction.Transmit:
                rover.Transmit();
                break;

            case Instruction.Sense:
                rover.SenseSquare(action.Direction);
                break;

            case Instruction.Move:
                rover.Move(action.Direction);
                break;

            default:
                throw new InvalidOperationException();
            }

            return(rover.IsHalted);
        }
예제 #2
0
        public void Simulate(IRover rover)
        {
            while (true)
            {
                var         adjacent = SenseAdjacent(rover);
                TerrainType occupied = rover.SenseSquare(Direction.None);
                (Direction? adjacentSmoothDir, Direction? adjacentRoughDir) = FindAdjacentUnsampled(adjacent);

                if (rover.MovesLeft <= 5)
                {
                    DoLowMoves(rover);
                    return;
                }

                if (rover.Power < LowPowerThreshold || (!adjacentSmoothDir.HasValue && occupied == TerrainType.Smooth))
                {
                    if (!HasExcessPower(rover))
                    {
                        rover.CollectPower();
                    }
                    if (rover.Power < LowPowerThreshold)
                    {
                        rover.Transmit();
                    }
                }

                // While we're gather power, we don't collect samples and instead abuse the Backtracking mechanic gather a large amount of power.
                if (occupied.IsSampleable() && (!_gatheringPower || (adjacentSmoothDir == null && occupied == TerrainType.Smooth)))
                {
                    rover.CollectSample();
                    if (rover.SamplesCollected >= Parameters.SamplesPerProcess && rover.Power > Parameters.ProcessCost + Parameters.MoveSmoothCost)
                    {
                        rover.ProcessSamples();
                    }
                }

                Boolean hasExcessPower = HasExcessPower(rover);
                if (hasExcessPower)
                {
                    _gatheringPower = false;
                }

                (Boolean isDeadEnd, Direction deadEndEscape) = CheckDeadEnd(adjacent);
                if (isDeadEnd)
                {
                    AddDeadEnd(rover.Position);
                }

                if (adjacentSmoothDir.HasValue)
                {
                    _destination = adjacentSmoothDir.Value; // Prioritize smooth squares
                }
                else if (hasExcessPower && !_gatheringPower && adjacentRoughDir.HasValue)
                {
                    _destination = adjacentRoughDir.Value; // Visit rough squares if the rover has enough power
                }
                else if (isDeadEnd)
                {
                    _destination = deadEndEscape;
                }

                Direction nextMove = _destination;
                if (nextMove == Direction.None || adjacent[nextMove] == TerrainType.Impassable)
                {
                    if (_avoidanceDestination != Direction.None)
                    {
                        if (adjacent[_avoidanceDestination] == TerrainType.Impassable)
                        {
                            _destination          = ResetDestination(adjacent);
                            nextMove              = _destination;
                            _avoidanceDestination = Direction.None;
                        }
                        else
                        {
                            nextMove = _avoidanceDestination;
                        }
                    }
                    else
                    {
                        nextMove = AvoidObstacle(adjacent); // Obstacle avoidance
                        _avoidanceDestination = nextMove;
                    }
                }
                else
                {
                    _avoidanceDestination = Direction.None;
                }

                rover.Move(nextMove);
                _roundRobin++;
            }
        }
예제 #3
0
        private void DoLowMoves(IRover rover)
        {
            if (rover.MovesLeft > 5)
            {
                return;
            }

            Boolean smoothOccupied = rover.SenseSquare(Direction.None) == TerrainType.Smooth;
            Boolean roughOccupied  = rover.SenseSquare(Direction.None) == TerrainType.Rough;

            (Direction? smoothDir, Direction? roughDir) = FindAdjacentUnsampled(rover);
            if (rover.MovesLeft == 5 && rover.Power > Parameters.SampleCost + Parameters.MoveRoughCost + Parameters.SampleCost + Parameters.ProcessCost)
            {
                if (smoothOccupied || roughOccupied)
                {
                    rover.CollectSample();
                }
                Direction?moveDir = smoothDir ?? roughDir;
                if (moveDir.HasValue)
                {
                    rover.Move(moveDir.Value);
                    rover.CollectSample();
                }

                rover.ProcessSamples();
                rover.Transmit();
                return;
            }

            if (rover.MovesLeft >= 4)
            {
                rover.CollectPower();
                if (rover.Power > Parameters.ProcessCost)
                {
                    if (rover.Power > Parameters.ProcessCost + Parameters.SampleCost && smoothOccupied)
                    {
                        rover.CollectSample();
                    }
                    rover.ProcessSamples();
                }
            }
            else if (rover.MovesLeft == 3)
            {
                if (rover.Power > Parameters.ProcessCost + Parameters.SampleCost && smoothOccupied)
                {
                    rover.CollectSample();
                }
                else
                {
                    rover.CollectPower();
                }
                if (rover.Power > Parameters.ProcessCost)
                {
                    rover.ProcessSamples();
                }
            }
            if (rover.MovesLeft == 2)
            {
                if (rover.Power == 0)
                {
                    rover.CollectPower();
                }
                else if (rover.Power > Parameters.ProcessCost && rover.SamplesCollected > 0)
                {
                    rover.ProcessSamples();
                }
            }
            if (rover.SamplesProcessed > 0)
            {
                rover.Transmit();
            }
            return;
        }