Skip to content

Commit

Permalink
Ensure that a rover can only traverse within the provided terrain bou…
Browse files Browse the repository at this point in the history
…ndary limits

The position is composed of the Terrain instead of the Rover. Appropriate changes are made accordingly.

Additional misc changes added include:

- Fix test description with regard to invalid Step
- Add custom rubocop rules on cops to ignore
- Fix rubocop related offenses
  • Loading branch information
boddhisattva committed Jun 24, 2024
1 parent 2dfd9b6 commit 39c7573
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 52 deletions.
8 changes: 8 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Metrics/BlockLength:
Enabled: false
Style/Documentation:
Enabled: false
Metrics/MethodLength:
Max: 25 # Default: 10
Naming/AccessorMethodName:
Enabled: false
14 changes: 7 additions & 7 deletions bin/deploy_mars_rover.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
require_relative '../lib/rectangular_plateau'
require 'pry' # Handy for debugging purposes

terrain = RectangularPlateau.new(5, 5)
terrain = RectangularPlateau.new(0, 0, 5, 5)

path1 = Path.new('LMLMLMLMM')
path2 = Path.new('MMRMMRMRRM')

rover_1 = Rover.new(RoverPosition.new(1, 2, 'N'), terrain)
rover_2 = Rover.new(RoverPosition.new(3, 3, 'E'), terrain)
rover1 = Rover.new(RoverPosition.new(1, 2, 'N', terrain))
rover2 = Rover.new(RoverPosition.new(3, 3, 'E', terrain))

rover_1.traverse(path1)
puts rover_1.current_position.location
rover1.traverse(path1)
puts rover1.current_position.location

rover_2.traverse(path2)
puts rover_2.current_position.location
rover2.traverse(path2)
puts rover2.current_position.location
32 changes: 29 additions & 3 deletions lib/rectangular_plateau.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
# frozen_string_literal: true

class RectangularPlateau
def initialize(length, breadth)
@length = length
@breadth = breadth
def initialize(lower_x_coordinate, lower_y_coordinate, upper_x_coordinate, upper_y_coordinate)
@lower_x_coordinate = lower_x_coordinate
@lower_y_coordinate = lower_y_coordinate
@upper_x_coordinate = upper_x_coordinate
@upper_y_coordinate = upper_y_coordinate
end

def upward_vertical_movement_permissible?(y_position)
y_position >= lower_y_coordinate &&
y_position < upper_y_coordinate
end

def downward_vertical_movement_permissible?(y_position)
y_position > lower_y_coordinate &&
y_position <= upper_y_coordinate
end

def forward_horizontal_movement_permissible?(x_position)
x_position >= lower_x_coordinate &&
x_position < upper_x_coordinate
end

def backward_horizontal_movement_permissible?(x_position)
x_position > lower_x_coordinate &&
x_position <= upper_x_coordinate
end

private

attr_reader :lower_x_coordinate, :lower_y_coordinate, :upper_x_coordinate, :upper_y_coordinate
end
3 changes: 1 addition & 2 deletions lib/rover.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
require_relative 'west'

class Rover
def initialize(current_position, terrain)
def initialize(current_position)
@current_position = current_position
@terrain = terrain
end

attr_reader :current_position
Expand Down
23 changes: 21 additions & 2 deletions lib/rover_position.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
# frozen_string_literal: true

class OutsideBoundaryLimitsError < StandardError; end

class RoverPosition
def initialize(x_coordinate, y_coordinate, orientation)
def initialize(x_coordinate, y_coordinate, orientation, terrain)
@x_coordinate = x_coordinate
@y_coordinate = y_coordinate
@orientation = orientation
@terrain = terrain
end

attr_reader :y_coordinate, :x_coordinate, :orientation
attr_reader :y_coordinate, :x_coordinate, :orientation, :terrain

def move_vertically_upward
unless terrain.upward_vertical_movement_permissible?(y_coordinate)
raise OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits'
end

self.y_coordinate += 1
end

def move_vertically_downward
unless terrain.downward_vertical_movement_permissible?(y_coordinate)
raise OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits'
end

self.y_coordinate -= 1
end

def move_horizontally_forward
unless terrain.forward_horizontal_movement_permissible?(x_coordinate)
raise OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits'
end

self.x_coordinate += 1
end

def move_horizontally_backward
unless terrain.backward_horizontal_movement_permissible?(x_coordinate)
raise OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits'
end

self.x_coordinate -= 1
end

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/east_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
describe '#move' do
context 'given an entity points in the East direction' do
it 'moves a step forward horizontally along that path(i.e., along the x-axis)' do
current_position = RoverPosition.new(1, 3, 'E')
current_position = RoverPosition.new(1, 3, 'E', RectangularPlateau.new(0, 0, 5, 5))

east.move(current_position)

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/north_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
describe '#move' do
context 'given an entity points in the North direction' do
it 'moves a step upward vertically along that path(i.e., along the y-axis)' do
current_position = RoverPosition.new(1, 3, 'N')
current_position = RoverPosition.new(1, 3, 'N', RectangularPlateau.new(0, 0, 5, 5))

north.move(current_position)

Expand Down
85 changes: 85 additions & 0 deletions spec/lib/rectangular_plateau_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# frozen_string_literal: true

describe RectangularPlateau do
let(:terrain) { RectangularPlateau.new(0, 0, 5, 5) }

describe '#upward_vertical_movement_permissible?' do
context 'when an entity wants to move vertically upward along the Y-axis' do
context 'movement is within terrain boundary limits' do
it 'returns true' do
current_position = RoverPosition.new(1, 3, 'N', terrain)

expect(terrain.upward_vertical_movement_permissible?(current_position.y_coordinate)).to be true
end
end

context 'movement is outside terrain boundary limits' do
it 'returns false' do
current_position = RoverPosition.new(1, 5, 'N', terrain)

expect(terrain.upward_vertical_movement_permissible?(current_position.y_coordinate)).to be false
end
end
end
end

describe '#downward_vertical_movement_permissible?' do
context 'when an entity wants to move vertically downward along the Y-axis' do
context 'movement is within terrain boundary limits' do
it 'returns true' do
current_position = RoverPosition.new(1, 3, 'S', terrain)

expect(terrain.downward_vertical_movement_permissible?(current_position.y_coordinate)).to be true
end
end

context 'movement is outside terrain boundary limits' do
it 'returns false' do
current_position = RoverPosition.new(1, 0, 'S', terrain)

expect(terrain.downward_vertical_movement_permissible?(current_position.y_coordinate)).to be false
end
end
end
end

describe '#forward_horizontal_movement_permissible?' do
context 'when an entity wants to move horizontally forward along the X-axis' do
context 'movement is within terrain boundary limits' do
it 'returns true' do
current_position = RoverPosition.new(1, 3, 'E', terrain)

expect(terrain.forward_horizontal_movement_permissible?(current_position.x_coordinate)).to be true
end
end

context 'movement is outside terrain boundary limits' do
it 'returns false' do
current_position = RoverPosition.new(5, 3, 'E', terrain)

expect(terrain.forward_horizontal_movement_permissible?(current_position.x_coordinate)).to be false
end
end
end
end

describe '#backward_horizontal_movement_permissible?' do
context 'when an entity wants to move horizontally backward along the X-axis' do
context 'movement is within terrain boundary limits' do
it 'returns true' do
current_position = RoverPosition.new(1, 3, 'W', terrain)

expect(terrain.backward_horizontal_movement_permissible?(current_position.x_coordinate)).to be true
end
end

context 'movement is outside terrain boundary limits' do
it 'returns false' do
current_position = RoverPosition.new(0, 5, 'W', terrain)

expect(terrain.backward_horizontal_movement_permissible?(current_position.x_coordinate)).to be false
end
end
end
end
end
96 changes: 73 additions & 23 deletions spec/lib/rover_position_spec.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,111 @@
# frozen_string_literal: true

describe RoverPosition do
let(:terrain) { RectangularPlateau.new(0, 0, 5, 5) }

describe '#move_vertically_upward' do
it 'allows one to go further up the Y axis(for e.g., in imagine a 2 Dimensional Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'N')
context 'movement attempted within terrain boundary limits' do
it 'allows one to go further up the Y axis(imagine a 2D Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'N', terrain)

current_position.move_vertically_upward

expect(current_position.x_coordinate).to eq 1
expect(current_position.y_coordinate).to eq 4
end
end

current_position.move_vertically_upward
context 'movement attempted outside terrain boundary limits' do
it 'returns an outside boundary limits error with related message' do
current_position = RoverPosition.new(1, 5, 'N', terrain)

expect(current_position.x_coordinate).to eq 1
expect(current_position.y_coordinate).to eq 4
expect do
current_position.move_vertically_upward
end.to raise_error(OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits')
end
end
end

describe '#move_vertically_downward' do
it 'allows one to go further down the Y axis(for e.g., in imagine a 2 Dimensional Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'S')
context 'movement attempted within terrain boundary limits' do
it 'allows one to go further down the Y axis(imagine a 2D Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'S', terrain)

current_position.move_vertically_downward

expect(current_position.x_coordinate).to eq 1
expect(current_position.y_coordinate).to eq 2
end
end

current_position.move_vertically_downward
context 'movement attempted outside terrain boundary limits' do
it 'returns an outside boundary limits error with related message' do
current_position = RoverPosition.new(1, 0, 'S', terrain)

expect(current_position.x_coordinate).to eq 1
expect(current_position.y_coordinate).to eq 2
expect do
current_position.move_vertically_downward
end.to raise_error(OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits')
end
end
end

describe '#move_horizontally_forward' do
it 'allows one to go a step further horizontally on the X axis(for e.g., in imagine a 2 Dimensional Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'E')
context 'movement attempted within terrain boundary limits' do
it 'allows one to go a step further horizontally on the X axis(imagine a 2D Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'E', terrain)

current_position.move_horizontally_forward
current_position.move_horizontally_forward

expect(current_position.x_coordinate).to eq 2
expect(current_position.y_coordinate).to eq 3
expect(current_position.x_coordinate).to eq 2
expect(current_position.y_coordinate).to eq 3
end
end

context 'movement attempted outside terrain boundary limits' do
it 'returns an outside boundary limits error with related message' do
current_position = RoverPosition.new(5, 3, 'E', terrain)

expect do
current_position.move_horizontally_forward
end.to raise_error(OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits')
end
end
end

describe '#move_horizontally_backward' do
it 'allows one to go a step backward horizontally on the X axis(for e.g., in imagine a 2 Dimensional Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'W')
context 'movement attempted within terrain boundary limits' do
it 'allows one to go a step backward horizontally on the X axis(imagine a 2D Grid system) by one unit' do
current_position = RoverPosition.new(1, 3, 'W', terrain)

current_position.move_horizontally_backward

expect(current_position.x_coordinate).to eq 0
expect(current_position.y_coordinate).to eq 3
end
end

current_position.move_horizontally_backward
context 'movement attempted outside terrain boundary limits' do
it 'returns an outside boundary limits error with related message' do
current_position = RoverPosition.new(0, 5, 'W', terrain)

expect(current_position.x_coordinate).to eq 0
expect(current_position.y_coordinate).to eq 3
expect do
current_position.move_horizontally_backward
end.to raise_error(OutsideBoundaryLimitsError, 'Movement not permissible outside terrain boundary limits')
end
end
end

describe '#get_orientation' do
it 'returns the current compass based position of a given entity' do
current_position = RoverPosition.new(1, 3, 'W')
current_position = RoverPosition.new(1, 3, 'W', terrain)

expect(current_position.get_orientation).to eq('W')
end
end

describe '#set_orientation' do
it 'sets a compass based position for a given entity' do
current_position = RoverPosition.new(1, 3, 'W')
current_position = RoverPosition.new(1, 3, 'W', terrain)

current_position.set_orientation('N')

Expand All @@ -65,7 +115,7 @@

describe '#location' do
it 'returns the current location of a given entity' do
current_position = RoverPosition.new(1, 3, 'W')
current_position = RoverPosition.new(1, 3, 'W', terrain)

expect(current_position.location).to eq('1 3 W')
end
Expand Down
Loading

0 comments on commit 39c7573

Please sign in to comment.