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); }
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); }
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()); }
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); }
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); }
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); }
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; }