Beispiel #1
0
        public IEnumerable <RoverAction> Simulate(IRoverStatusAccessor rover)
        {
            foreach (var action in GatherPower(rover))
            {
                yield return(action);
            }

            while (true)
            {
                var         adjacent = rover.Adjacent;
                TerrainType occupied = adjacent[Direction.None];

                if (rover.MovesLeft <= 5)
                {
                    foreach (var action in DoLowMoves(rover, adjacent))
                    {
                        yield return(action);
                    }
                    yield break;
                }

                if (occupied.IsSampleable())
                {
                    yield return(RoverAction.CollectSample);

                    UpdateMap(rover);
                    if (rover.SamplesCollected >= Parameters.SamplesPerProcess && rover.Power > Parameters.ProcessCost + Parameters.MoveSmoothCost)
                    {
                        yield return(RoverAction.ProcessSamples);
                    }
                }

                Direction nextMove = Direction.None;
                if (_path != null && _path.Count > 1)
                {
                    nextMove = _path.Pop();
                }
                else if (FindAdjacentSampleable(adjacent).HasValue)
                {
                    nextMove = FindAdjacentSampleable(adjacent).Value;
                }

                if (nextMove == Direction.None || adjacent[nextMove] == TerrainType.Impassable)
                {
                    Direction?reset = ResetDestination(rover.Position);
                    if (reset == null)
                    {
                        yield break; // We're stuck.
                    }
                    nextMove = reset.Value;
                }

                yield return(new RoverAction(nextMove));

                UpdateMap(rover);
            }
        }
Beispiel #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++;
            }
        }
Beispiel #3
0
        public IEnumerable <RoverAction> Simulate(IRoverStatusAccessor rover)
        {
            while (true)
            {
                var         adjacent = GetAdjacent(rover);
                TerrainType occupied = adjacent[Direction.None];
                (Direction? adjacentSmoothDir, Direction? adjacentRoughDir, Int32 smoothCount) = FindAdjacentUnsampled(adjacent);

                if (rover.MovesLeft <= 5)
                {
                    foreach (var action in DoLowMoves(rover, adjacent))
                    {
                        yield return(action);
                    }
                    yield break;
                }

                if (rover.Power < LowPowerThreshold || (!adjacentSmoothDir.HasValue && occupied == TerrainType.Smooth))
                {
                    if (rover.Power < CalculateExcessPowerThershold(rover) / 2 && rover.NoBacktrack > 3)
                    {
                        yield return(RoverAction.CollectPower);
                    }
                    if (rover.Power < LowPowerThreshold)
                    {
                        yield return(RoverAction.Transmit);
                    }
                }
                else if (_gatheringPower && HasExcessPower(rover, rover.CollectablePower))
                {
                    yield return(RoverAction.CollectPower);

                    _gatheringPower = false;
                }

                // 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) || _gatherPowerDir != Direction.None))
                {
                    yield return(RoverAction.CollectSample);

                    if (rover.SamplesCollected >= Parameters.SamplesPerProcess && rover.Power > Parameters.ProcessCost + Parameters.MoveSmoothCost)
                    {
                        yield return(RoverAction.ProcessSamples);
                    }
                }

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

                (Boolean isDeadEnd, Direction deadEndEscape) = CheckDeadEnd(adjacent);
                if (isDeadEnd && rover.Adjacent.Occupied != TerrainType.Smooth)
                {
                    AddDeadEnd(rover.Position);
                }

                if (_gatherPowerDir != Direction.None)
                {
                    _destination = _gatherPowerDir;
                }
                else 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;
                }

                if (_gatheringPower && rover.Adjacent.Occupied == TerrainType.Smooth && smoothCount > 1)
                {
                    _gatherPowerDir = nextMove.Opposite();
                }
                else
                {
                    _gatherPowerDir = Direction.None;
                }

                yield return(new RoverAction(nextMove));

                _roundRobin++;
            }
        }