Beispiel #1
0
        private Direction?FindAdjacentSmooth(AdjacentTerrain adjacent)
        {
            for (Int32 i = Direction.DirectionCount - 1; i >= 0; i--)
            {
                Direction direction = Direction.FromInt32(i);
                if (adjacent[direction] == TerrainType.Smooth)
                {
                    return(direction);
                }
            }

            return(null);
        }
Beispiel #2
0
        private Direction?FindAdjacentSampleable(AdjacentTerrain adjacent)
        {
            for (Int32 i = Direction.DirectionCount - 1; i >= 0; i--)
            {
                Direction direction = Direction.FromInt32(i);
                if (adjacent[direction].IsSampleable())
                {
                    return(direction);
                }
            }

            return(null);
        }
Beispiel #3
0
        private Direction AvoidObstacle(AdjacentTerrain adjacent)
        {
            // We use round robin here to avoid always checking the same side first,
            // as that causes the rover to favor one area.
            Direction turn = _roundRobin % 8 <= 5 ? _destination.RotateCW() : _destination.RotateCCW();

            if (adjacent[turn] != TerrainType.Impassable)
            {
                return(turn);
            }
            if (adjacent[turn.Opposite()] != TerrainType.Impassable)
            {
                return(turn.Opposite());
            }

            return(_destination.Opposite());
        }
Beispiel #4
0
        private Direction ResetDestination(AdjacentTerrain adjacent)
        {
            // We do some weird things here to avoid getting stuck in a loop too easily.
            Int32   addend    = _roundRobin % 7;
            Boolean shouldAdd = _roundRobin % 3 != 0;

            for (Int32 i = 0; i < Direction.DirectionCount; i++)
            {
                Int32     modified = _roundRobin + addend + (shouldAdd ? i : Direction.DirectionCount - i);
                Direction dir      = Direction.FromInt32(modified % Direction.DirectionCount);
                if (adjacent[dir] != TerrainType.Impassable)
                {
                    return(dir);
                }
            }

            return(Direction.None);
        }
Beispiel #5
0
        private (Boolean isDeadEnd, Direction escapeDir) CheckDeadEnd(AdjacentTerrain adjacent)
        {
            Direction direction       = Direction.None;
            Int32     impassableCount = 0;

            for (Int32 i = 0; i < Direction.DirectionCount; i++)
            {
                Direction dir = (Direction)i;
                if (adjacent[dir] == TerrainType.Impassable)
                {
                    impassableCount++;
                }
                else
                {
                    direction = dir;
                }
            }
            return(impassableCount >= 3, direction);
        }
Beispiel #6
0
        private (Direction?smoothDir, Direction?roughDir, Int32 smoothCount) FindAdjacentUnsampled(AdjacentTerrain adjacent)
        {
            Direction?adjacentSmooth = null;
            Direction?adjacentRough  = null;
            Int32     smoothCount    = 0;

            for (Int32 i = 0; i < Direction.DirectionCount; i++)
            {
                Direction roundRobin = Direction.FromInt32((i + _roundRobin) % Direction.DirectionCount);
                switch (adjacent[roundRobin])
                {
                case TerrainType.Smooth:
                    adjacentSmooth = roundRobin;
                    smoothCount++;
                    break;

                case TerrainType.Rough:
                    adjacentRough = roundRobin;
                    break;
                }
            }

            return(adjacentSmooth, adjacentRough, smoothCount);
        }
Beispiel #7
0
        private IEnumerable <RoverAction> DoLowMoves(IRoverStatusAccessor rover, AdjacentTerrain adjacent)
        {
            if (rover.MovesLeft > 5)
            {
                yield break;
            }

            Boolean smoothOccupied = adjacent[Direction.None] == TerrainType.Smooth;
            Boolean roughOccupied  = adjacent[Direction.None] == TerrainType.Rough;

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

                    yield return(RoverAction.CollectSample);
                }

                yield return(RoverAction.ProcessSamples);

                yield return(RoverAction.Transmit);

                yield break;
            }

            if (rover.MovesLeft >= 4)
            {
                if (rover.Power < Parameters.ProcessCost + Parameters.SampleCost + Parameters.ProcessCost)
                {
                    yield return(RoverAction.CollectPower);
                }
                yield return(RoverAction.CollectPower);

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