Permalink
Browse files

Abstract actions into their own classes, tidy up input handler. Add s…

…pecs for each action
  • Loading branch information...
SelenaSmall committed Aug 27, 2017
1 parent 5152d59 commit ceed3ffc273abf2ae1642f7abd3e301e1062778a
@@ -0,0 +1,39 @@
class Move
attr_reader :robot, :table
def initialize(robot, table)
@robot = robot
@table = table
end
def perform
case robot.position.f
when 'NORTH'
y = robot.position.y
y += 1
position = Position.new(robot.position.x, y, robot.position.f)
robot.update_robot(position) if table.valid_position?(robot.position.x, position.y)
when 'EAST'
x = robot.position.x
x += 1
position = Position.new(x, robot.position.y, robot.position.f)
robot.update_robot(position) if table.valid_position?(position.x, robot.position.y)
when 'SOUTH'
y = robot.position.y
y -= 1
position = Position.new(robot.position.x, y, robot.position.f)
robot.update_robot(position) if table.valid_position?(robot.position.x, position.y)
when 'WEST'
x = robot.position.x
x -= 1
position = Position.new(x, robot.position.y, robot.position.f)
robot.update_robot(position) if table.valid_position?(position.x, robot.position.y)
end
end
end
@@ -0,0 +1,16 @@
class Place
attr_reader :robot, :table
def initialize(robot, table)
@robot = robot
@table = table
end
def perform(command)
_command, x, y, f = command.tr(',', ' ').split
position = Position.new(x.to_i, y.to_i, f)
robot.update_robot(position) if table.valid_position?(position.x, position.y)
end
end
@@ -0,0 +1,12 @@
class Report
attr_reader :robot
def initialize(robot)
@robot = robot
end
def perform
message = "Output: #{robot.position.x},#{robot.position.y},#{robot.position.f} \n"
$stdout.print message
end
end
@@ -0,0 +1,45 @@
class Turn
attr_reader :robot
OPTIONS = %w[WEST NORTH EAST SOUTH].freeze
def initialize(robot)
@robot = robot
end
def left
robot.position.f = prev_option(robot.position.f)
robot.update_robot(robot.position)
end
def right
robot.position.f = next_option(robot.position.f)
robot.update_robot(robot.position)
end
private
def prev_option(direction)
return unless OPTIONS.include?(direction)
return OPTIONS.last if direction == OPTIONS.first
i = OPTIONS.index { |e| e == direction }
i -= 1
OPTIONS.fetch(i)
end
def next_option(direction)
return unless OPTIONS.include?(direction)
return OPTIONS.first if direction == OPTIONS.last
i = OPTIONS.index { |e| e == direction }
i += 1
OPTIONS.fetch(i)
end
end

This file was deleted.

Oops, something went wrong.
@@ -1,98 +1,38 @@
require_relative 'direction'
require_relative 'position'
require_relative './actions/place'
require_relative './actions/move'
require_relative './actions/turn'
require_relative './actions/report'
# HandleInput class
class HandleInput
attr_accessor :robot, :table
# Command Options
PLACE = /^PLACE\s+\d+\s*,\s*\d+\s*,\s*(WEST||NORTH||EAST||SOUTH)$/
MOVE = /^MOVE$/
LEFT = /^LEFT$/
RIGHT = /^RIGHT$/
REPORT = /^REPORT$/
def initialize(robot, table)
@robot = robot
@table = table
end
# Interpret user Command
def interpret(command)
# Valid command patterns
# TODO: Add direction to place command
place = /^PLACE\s+\d+\s*,\s*\d+\s*,\s*(WEST||NORTH||EAST||SOUTH)$/
move = /^MOVE$/
left = /^LEFT$/
right = /^RIGHT$/
report = /^REPORT$/
# PLACE
if place.match?(command)
command, x, y, f = command.tr(',', ' ').split
position = @robot.place(x.to_i, y.to_i, f)
# Only update robot if the position is valid on the table
robot.update_robot(position) if @table.valid_position?(position.x, position.y)
return Place.new(robot, table).perform(command) if PLACE.match?(command)
puts "CMD: #{command} #{position.x},#{position.y},#{position.f}"
puts 'placed!' unless robot.not_in_place?
return "#{command} #{position.x},#{position.y},#{position.f}" unless robot.not_in_place?
end
# PLACE is the only valid command unless robot is in place
return if robot.not_in_place?
# LEFT
if left.match?(command)
# Turn left and update the robots direction
robot.position.f = Direction.new.turn_left(robot.position.f)
robot.update_robot(robot.position)
puts "New position #{robot.position.x},#{robot.position.y},#{robot.position.f}"
end
# RIGHT
if right.match?(command)
# Turn right and update the robots direction
robot.position.f = Direction.new.turn_right(robot.position.f)
robot.update_robot(robot.position)
puts "New position #{robot.position.x},#{robot.position.y},#{robot.position.f}"
end
# MOVE
if move.match?(command)
case robot.position.f
when 'NORTH'
y = robot.position.y
y += 1
position = Position.new(robot.position.x, y, robot.position.f)
robot.update_robot(position) if table.valid_position?(robot.position.x, position.y)
when 'EAST'
x = robot.position.x
x += 1
position = Position.new(x, robot.position.y, robot.position.f)
robot.update_robot(position) if table.valid_position?(position.x, robot.position.y)
when 'SOUTH'
y = robot.position.y
y -= 1
position = Position.new(robot.position.x, y, robot.position.f)
return Move.new(robot, table).perform if MOVE.match?(command)
robot.update_robot(position) if table.valid_position?(robot.position.x, position.y)
when 'WEST'
x = robot.position.x
x -= 1
return Turn.new(robot).left if LEFT.match?(command)
position = Position.new(x, robot.position.y, robot.position.f)
return Turn.new(robot).right if RIGHT.match?(command)
robot.update_robot(position) if table.valid_position?(position.x, robot.position.y)
end
end
return Report.new(robot).perform if REPORT.match?(command)
# puts 'reporting' if report.match?(command)
if report.match?(command)
puts "Output: #{robot.position.x},#{robot.position.y},#{robot.position.f}"
end
# TODO: Exception handler
end
end
@@ -8,11 +8,6 @@ def intialize
@position = nil
end
# Place the robot
def place(x, y, f)
Position.new(x, y, f)
end
# Update the robot's position
def update_robot(new_position)
@position = new_position

This file was deleted.

Oops, something went wrong.
@@ -18,12 +18,11 @@
end
describe '#interpret' do
it 'should return a string if command matches place pattern' do
it 'should return an instance of Position command matches place pattern' do
instance = HandleInput.new(Robot.new, Table.new)
command = 'PLACE 1,2,NORTH'
command = 'PLACE 1,2,NORTH'
expect(instance.interpret(command)).to be_a String
expect(instance.interpret(command)).to match(/^PLACE\s+\d+\s*,\s*\d+\s*,\s*(WEST||NORTH||EAST||SOUTH)$/)
expect(instance.interpret(command)).to be_a Position
end
it 'should return nil if command does not match a valid pattern' do
@@ -0,0 +1,19 @@
require 'rspec'
require 'spec_helper'
require './lib/actions/move'
describe Move do
describe '#initialize' do
it 'should have a robot attribute which is nil' do
instance = Move.new(@robot, @table)
expect(instance.robot).to be_nil
end
it 'should have a table attribute which is nil' do
instance = Move.new(@robot, @table)
expect(instance.table).to be_nil
end
end
end
@@ -0,0 +1,19 @@
require 'rspec'
require 'spec_helper'
require './lib/actions/place'
describe Place do
describe '#initialize' do
it 'should have a robot attribute which is nil' do
instance = Place.new(@robot, @table)
expect(instance.robot).to be_nil
end
it 'should have a table attribute which is nil' do
instance = Place.new(@robot, @table)
expect(instance.table).to be_nil
end
end
end
@@ -0,0 +1,13 @@
require 'rspec'
require 'spec_helper'
require './lib/actions/report'
describe Report do
describe '#initialize' do
it 'should have a robot attribute which is nil' do
instance = Report.new(@robot)
expect(instance.robot).to be_nil
end
end
end
Oops, something went wrong.

0 comments on commit ceed3ff

Please sign in to comment.