robot-simulator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +1 -0
- data/bin/robot-simulator +4 -0
- data/lib/robot/simulator.rb +7 -0
- data/lib/robot/simulator/controller.rb +34 -0
- data/lib/robot/simulator/coordinate.rb +12 -0
- data/lib/robot/simulator/direction.rb +43 -0
- data/lib/robot/simulator/robot.rb +60 -0
- data/lib/robot/simulator/table.rb +18 -0
- data/lib/robot/simulator/track.rb +12 -0
- data/lib/robot/simulator/ui/cli.rb +86 -0
- data/lib/robot/simulator/version.rb +5 -0
- data/robot-simulator.gemspec +26 -0
- data/robot-simulator.txt +72 -0
- data/spec/robot/simulator/controller_spec.rb +97 -0
- data/spec/robot/simulator/coordinate_spec.rb +15 -0
- data/spec/robot/simulator/direction_spec.rb +72 -0
- data/spec/robot/simulator/robot_spec.rb +115 -0
- data/spec/robot/simulator/table_spec.rb +32 -0
- data/spec/robot/simulator/track_spec.rb +16 -0
- data/spec/robot/simulator/ui/cli_spec.rb +131 -0
- data/spec/robot/simulator/ui/commands.txt +8 -0
- data/spec/robot/simulator_spec.rb +11 -0
- data/spec/spec_helper.rb +2 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b9cb140774f5e37640651be65f0875aeef72f8e1
|
4
|
+
data.tar.gz: f7fde3553a045be18db5292044d22fc9027e7ab9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3ffb093b24db252b7af2a8ecb8e1a4ab734220dc545f29e9c0a5e9e78513e8c62b313be398b85d8ab4938d1a4f95a8086dc2730fb0fa17b7b351580236d6a74
|
7
|
+
data.tar.gz: 187f05a2b7767b5ee1c16e7633eec89423a09be55e3bfb53009fc464ba39f761980c2d15719bebde28035ccc0aeb5bf7868852d247a376092a3212477ef1dcce
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Andrew Feng
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Robot::Simulator
|
2
|
+
|
3
|
+
A robot simulator that can receive commands and move around on a table surface. It will prevent falling from the table, and can report its position.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Install it using gem:
|
9
|
+
|
10
|
+
$ gem install robot-simulator
|
11
|
+
|
12
|
+
Or directly from git repository:
|
13
|
+
|
14
|
+
$ git clone https://mingliangfeng@bitbucket.org/mingliangfeng/robot-simulator.git
|
15
|
+
$ cd robot-simulator
|
16
|
+
$ bundle install
|
17
|
+
$ bundle exec rspec
|
18
|
+
|
19
|
+
|
20
|
+
## Environment
|
21
|
+
|
22
|
+
* Ruby version: `ruby 2.1.2p95`, best to use rbenv to set the ruby version.
|
23
|
+
|
24
|
+
|
25
|
+
## Dependencies
|
26
|
+
|
27
|
+
* [thor](https://github.com/erikhuda/thor)
|
28
|
+
* [RSpec](https://github.com/rspec/rspec) for testing
|
29
|
+
* [rbenv](https://github.com/sstephenson/rbenv) for seting the right ruby version
|
30
|
+
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
#### Use installation
|
35
|
+
Once installed, try the following, you will be asked for commands to instruct the robot to move:
|
36
|
+
|
37
|
+
$ robot-simulator
|
38
|
+
|
39
|
+
Or alternatively run robot simulator with commands from a text file:
|
40
|
+
|
41
|
+
$ robot-simulator -f /path/to/commands/text/file
|
42
|
+
|
43
|
+
#### Use source code
|
44
|
+
Get the source code from bitbucket as instructed in Installation section, go to robot-simulator folder and play straightaway:
|
45
|
+
|
46
|
+
$ bundle exec bin/robot-simulator
|
47
|
+
$ bundle exec bin/robot-simulator -f /path/to/commands/text/file
|
48
|
+
|
49
|
+
|
50
|
+
## Design
|
51
|
+
|
52
|
+
Please see the class diagram [here](https://repository.genmymodel.com/mingliangfeng/robot-simulator).
|
53
|
+
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/robot-simulator
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'robot/simulator'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
# Controller of the game, initialize the game and receive commands from UI
|
6
|
+
class Controller
|
7
|
+
attr_reader :robot
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@robot = Robot.new Table.new(5, 5)
|
11
|
+
end
|
12
|
+
|
13
|
+
def place(x, y, facing)
|
14
|
+
raise "Invalid PLACE command: PLACE #{x},#{y},#{facing}" unless robot.place Coordinate.new(x, y), Direction.from_str(facing)
|
15
|
+
end
|
16
|
+
|
17
|
+
def move
|
18
|
+
raise "Invalid MOVE command: robot is not on the table or could fall if move" unless robot.move
|
19
|
+
end
|
20
|
+
|
21
|
+
def left
|
22
|
+
raise "Invalid LEFT command: robot is not on the table" unless robot.turn_left
|
23
|
+
end
|
24
|
+
|
25
|
+
def right
|
26
|
+
raise "Invalid RIGHT command: robot is not on the table" unless robot.turn_right
|
27
|
+
end
|
28
|
+
|
29
|
+
def report
|
30
|
+
[robot.current_track.coordinate.x, robot.current_track.coordinate.y, Direction.to_str(robot.current_track.facing)] if robot.current_track
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Robot
|
2
|
+
module Simulator
|
3
|
+
module Direction
|
4
|
+
DIRECTIONS = [EAST = 0, NORTH = 1, WEST = 2, SOUTH = 3]
|
5
|
+
TO_STRS = { EAST => 'EAST', NORTH => 'NORTH', WEST => 'WEST', SOUTH => 'SOUTH' }
|
6
|
+
TO_CONSTANTS = TO_STRS.invert
|
7
|
+
|
8
|
+
# Direction on the left when facing current direction
|
9
|
+
# @return [Direction]
|
10
|
+
def self.left(direction)
|
11
|
+
validate direction
|
12
|
+
|
13
|
+
DIRECTIONS[(direction + 1) % 4]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Direction on the right when facing current direction
|
17
|
+
# @return [Direction]
|
18
|
+
def self.right(direction)
|
19
|
+
validate direction
|
20
|
+
|
21
|
+
DIRECTIONS[(direction - 1 + 4) % 4]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.to_str(direction)
|
25
|
+
validate direction
|
26
|
+
|
27
|
+
TO_STRS[direction]
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.from_str(direction_str)
|
31
|
+
key = (direction_str || "").upcase
|
32
|
+
raise(ArgumentError, "Direction string '#{direction_str}' must be one of #{TO_CONSTANTS.keys}") unless TO_CONSTANTS.keys.include? key
|
33
|
+
TO_CONSTANTS[key]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.validate(direction)
|
37
|
+
raise(ArgumentError, "Direction must be one of #{DIRECTIONS}") unless DIRECTIONS.include?(direction)
|
38
|
+
end
|
39
|
+
|
40
|
+
private_class_method :validate
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Robot
|
2
|
+
module Simulator
|
3
|
+
# Robot class corresponds to robot which can move around on the table.
|
4
|
+
class Robot
|
5
|
+
attr_reader :current_track, :table
|
6
|
+
|
7
|
+
def initialize(table)
|
8
|
+
@table = table
|
9
|
+
end
|
10
|
+
|
11
|
+
def place(coordinate, direction)
|
12
|
+
return false unless is_valid_coordinate?(coordinate)
|
13
|
+
|
14
|
+
self.current_track = Track.new coordinate, direction
|
15
|
+
end
|
16
|
+
|
17
|
+
def move
|
18
|
+
return false unless is_on_table?
|
19
|
+
|
20
|
+
newX = current_track.coordinate.x
|
21
|
+
newX += 1 if current_track.facing == Direction::EAST
|
22
|
+
newX -= 1 if current_track.facing == Direction::WEST
|
23
|
+
|
24
|
+
newY = current_track.coordinate.y
|
25
|
+
newY += 1 if current_track.facing == Direction::NORTH
|
26
|
+
newY -= 1 if current_track.facing == Direction::SOUTH
|
27
|
+
|
28
|
+
new_coordinate = Coordinate.new(newX, newY)
|
29
|
+
return false unless is_valid_coordinate? new_coordinate
|
30
|
+
|
31
|
+
self.current_track = Track.new new_coordinate, current_track.facing
|
32
|
+
end
|
33
|
+
|
34
|
+
def turn_left
|
35
|
+
return false unless is_on_table?
|
36
|
+
|
37
|
+
self.current_track = Track.new current_track.coordinate, Direction.left(current_track.facing)
|
38
|
+
end
|
39
|
+
|
40
|
+
def turn_right
|
41
|
+
return false unless is_on_table?
|
42
|
+
|
43
|
+
self.current_track = Track.new current_track.coordinate, Direction.right(current_track.facing)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def current_track=(current_track)
|
48
|
+
@current_track = current_track
|
49
|
+
end
|
50
|
+
|
51
|
+
def is_valid_coordinate?(coordinate)
|
52
|
+
table.is_valid_coordinate? coordinate
|
53
|
+
end
|
54
|
+
|
55
|
+
def is_on_table?
|
56
|
+
self.current_track != nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Robot
|
2
|
+
module Simulator
|
3
|
+
# Table with dimension, in which a robot can be placed and roam around.
|
4
|
+
class Table
|
5
|
+
attr_reader :dimensionX, :dimensionY
|
6
|
+
|
7
|
+
def initialize(dimensionX, dimensionY)
|
8
|
+
@dimensionX, @dimensionY = dimensionX, dimensionY
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_valid_coordinate?(coordinate)
|
12
|
+
coordinate and
|
13
|
+
coordinate.x >= 0 and coordinate.x < dimensionX and
|
14
|
+
coordinate.y >= 0 and coordinate.y < dimensionY
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "thor"
|
2
|
+
require 'robot/simulator'
|
3
|
+
|
4
|
+
module Robot
|
5
|
+
module Simulator
|
6
|
+
module UI
|
7
|
+
class CLI < Thor
|
8
|
+
|
9
|
+
desc "start_game", "Start the robot simulator game"
|
10
|
+
method_option :file, :aliases => "-f", :desc => "path to a text file containing robot commands"
|
11
|
+
def start_game
|
12
|
+
@controller = Controller.new
|
13
|
+
|
14
|
+
if options[:file]
|
15
|
+
commands = read_commands_from_file options[:file]
|
16
|
+
else
|
17
|
+
commands = read_commands_from_console
|
18
|
+
end
|
19
|
+
|
20
|
+
commands.each {|command| dispatch_command command }
|
21
|
+
end
|
22
|
+
|
23
|
+
default_task :start_game
|
24
|
+
|
25
|
+
private
|
26
|
+
def read_commands_from_console
|
27
|
+
say "Please input robot commands, end with a blank line ...", :green
|
28
|
+
commands = []
|
29
|
+
loop do
|
30
|
+
command = ask('>').strip
|
31
|
+
break if command.empty?
|
32
|
+
commands << command
|
33
|
+
end
|
34
|
+
commands
|
35
|
+
end
|
36
|
+
|
37
|
+
def read_commands_from_file(file_name)
|
38
|
+
say "Reading robot commands from file #{file_name} ...", :green
|
39
|
+
commands = []
|
40
|
+
File.foreach(file_name) do |line|
|
41
|
+
line = line.strip
|
42
|
+
commands << line unless line.empty?
|
43
|
+
end
|
44
|
+
commands
|
45
|
+
end
|
46
|
+
|
47
|
+
def dispatch_command(command)
|
48
|
+
action, param = command.split(/\s+/)
|
49
|
+
say "Will execute command: #{command}", :cyan
|
50
|
+
begin
|
51
|
+
case action.upcase
|
52
|
+
when 'PLACE'
|
53
|
+
execute_place_command action, param
|
54
|
+
when 'MOVE'
|
55
|
+
@controller.move
|
56
|
+
when 'LEFT'
|
57
|
+
@controller.left
|
58
|
+
when 'RIGHT'
|
59
|
+
@controller.right
|
60
|
+
when 'REPORT'
|
61
|
+
report = @controller.report
|
62
|
+
say report ? report.join(',') : 'Not on table'
|
63
|
+
else
|
64
|
+
error "Unknow command is ignored: #{command}"
|
65
|
+
end
|
66
|
+
rescue StandardError => err
|
67
|
+
error err.message
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def execute_place_command(action, param)
|
72
|
+
if param
|
73
|
+
x, y, facing = param.split(/\s*\,\s*/)
|
74
|
+
if x and y and facing
|
75
|
+
@controller.place x.to_i, y.to_i, facing
|
76
|
+
else
|
77
|
+
error "Command PLACE needs 3 parameters in format of x,y,facing, got #{param}"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
error "Command PLACE is ignored because of lack parameters"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'robot/simulator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "robot-simulator"
|
8
|
+
spec.version = Robot::Simulator::VERSION
|
9
|
+
spec.authors = ["Andrew Feng"]
|
10
|
+
spec.email = ["mingliangfeng@gmail.com"]
|
11
|
+
spec.description = %q{Robot Simulator Code Exercise}
|
12
|
+
spec.summary = %q{A robot simulator that can receive commands and move around on a table surface. It will prevent falling from the table, and can report its position.}
|
13
|
+
spec.homepage = "https://github.com/mingliangfeng"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "thor", '~> 0.19'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake", '~> 10.3'
|
25
|
+
spec.add_development_dependency 'rspec', '3.1'
|
26
|
+
end
|
data/robot-simulator.txt
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
Robot Simulator
|
2
|
+
|
3
|
+
## Description:
|
4
|
+
|
5
|
+
The application is a simulation of a toy robot moving on a square tabletop, of dimensions 5 units x 5 units.
|
6
|
+
|
7
|
+
There are no other obstructions on the table surface.
|
8
|
+
|
9
|
+
The robot is free to roam around the surface of the table, but must be prevented from falling to destruction. Any movement that would result in the robot falling from the table must be prevented, however further valid movement commands must still be allowed.
|
10
|
+
|
11
|
+
Create an application that can read in commands of the following form:
|
12
|
+
|
13
|
+
```
|
14
|
+
PLACE X,Y,F
|
15
|
+
MOVE
|
16
|
+
LEFT
|
17
|
+
RIGHT
|
18
|
+
REPORT
|
19
|
+
```
|
20
|
+
|
21
|
+
- `PLACE` will put the toy robot on the table in position X,Y and facing NORTH, SOUTH, EAST or WEST.
|
22
|
+
|
23
|
+
- The origin (0,0) can be considered to be the SOUTH WEST most corner.
|
24
|
+
|
25
|
+
- The first valid command to the robot is a `PLACE` command, after that, any sequence of commands may be issued, in any order, including another `PLACE` command. The application should discard all commands in the sequence until a valid `PLACE` command has been executed.
|
26
|
+
|
27
|
+
- `MOVE` will move the toy robot one unit forward in the direction it is currently facing.
|
28
|
+
|
29
|
+
- `LEFT` and `RIGHT` will rotate the robot 90 degrees in the specified direction without changing the position of the robot.
|
30
|
+
|
31
|
+
- `REPORT` will announce the X,Y and F of the robot. This can be in any form, but standard output is sufficient.
|
32
|
+
|
33
|
+
- A robot that is not on the table can choose the ignore the MOVE, LEFT, RIGHT and REPORT commands.
|
34
|
+
|
35
|
+
- Input can be from a file, or from standard input, as the developer chooses.
|
36
|
+
|
37
|
+
- Provide test data to exercise the application.
|
38
|
+
|
39
|
+
## Constraints:
|
40
|
+
|
41
|
+
The toy robot must not fall off the table during movement. This also includes the initial placement of the toy robot. Any move that would cause the robot to fall must be ignored.
|
42
|
+
|
43
|
+
## Example Input and Output:
|
44
|
+
|
45
|
+
```
|
46
|
+
a)
|
47
|
+
PLACE 0,0,NORTH
|
48
|
+
MOVE
|
49
|
+
REPORT
|
50
|
+
Output: 0,1,NORTH
|
51
|
+
|
52
|
+
b)
|
53
|
+
PLACE 0,0,NORTH
|
54
|
+
LEFT
|
55
|
+
REPORT
|
56
|
+
Output: 0,0,WEST
|
57
|
+
|
58
|
+
c)
|
59
|
+
PLACE 1,2,EAST
|
60
|
+
MOVE
|
61
|
+
MOVE
|
62
|
+
LEFT
|
63
|
+
MOVE
|
64
|
+
REPORT
|
65
|
+
Output: 3,3,NORTH
|
66
|
+
```
|
67
|
+
|
68
|
+
## Deliverables:
|
69
|
+
|
70
|
+
The source files, the test data and any test code.
|
71
|
+
|
72
|
+
It is not required to provide any graphical output showing the movement of the toy robot.
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Controller do
|
6
|
+
context 'Robot simulator controller' do
|
7
|
+
let!(:controller) { Controller.new }
|
8
|
+
|
9
|
+
it 'controller should init the game with a robot and a 5 x 5 dimension table' do
|
10
|
+
expect( controller.robot ).not_to be nil
|
11
|
+
expect( controller.robot.table ).not_to be nil
|
12
|
+
expect( controller.robot.table.dimensionX ).to eq(5)
|
13
|
+
expect( controller.robot.table.dimensionY ).to eq(5)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'test place' do
|
17
|
+
it 'controller should receive PLACE command and set robot at correct coordinate' do
|
18
|
+
controller.place 0, 1, 'EAST'
|
19
|
+
expect( controller.robot.current_track ).not_to be nil
|
20
|
+
expect( controller.robot.current_track.coordinate.x ).to eq(0)
|
21
|
+
expect( controller.robot.current_track.coordinate.y ).to eq(1)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'controller should raise error for invalid PLACE command' do
|
25
|
+
expect{ controller.place 6, 6, 'EAST' }.to raise_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'test move' do
|
30
|
+
it 'controller should receive MOVE command and move robot to correct coordinate' do
|
31
|
+
controller.place 0, 1, 'EAST'
|
32
|
+
controller.move
|
33
|
+
expect( controller.robot.current_track.coordinate.x ).to eq(1)
|
34
|
+
expect( controller.robot.current_track.coordinate.y ).to eq(1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'controller should raise error for MOVE command before valid PLACE command' do
|
38
|
+
expect{ controller.move }.to raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'controller should ingore MOVE command if doing so will cause robot to fall' do
|
42
|
+
controller.place 4, 4, 'EAST'
|
43
|
+
expect{ controller.move }.to raise_error
|
44
|
+
expect( controller.robot.current_track.coordinate.x ).to eq(4)
|
45
|
+
expect( controller.robot.current_track.coordinate.y ).to eq(4)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'test left' do
|
50
|
+
it 'controller should receive LEFT command and change robot facing direction' do
|
51
|
+
controller.place 0, 1, 'EAST'
|
52
|
+
controller.left
|
53
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::NORTH)
|
54
|
+
controller.left
|
55
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::WEST)
|
56
|
+
controller.left
|
57
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::SOUTH)
|
58
|
+
controller.left
|
59
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::EAST)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'controller should raise error for LEFT command before valid PLACE command' do
|
63
|
+
expect{ controller.left }.to raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'test right' do
|
68
|
+
it 'controller should receive RIGHT command and change robot facing direction' do
|
69
|
+
controller.place 0, 1, 'EAST'
|
70
|
+
controller.right
|
71
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::SOUTH)
|
72
|
+
controller.right
|
73
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::WEST)
|
74
|
+
controller.right
|
75
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::NORTH)
|
76
|
+
controller.right
|
77
|
+
expect( controller.robot.current_track.facing ).to eq(Direction::EAST)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'controller should raise error for RIGHT command before valid PLACE command' do
|
81
|
+
expect{ controller.right }.to raise_error
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'test commands sequence' do
|
86
|
+
controller.place 1, 2, 'EAST'
|
87
|
+
controller.move
|
88
|
+
controller.move
|
89
|
+
controller.left
|
90
|
+
controller.move
|
91
|
+
expect( controller.report ).to eq [3, 3, "NORTH"]
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Coordinate do
|
6
|
+
|
7
|
+
it 'constructor and getters' do
|
8
|
+
coordinate = Coordinate.new 0, 1
|
9
|
+
expect( coordinate.x ).to eq(0)
|
10
|
+
expect( coordinate.y ).to eq(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Direction do
|
6
|
+
|
7
|
+
context 'test left' do
|
8
|
+
|
9
|
+
it 'expect ArgumentError if not called by passing Direction constants value' do
|
10
|
+
expect { Direction.left(-1) }.to raise_error(ArgumentError)
|
11
|
+
expect { Direction.left(5) }.to raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'left should return correct value' do
|
15
|
+
expect( Direction.left(Direction::EAST) ).to eq(Direction::NORTH)
|
16
|
+
expect( Direction.left(Direction::NORTH) ).to eq(Direction::WEST)
|
17
|
+
expect( Direction.left(Direction::WEST) ).to eq(Direction::SOUTH)
|
18
|
+
expect( Direction.left(Direction::SOUTH) ).to eq(Direction::EAST)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'test right' do
|
24
|
+
|
25
|
+
it 'expect ArgumentError if not called by passing Direction constants value' do
|
26
|
+
expect { Direction.right(-1) }.to raise_error(ArgumentError)
|
27
|
+
expect { Direction.right(5) }.to raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'right should return correct value' do
|
31
|
+
expect( Direction.right(Direction::EAST) ).to eq(Direction::SOUTH)
|
32
|
+
expect( Direction.right(Direction::SOUTH) ).to eq(Direction::WEST)
|
33
|
+
expect( Direction.right(Direction::WEST) ).to eq(Direction::NORTH)
|
34
|
+
expect( Direction.right(Direction::NORTH) ).to eq(Direction::EAST)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'test to_str' do
|
40
|
+
|
41
|
+
it 'expect ArgumentError if not called by passing Direction constants value' do
|
42
|
+
expect { Direction.to_str(-1) }.to raise_error(ArgumentError)
|
43
|
+
expect { Direction.to_str(5) }.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'to_str should return correct string value' do
|
47
|
+
expect( Direction.to_str(Direction::EAST) ).to eq('EAST')
|
48
|
+
expect( Direction.to_str(Direction::SOUTH) ).to eq('SOUTH')
|
49
|
+
expect( Direction.to_str(Direction::WEST) ).to eq('WEST')
|
50
|
+
expect( Direction.to_str(Direction::NORTH) ).to eq('NORTH')
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'test from_str' do
|
56
|
+
|
57
|
+
it 'expect ArgumentError if not called by passing right string' do
|
58
|
+
expect { Direction.from_str('east-weast') }.to raise_error(ArgumentError)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'from_str should return correct Direction constant' do
|
62
|
+
expect( Direction.from_str('EAST') ).to eq(Direction::EAST)
|
63
|
+
expect( Direction.from_str('south') ).to eq(Direction::SOUTH)
|
64
|
+
expect( Direction.from_str('West') ).to eq(Direction::WEST)
|
65
|
+
expect( Direction.from_str('NorTH') ).to eq(Direction::NORTH)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Robot do
|
6
|
+
|
7
|
+
let(:robot) { Robot.new Table.new(5, 5) }
|
8
|
+
|
9
|
+
context 'test place method' do
|
10
|
+
it 'expect robot current track to be nil before valid PLACE command' do
|
11
|
+
expect( robot.current_track ).to be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'expect robot current track NOT to be nil after valid PLACE command' do
|
15
|
+
expect( robot.place(Coordinate.new(0, 0), Direction::EAST) ).to be_truthy
|
16
|
+
expect( robot.current_track ).not_to be_nil
|
17
|
+
expect( robot.current_track.coordinate.x ).to eq(0)
|
18
|
+
expect( robot.current_track.coordinate.y ).to eq(0)
|
19
|
+
expect( robot.current_track.facing ).to eq(Direction::EAST)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'expect robot current track to be nil after invalid PLACE command' do
|
23
|
+
expect( robot.place(Coordinate.new(6, 6), Direction::EAST) ).to be_falsey
|
24
|
+
expect( robot.current_track ).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'expect robot to stay on track and refuse subsequent invalid PLACE commands' do
|
28
|
+
robot.send :current_track=, Track.new(Coordinate.new(0, 0), Direction::EAST)
|
29
|
+
|
30
|
+
expect( robot.place(Coordinate.new(6, 6), Direction::EAST) ).to be_falsey
|
31
|
+
expect( robot.current_track ).not_to be_nil
|
32
|
+
expect( robot.current_track.coordinate.x ).to eq(0)
|
33
|
+
expect( robot.current_track.coordinate.y ).to eq(0)
|
34
|
+
expect( robot.current_track.facing ).to eq(Direction::EAST)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'test move method' do
|
39
|
+
it 'expect robot move to be failed before valid PLACE command' do
|
40
|
+
expect( robot.move() ).to be_falsey
|
41
|
+
expect( robot.current_track ).to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'expect robot move to next track after valid PLACE command' do
|
45
|
+
robot.send :current_track=, Track.new(Coordinate.new(0, 0), Direction::EAST)
|
46
|
+
expect( robot.move() ).to be_truthy
|
47
|
+
expect( robot.current_track.coordinate.x ).to eq(1)
|
48
|
+
expect( robot.current_track.coordinate.y ).to eq(0)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'expect robot to refuse to move to prevent falling from table' do
|
52
|
+
robot.send :current_track=, Track.new(Coordinate.new(4, 4), Direction::EAST)
|
53
|
+
expect( robot.move() ).to be_falsey
|
54
|
+
expect( robot.current_track.coordinate.x ).to eq(4)
|
55
|
+
expect( robot.current_track.coordinate.y ).to eq(4)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'test turn_left' do
|
60
|
+
it 'expect robot to ingore LEFT command before valid PLACE command' do
|
61
|
+
expect( robot.turn_left() ).to be_falsey
|
62
|
+
expect( robot.current_track ).to be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'expect robot to change facing direction when receive LEFT command' do
|
66
|
+
robot.send :current_track=, Track.new(Coordinate.new(0, 0), Direction::EAST)
|
67
|
+
|
68
|
+
expect( robot.turn_left() ).to be_truthy
|
69
|
+
expect( robot.current_track ).not_to be_nil
|
70
|
+
expect( robot.current_track.facing ).to eq(Direction::NORTH)
|
71
|
+
|
72
|
+
expect( robot.turn_left() ).to be_truthy
|
73
|
+
expect( robot.current_track ).not_to be_nil
|
74
|
+
expect( robot.current_track.facing ).to eq(Direction::WEST)
|
75
|
+
|
76
|
+
expect( robot.turn_left() ).to be_truthy
|
77
|
+
expect( robot.current_track ).not_to be_nil
|
78
|
+
expect( robot.current_track.facing ).to eq(Direction::SOUTH)
|
79
|
+
|
80
|
+
expect( robot.turn_left() ).to be_truthy
|
81
|
+
expect( robot.current_track ).not_to be_nil
|
82
|
+
expect( robot.current_track.facing ).to eq(Direction::EAST)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'test turn_right' do
|
87
|
+
it 'expect robot to ingore RIGHT command before valid PLACE command' do
|
88
|
+
expect( robot.turn_right() ).to be_falsey
|
89
|
+
expect( robot.current_track ).to be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'expect robot to change facing direction when receive RIGHT command' do
|
93
|
+
robot.send :current_track=, Track.new(Coordinate.new(0, 0), Direction::EAST)
|
94
|
+
|
95
|
+
expect( robot.turn_right() ).to be_truthy
|
96
|
+
expect( robot.current_track ).not_to be_nil
|
97
|
+
expect( robot.current_track.facing ).to eq(Direction::SOUTH)
|
98
|
+
|
99
|
+
expect( robot.turn_right() ).to be_truthy
|
100
|
+
expect( robot.current_track ).not_to be_nil
|
101
|
+
expect( robot.current_track.facing ).to eq(Direction::WEST)
|
102
|
+
|
103
|
+
expect( robot.turn_right() ).to be_truthy
|
104
|
+
expect( robot.current_track ).not_to be_nil
|
105
|
+
expect( robot.current_track.facing ).to eq(Direction::NORTH)
|
106
|
+
|
107
|
+
expect( robot.turn_right() ).to be_truthy
|
108
|
+
expect( robot.current_track ).not_to be_nil
|
109
|
+
expect( robot.current_track.facing ).to eq(Direction::EAST)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Table do
|
6
|
+
|
7
|
+
let(:table) { Table.new 5, 5 }
|
8
|
+
|
9
|
+
it 'constructor and getters' do
|
10
|
+
expect( table.dimensionX ).to eq(5)
|
11
|
+
expect( table.dimensionY ).to eq(5)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'test is_valid_coordinate?' do
|
15
|
+
expect( table.is_valid_coordinate?(Coordinate.new(0, 0)) ).to be true
|
16
|
+
expect( table.is_valid_coordinate?(Coordinate.new(4, 0)) ).to be true
|
17
|
+
expect( table.is_valid_coordinate?(Coordinate.new(4, 4)) ).to be true
|
18
|
+
expect( table.is_valid_coordinate?(Coordinate.new(0, 4)) ).to be true
|
19
|
+
|
20
|
+
expect( table.is_valid_coordinate?(Coordinate.new(0, -1)) ).to be false
|
21
|
+
expect( table.is_valid_coordinate?(Coordinate.new(-1, 0)) ).to be false
|
22
|
+
expect( table.is_valid_coordinate?(Coordinate.new(4, -1)) ).to be false
|
23
|
+
expect( table.is_valid_coordinate?(Coordinate.new(5, 0)) ).to be false
|
24
|
+
expect( table.is_valid_coordinate?(Coordinate.new(4, 5)) ).to be false
|
25
|
+
expect( table.is_valid_coordinate?(Coordinate.new(5, 4)) ).to be false
|
26
|
+
expect( table.is_valid_coordinate?(Coordinate.new(0, 5)) ).to be false
|
27
|
+
expect( table.is_valid_coordinate?(Coordinate.new(-1, 4)) ).to be false
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
describe Track do
|
6
|
+
|
7
|
+
it 'constructor and getters' do
|
8
|
+
track = Track.new Coordinate.new(0, 1), Direction::EAST
|
9
|
+
expect( track.coordinate.x ).to eq(0)
|
10
|
+
expect( track.coordinate.y ).to eq(1)
|
11
|
+
expect( track.facing ).to eq(Direction::EAST)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Robot
|
4
|
+
module Simulator
|
5
|
+
module UI
|
6
|
+
describe CLI do
|
7
|
+
let(:cli) { CLI.new }
|
8
|
+
|
9
|
+
it 'test commands from file' do
|
10
|
+
expect( cli ).to receive(:say).with(/Reading robot commands from file/, anything)
|
11
|
+
expect( cli ).to receive(:say).exactly 6
|
12
|
+
expect( cli ).to receive(:say).with "3,3,NORTH"
|
13
|
+
|
14
|
+
cli.options = { :file => File.expand_path('../commands.txt', __FILE__) }
|
15
|
+
cli.start_game
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'test commands from console' do
|
19
|
+
let(:console_prompt) { "Please input robot commands, end with a blank line ..." }
|
20
|
+
|
21
|
+
it "should process the commands and output the results" do
|
22
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
23
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE 1,2,East'
|
24
|
+
expect( cli ).to receive(:ask).with('>').and_return 'MOVE'
|
25
|
+
expect( cli ).to receive(:ask).with('>').and_return 'MOVE'
|
26
|
+
expect( cli ).to receive(:ask).with('>').and_return 'LEFT'
|
27
|
+
expect( cli ).to receive(:ask).with('>').and_return 'MOVE'
|
28
|
+
expect( cli ).to receive(:ask).with('>').and_return 'REPORT'
|
29
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
30
|
+
|
31
|
+
expect( cli ).to receive(:say).exactly 6
|
32
|
+
expect( cli ).to receive(:say).with "3,3,NORTH"
|
33
|
+
|
34
|
+
cli.start_game
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'should report error for invalid commands' do
|
38
|
+
it 'report unknow command error' do
|
39
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
40
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE2'
|
41
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
42
|
+
|
43
|
+
expect( cli ).to receive(:say).once
|
44
|
+
expect( cli ).to receive(:error).with "Unknow command is ignored: PLACE2"
|
45
|
+
|
46
|
+
cli.start_game
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'report error when there is exception' do
|
50
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
51
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE 1,2,EastWest'
|
52
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
53
|
+
|
54
|
+
expect( cli ).to receive(:say).once
|
55
|
+
expect( cli ).to receive(:error).with(/Direction string/)
|
56
|
+
|
57
|
+
cli.start_game
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'report error when robot would fall' do
|
61
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
62
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE 4,4,East'
|
63
|
+
expect( cli ).to receive(:ask).with('>').and_return 'MOVE'
|
64
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
65
|
+
|
66
|
+
expect( cli ).to receive(:say).twice
|
67
|
+
expect( cli ).to receive(:error).with(/Invalid MOVE command/)
|
68
|
+
|
69
|
+
cli.start_game
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'report error if robot is not on the table' do
|
73
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
74
|
+
expect( cli ).to receive(:ask).with('>').and_return 'MOVE'
|
75
|
+
expect( cli ).to receive(:ask).with('>').and_return 'LEFT'
|
76
|
+
expect( cli ).to receive(:ask).with('>').and_return 'RIGHT'
|
77
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
78
|
+
|
79
|
+
expect( cli ).to receive(:say).once
|
80
|
+
expect( cli ).to receive(:error).with(/Invalid MOVE command/)
|
81
|
+
|
82
|
+
expect( cli ).to receive(:say).once
|
83
|
+
expect( cli ).to receive(:error).with(/Invalid LEFT command/)
|
84
|
+
|
85
|
+
expect( cli ).to receive(:say).once
|
86
|
+
expect( cli ).to receive(:error).with(/Invalid RIGHT command/)
|
87
|
+
|
88
|
+
cli.start_game
|
89
|
+
end
|
90
|
+
|
91
|
+
context "should report invalid PLACE commands" do
|
92
|
+
it 'report if PLACE on invalid position' do
|
93
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
94
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE'
|
95
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
96
|
+
|
97
|
+
expect( cli ).to receive(:say).once
|
98
|
+
expect( cli ).to receive(:error).with "Command PLACE is ignored because of lack parameters"
|
99
|
+
|
100
|
+
cli.start_game
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'report no arguments error' do
|
104
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
105
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE 5,5,EAST'
|
106
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
107
|
+
|
108
|
+
expect( cli ).to receive(:say).once
|
109
|
+
expect( cli ).to receive(:error).with(/Invalid PLACE command/)
|
110
|
+
|
111
|
+
cli.start_game
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'report no enough arguments error' do
|
115
|
+
expect( cli ).to receive(:say).with console_prompt, anything
|
116
|
+
expect( cli ).to receive(:ask).with('>').and_return 'PLACE 1,2'
|
117
|
+
expect( cli ).to receive(:ask).with('>').and_return ''
|
118
|
+
|
119
|
+
expect( cli ).to receive(:say).once
|
120
|
+
expect( cli ).to receive(:error).with "Command PLACE needs 3 parameters in format of x,y,facing, got 1,2"
|
121
|
+
|
122
|
+
cli.start_game
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: robot-simulator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Feng
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.19'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.19'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.1'
|
69
|
+
description: Robot Simulator Code Exercise
|
70
|
+
email:
|
71
|
+
- mingliangfeng@gmail.com
|
72
|
+
executables:
|
73
|
+
- robot-simulator
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".ruby-version"
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/robot-simulator
|
84
|
+
- lib/robot/simulator.rb
|
85
|
+
- lib/robot/simulator/controller.rb
|
86
|
+
- lib/robot/simulator/coordinate.rb
|
87
|
+
- lib/robot/simulator/direction.rb
|
88
|
+
- lib/robot/simulator/robot.rb
|
89
|
+
- lib/robot/simulator/table.rb
|
90
|
+
- lib/robot/simulator/track.rb
|
91
|
+
- lib/robot/simulator/ui/cli.rb
|
92
|
+
- lib/robot/simulator/version.rb
|
93
|
+
- robot-simulator.gemspec
|
94
|
+
- robot-simulator.txt
|
95
|
+
- spec/robot/simulator/controller_spec.rb
|
96
|
+
- spec/robot/simulator/coordinate_spec.rb
|
97
|
+
- spec/robot/simulator/direction_spec.rb
|
98
|
+
- spec/robot/simulator/robot_spec.rb
|
99
|
+
- spec/robot/simulator/table_spec.rb
|
100
|
+
- spec/robot/simulator/track_spec.rb
|
101
|
+
- spec/robot/simulator/ui/cli_spec.rb
|
102
|
+
- spec/robot/simulator/ui/commands.txt
|
103
|
+
- spec/robot/simulator_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
homepage: https://github.com/mingliangfeng
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.4.2
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: A robot simulator that can receive commands and move around on a table surface.
|
129
|
+
It will prevent falling from the table, and can report its position.
|
130
|
+
test_files:
|
131
|
+
- spec/robot/simulator/controller_spec.rb
|
132
|
+
- spec/robot/simulator/coordinate_spec.rb
|
133
|
+
- spec/robot/simulator/direction_spec.rb
|
134
|
+
- spec/robot/simulator/robot_spec.rb
|
135
|
+
- spec/robot/simulator/table_spec.rb
|
136
|
+
- spec/robot/simulator/track_spec.rb
|
137
|
+
- spec/robot/simulator/ui/cli_spec.rb
|
138
|
+
- spec/robot/simulator/ui/commands.txt
|
139
|
+
- spec/robot/simulator_spec.rb
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
has_rdoc:
|