Created
January 20, 2017 10:14
-
-
Save adityashedge/931a1148a2fe12da5a646a279d7ad611 to your computer and use it in GitHub Desktop.
Mars rover π problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DIRECTIONS = ['N', 'E', 'S', 'W'] | |
CONTROLS = ['L', 'R', 'M'] | |
MOVES = { | |
'N' => {'L' => 'W', 'R' => 'E'}, | |
'E' => {'L' => 'N', 'R' => 'S'}, | |
'S' => {'L' => 'E', 'R' => 'W'}, | |
'W' => {'L' => 'S', 'R' => 'N'} | |
} | |
class GridError < StandardError; end | |
class RoverError < StandardError; end | |
class Grid | |
attr_reader :pos_x, :pos_y | |
def initialize(pos_x, pos_y) | |
@pos_x = pos_x | |
@pos_y = pos_y | |
end | |
def valid? | |
pos_x > 0 && pos_y > 0 | |
end | |
def valid! | |
raise GridError, "Grid is invalid" unless valid? | |
end | |
end | |
class Rover | |
attr_reader :grid, :start_position | |
attr_accessor :pos_x, :pos_y, :direction, :controls | |
def initialize(grid) | |
@grid = grid | |
end | |
def move! | |
for control in controls do | |
if control == 'M' | |
puts "Cannot move #{control} ahead." and next unless can_move? | |
move | |
else | |
turn(control) | |
end | |
end | |
end | |
def land!(pos_x, pos_y, direction) | |
unless pos_x > 0 && pos_x < grid.pos_x && pos_y > 0 && pos_y < grid.pos_y && DIRECTIONS.include?(direction) | |
raise("RoverError", "Landed out of the grid!") | |
end | |
self.start_position = [pos_x, pos_y, direction] | |
end | |
private | |
def start_position=(position) | |
@start_position = position | |
@pos_x, @pos_y, @direction = position | |
end | |
def can_move? | |
case direction | |
when 'N' | |
(pos_y + 1) < grid.pos_y | |
when 'E' | |
(pos_x + 1) < grid.pos_x | |
when 'S' | |
(pos_y - 1) >= 0 | |
when 'W' | |
(pos_x - 1) >= 0 | |
else | |
false | |
end | |
end | |
def move | |
case direction | |
when 'N' | |
@pos_y += 1 | |
when 'E' | |
@pos_x += 1 | |
when 'S' | |
@pos_y -= 1 | |
when 'W' | |
@pos_x -= 1 | |
end | |
end | |
def turn(control) | |
@direction = MOVES[direction][control] | |
end | |
end | |
begin | |
puts "Enter the co-ordinates of grid: " | |
co_ords = gets.chomp.split.map(&:to_i) | |
grid = Grid.new(*co_ords) | |
grid.valid! | |
rescue StandardError | |
puts "Grid is is invalid." | |
retry | |
end | |
while true do | |
rover = Rover.new(grid) | |
begin | |
puts "Enter the landing position of the rover" | |
postion = gets.chomp.split | |
pos_x = postion[0].to_i | |
pos_y = postion[1].to_i | |
direction = postion[2] | |
rover.land!(pos_x, pos_y, direction) | |
rescue StandardError => e | |
puts "Invalid landing position." | |
retry | |
end | |
puts "Enter the controls to move the rover (invalid controls will be rejected): " | |
rover.controls = gets.chomp.each_char.select{|ch| CONTROLS.include?(ch.upcase)}.map(&:upcase) | |
rover.move! | |
puts "Rover reached #{rover.pos_x} #{rover.pos_y} #{rover.direction}." | |
puts "Do you want to send another rover? (y to continue, press any other key to exit)" | |
break unless gets.chomp == "y" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment