loco_bot 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef33dd6ab2797541d85647722519e50e1fcf5c56
4
- data.tar.gz: 2695c38bbc217dd317ba7ab67cfc6681e4034be7
3
+ metadata.gz: 5bcc03fc9e471fbe3836c3d97c8f4b2c1781c3b4
4
+ data.tar.gz: 3422b70bf9684df8760c86aee333509d3c3ea18f
5
5
  SHA512:
6
- metadata.gz: 713365f6dd107ae2ac6410e192d5f77d4da7fd60590f289b409967e29dad9a83987103a6be79800092d0d02eba6b27a15b1f28dec10ac205736b1b4b0db69526
7
- data.tar.gz: 511a8c28a3cfcd05ceb5b925f15c4cebfa250ca6a7b219657403c80d829add94e1c070248112b6260641a6805a94f505aa4a49828696ba914941d776663de2ac
6
+ metadata.gz: f6e1f94945da2600e5d87060c1d86a38609e38b762c2b270a2f603306b7bd762aa93883a1b6627d82a9a545d6f5a07471337a266bb1af7b4b11c1141f5a8a4d5
7
+ data.tar.gz: 1a543d54eb4229da4fe29d915b1f4f9251d31e9d9b56f76d34807d611193cfcec09c9cc3e2b1f60338d934224669109cf8ab08bea020c7c78acda7ef30f5b053
@@ -22,13 +22,13 @@ module LocoBot
22
22
  'EAST'
23
23
  end
24
24
 
25
- # Returns the given coordinates in a Hash, modified to reflect the Direction.
25
+ # The Direction is applied to the given coordinates and returns vectorial coordinates in a Hash.
26
26
  # @param x [Integer] the x-axis coordinate
27
27
  # @param y [Integer] the y-axis coordinate
28
- # @return [Hash] the modified x and y coordinates
28
+ # @return [Hash] the vectorial x and y coordinates
29
29
  # @example
30
- # Direction::East.coordinates(1, 2) # => {x: 2, y: 2}
31
- def self.coordinates(x, y)
30
+ # Direction::East.vector(1, 2) # => {x: 2, y: 2}
31
+ def self.vector(x, y)
32
32
  { x: x + 1, y: y }
33
33
  end
34
34
  end
@@ -22,13 +22,13 @@ module LocoBot
22
22
  'NORTH'
23
23
  end
24
24
 
25
- # Returns the given coordinates in a Hash, modified to reflect the Direction.
25
+ # The Direction is applied to the given coordinates and returns vectorial coordinates in a Hash.
26
26
  # @param x [Integer] the x-axis coordinate
27
27
  # @param y [Integer] the y-axis coordinate
28
- # @return [Hash] the modified x and y coordinates
28
+ # @return [Hash] the vectorial x and y coordinates
29
29
  # @example
30
- # Direction::North.coordinates(1, 2) # => {x: 1, y: 3}
31
- def self.coordinates(x, y)
30
+ # Direction::North.vector(1, 2) # => {x: 1, y: 3}
31
+ def self.vector(x, y)
32
32
  { x: x, y: y + 1 }
33
33
  end
34
34
  end
@@ -22,13 +22,13 @@ module LocoBot
22
22
  'SOUTH'
23
23
  end
24
24
 
25
- # Returns the given coordinates in a Hash, modified to reflect the Direction.
25
+ # The Direction is applied to the given coordinates and returns vectorial coordinates in a Hash.
26
26
  # @param x [Integer] the x-axis coordinate
27
27
  # @param y [Integer] the y-axis coordinate
28
- # @return [Hash] the modified x and y coordinates
28
+ # @return [Hash] the vectorial x and y coordinates
29
29
  # @example
30
- # Direction::South.coordinates(1, 2) # => {x: 1, y: 1}
31
- def self.coordinates(x, y)
30
+ # Direction::South.vector(1, 2) # => {x: 1, y: 1}
31
+ def self.vector(x, y)
32
32
  { x: x, y: y - 1 }
33
33
  end
34
34
  end
@@ -22,13 +22,13 @@ module LocoBot
22
22
  'WEST'
23
23
  end
24
24
 
25
- # Returns the given coordinates in a Hash, modified to reflect the Direction.
25
+ # The Direction is applied to the given coordinates and returns vectorial coordinates in a Hash.
26
26
  # @param x [Integer] the x-axis coordinate
27
27
  # @param y [Integer] the y-axis coordinate
28
- # @return [Hash] the modified x and y coordinates
28
+ # @return [Hash] the vectorial x and y coordinates
29
29
  # @example
30
- # Direction::West.coordinates(1, 2) # => {x: 0, y: 2}
31
- def self.coordinates(x, y)
30
+ # Direction::West.vector(1, 2) # => {x: 0, y: 2}
31
+ def self.vector(x, y)
32
32
  { x: x - 1, y: y }
33
33
  end
34
34
  end
@@ -4,21 +4,21 @@ module LocoBot
4
4
  # Representation of a robot, placeable on tables.
5
5
  class Robot
6
6
 
7
- # @!attribute [rw] table
7
+ # @!attribute [r] table
8
8
  # @return [Table] the Table the Robot is currently placed on
9
- attr_accessor :table
9
+ attr_reader :table
10
10
 
11
- # @!attribute [rw] x
11
+ # @!attribute [r] x
12
12
  # @return [Integer] the x-axis coordinate the Robot is currently at on the Table
13
- attr_accessor :x
13
+ attr_reader :x
14
14
 
15
- # @!attribute [rw] y
15
+ # @!attribute [r] y
16
16
  # @return [Integer] the y-axis coordinate the Robot is currently at on the Table
17
- attr_accessor :y
17
+ attr_reader :y
18
18
 
19
- # @!attribute [rw] direction
19
+ # @!attribute [r] direction
20
20
  # @return [Direction] the Direction the Robot is currently facing on the Table
21
- attr_accessor :direction
21
+ attr_reader :direction
22
22
 
23
23
  # Places the Robot on the given Table at the given coordinates, facing the given Direction.
24
24
  # If the Robot was previously on another Table, it is removed from it before being placed on the given.
@@ -31,7 +31,7 @@ module LocoBot
31
31
  table.place_robot(self, x, y, direction)
32
32
  end
33
33
 
34
- # Removes the Robot its current Table. Position attributes of the Robot are set to nil.
34
+ # Removes the Robot from its current Table. Position attributes of the Robot are set to nil.
35
35
  # @return [Boolean] true if removing was successful, false otherwise.
36
36
  def remove
37
37
  return false if table.nil?
@@ -42,7 +42,7 @@ module LocoBot
42
42
  # Moves the robot one unit forward in the direction it is currently facing.
43
43
  # @return [Boolean] true if moving was successful, false otherwise.
44
44
  def move
45
- return false if table.nil? or !table.position_valid?(next_position[:x], next_position[:y])
45
+ return false unless next_position_valid?
46
46
 
47
47
  @x = next_position[:x]
48
48
  @y = next_position[:y]
@@ -92,11 +92,19 @@ module LocoBot
92
92
  # @return [Hash] the next x and y coordinates of the Robot.
93
93
  # @example
94
94
  # robot.place(1, 2, Direction::West)
95
- # robot.next_direction # => {x: 0, y: 2}
95
+ # robot.next_position # => {x: 0, y: 2}
96
96
  def next_position
97
97
  return {} if table.nil?
98
98
 
99
- direction.coordinates(x, y)
99
+ direction.vector(x, y)
100
+ end
101
+
102
+ # Determines if the next position position of the Robot is valid according to its Table.
103
+ # @return [Boolean] true if the position is valid, false otherwise.
104
+ def next_position_valid?
105
+ return false if table.nil?
106
+
107
+ table.position_valid?(next_position[:x], next_position[:y])
100
108
  end
101
109
  end
102
110
  end
@@ -12,11 +12,6 @@ module LocoBot
12
12
  # Determines the farthest accessible point on the Table's y-axis.
13
13
  attr_reader :height
14
14
 
15
- # @!attribute [r] robots
16
- # @return [Array<Robot>] a collection of [Robot]
17
- # The collection of Robots currently placed on the Table.
18
- attr_reader :robots
19
-
20
15
  # @param width [Integer] The width of the Table
21
16
  # @param height [Integer] The height of the Table
22
17
  def initialize(width = 5, height = 5)
@@ -37,28 +32,28 @@ module LocoBot
37
32
  def place_robot(robot, x, y, direction)
38
33
  return false unless position_valid?(x, y)
39
34
 
40
- robot.table.remove_robot(robot) if robot.table
35
+ robot.remove if robot.table
41
36
 
42
- robot.table = self
43
- robot.direction = direction
44
- robot.x = x
45
- robot.y = y
37
+ robot.instance_variable_set(:@table, self)
38
+ robot.instance_variable_set(:@x, x)
39
+ robot.instance_variable_set(:@y, y)
40
+ robot.instance_variable_set(:@direction, direction)
46
41
 
47
42
  @robots.push(robot) unless robots.include?(robot)
48
43
 
49
44
  true
50
45
  end
51
46
 
52
- # Removes the given Robot from the Table. Position attributes of the Robot are set to nil
47
+ # Removes the given Robot from the Table. Position attributes of the Robot are set to nil.
53
48
  # @param robot [Robot] the Robot to remove from the Table
54
49
  # @return [Boolean] true if removing was successful, false otherwise.
55
50
  def remove_robot(robot)
56
51
  return false unless robots.include?(robot)
57
52
 
58
- robot.table = nil
59
- robot.x = nil
60
- robot.y = nil
61
- robot.direction = nil
53
+ robot.instance_variable_set(:@table, nil)
54
+ robot.instance_variable_set(:@x, nil)
55
+ robot.instance_variable_set(:@y, nil)
56
+ robot.instance_variable_set(:@direction, nil)
62
57
 
63
58
  @robots.delete(robot)
64
59
 
@@ -73,6 +68,12 @@ module LocoBot
73
68
  position_within_bounds?(x, y) and position_free?(x, y)
74
69
  end
75
70
 
71
+ # The collection of Robots currently placed on the Table.
72
+ # @return [Array<Robot>] a collection of Robots
73
+ def robots
74
+ @robots.dup
75
+ end
76
+
76
77
  private
77
78
 
78
79
  def position_within_bounds?(x, y)
@@ -1,4 +1,4 @@
1
1
  module LocoBot
2
2
  # The gem's current version
3
- VERSION = '1.0.0'
3
+ VERSION = '2.0.0'
4
4
  end
@@ -14,6 +14,17 @@ RSpec.describe LocoBot::CLI do
14
14
 
15
15
  context 'with a valid number of arguments' do
16
16
  let(:arguments) { '1, 3, SOUTH' }
17
+ let(:command_class_double) { double }
18
+
19
+ it 'calls the correct command' do
20
+ expect(LocoBot::CLI::Command::Place).to receive(:new).
21
+ with(subject.robot, subject.table).
22
+ once.and_return(command_class_double)
23
+
24
+ expect(command_class_double).to receive(:execute).with('1', '3', 'SOUTH').once
25
+
26
+ subject.input!(input)
27
+ end
17
28
  end
18
29
 
19
30
  context 'with an invalid number of arguments' do
@@ -17,8 +17,8 @@ RSpec.describe LocoBot::Robot::Direction::East do
17
17
  it { is_expected.to eql 'EAST' }
18
18
  end
19
19
 
20
- describe '.coordinates' do
21
- subject { described_class.coordinates(21, 17) }
20
+ describe '.vector' do
21
+ subject { described_class.vector(21, 17) }
22
22
 
23
23
  it { is_expected.to eql({ x: 22, y: 17 }) }
24
24
  end
@@ -17,8 +17,8 @@ RSpec.describe LocoBot::Robot::Direction::North do
17
17
  it { is_expected.to eql 'NORTH' }
18
18
  end
19
19
 
20
- describe '.coordinates' do
21
- subject { described_class.coordinates(21, 17) }
20
+ describe '.vector' do
21
+ subject { described_class.vector(21, 17) }
22
22
 
23
23
  it { is_expected.to eql({ x: 21, y: 18 }) }
24
24
  end
@@ -17,8 +17,8 @@ RSpec.describe LocoBot::Robot::Direction::South do
17
17
  it { is_expected.to eql 'SOUTH' }
18
18
  end
19
19
 
20
- describe '.coordinates' do
21
- subject { described_class.coordinates(21, 17) }
20
+ describe '.vector' do
21
+ subject { described_class.vector(21, 17) }
22
22
 
23
23
  it { is_expected.to eql({ x: 21, y: 16 }) }
24
24
  end
@@ -17,8 +17,8 @@ RSpec.describe LocoBot::Robot::Direction::West do
17
17
  it { is_expected.to eql 'WEST' }
18
18
  end
19
19
 
20
- describe '.coordinates' do
21
- subject { described_class.coordinates(21, 17) }
20
+ describe '.vector' do
21
+ subject { described_class.vector(21, 17) }
22
22
 
23
23
  it { is_expected.to eql({ x: 20, y: 17 }) }
24
24
  end
@@ -3,26 +3,104 @@ RSpec.describe LocoBot::Robot do
3
3
  let(:table) { LocoBot::Table.new(20, 20) }
4
4
 
5
5
  describe '#place' do
6
- subject { robot }
6
+ let(:other_table) { LocoBot::Table.new(10, 10) }
7
+ let(:robot) { described_class.new }
8
+
9
+ before { robot.place(other_table, 5, 7, LocoBot::Robot::Direction::West) }
10
+
11
+ context 'with a valid position' do
12
+ it "modifies the table's robot list" do
13
+ expect(other_table.robots).to include(robot)
14
+ expect(table.robots).not_to include(robot)
15
+
16
+ robot.place(table, 12, 14, LocoBot::Robot::Direction::South)
17
+
18
+ expect(other_table.robots).not_to include(robot)
19
+ expect(table.robots).to include(robot)
20
+ end
21
+
22
+ it 'changes the robot table, x, y and position' do
23
+ expect(robot.table).to eql other_table
24
+ expect(robot.x).to eql 5
25
+ expect(robot.y).to eql 7
26
+ expect(robot.direction).to eql LocoBot::Robot::Direction::West
27
+
28
+ robot.place(table, 12, 14, LocoBot::Robot::Direction::South)
29
+
30
+ expect(robot.table).to eql table
31
+ expect(robot.x).to eql 12
32
+ expect(robot.y).to eql 14
33
+ expect(robot.direction).to eql LocoBot::Robot::Direction::South
34
+ end
35
+
36
+ it { expect(robot.place(table, 12, 14, LocoBot::Robot::Direction::South)).to be true }
37
+ end
38
+
39
+ context 'with an invalid position' do
40
+ it "does not modify the table's robot list" do
41
+ expect(other_table.robots).to include(robot)
42
+ expect(table.robots).not_to include(robot)
43
+
44
+ robot.place(table, 617, 9001, LocoBot::Robot::Direction::South)
45
+
46
+ expect(other_table.robots).to include(robot)
47
+ expect(table.robots).not_to include(robot)
48
+ end
49
+
50
+ it 'does not change the robot table, x, y and position' do
51
+ expect(robot.table).to eql other_table
52
+ expect(robot.x).to eql 5
53
+ expect(robot.y).to eql 7
54
+ expect(robot.direction).to eql LocoBot::Robot::Direction::West
7
55
 
8
- it 'calls Table#place_robot' do
9
- expect(table).to receive(:place_robot).with(subject, 9, 3, LocoBot::Robot::Direction::East).once
56
+ robot.place(table, 617, 9001, LocoBot::Robot::Direction::South)
10
57
 
11
- subject.place(table, 9, 3, LocoBot::Robot::Direction::East)
58
+ expect(robot.table).to eql other_table
59
+ expect(robot.x).to eql 5
60
+ expect(robot.y).to eql 7
61
+ expect(robot.direction).to eql LocoBot::Robot::Direction::West
62
+ end
63
+
64
+ it { expect(robot.place(table, 617, 9001, LocoBot::Robot::Direction::South)).to be false }
12
65
  end
13
66
  end
14
67
 
15
68
  describe '#remove' do
16
69
  subject { robot.remove }
17
70
 
71
+ before do
72
+ table.place_robot(LocoBot::Robot.new, 3, 4, LocoBot::Robot::Direction::North)
73
+ table.place_robot(LocoBot::Robot.new, 1, 8, LocoBot::Robot::Direction::West)
74
+ end
75
+
18
76
  context 'when placed on a table' do
19
77
  before { robot.place(table, 6, 17, LocoBot::Robot::Direction::East) }
20
78
 
21
- it 'calls Table#remove_robot' do
22
- expect(table).to receive(:remove_robot).with(robot).once
79
+ it "removes the robot from the table's list" do
80
+ expect(table.robots.count).to eql 3
81
+ expect(table.robots).to include(robot)
82
+
83
+ robot.remove
23
84
 
24
- subject
85
+ expect(table.robots.count).to eql 2
86
+ expect(table.robots).not_to include(robot)
25
87
  end
88
+
89
+ it 'sets to nil robot table, x, y and direction' do
90
+ expect(robot.table).to eql table
91
+ expect(robot.x).to eql 6
92
+ expect(robot.y).to eql 17
93
+ expect(robot.direction).to eql LocoBot::Robot::Direction::East
94
+
95
+ robot.remove
96
+
97
+ expect(robot.table).to be_nil
98
+ expect(robot.x).to be_nil
99
+ expect(robot.y).to be_nil
100
+ expect(robot.direction).to be_nil
101
+ end
102
+
103
+ it { expect(subject).to be true }
26
104
  end
27
105
 
28
106
  context 'when not placed on a table' do
@@ -244,4 +322,29 @@ RSpec.describe LocoBot::Robot do
244
322
  end
245
323
  end
246
324
  end
325
+
326
+ describe '#next_position_valid?' do
327
+ subject { robot.next_position_valid? }
328
+
329
+ context 'when not placed on a table' do
330
+ it { is_expected.to be false }
331
+ end
332
+
333
+
334
+ context 'when placed on a table' do
335
+ before { robot.place(table, 0, 0, direction) }
336
+
337
+ context 'facing a invalid position' do
338
+ let(:direction) { LocoBot::Robot::Direction::West }
339
+
340
+ it { is_expected.to be false }
341
+ end
342
+
343
+ context 'facing a valid position' do
344
+ let(:direction) { LocoBot::Robot::Direction::North }
345
+
346
+ it { is_expected.to be true }
347
+ end
348
+ end
349
+ end
247
350
  end
@@ -36,7 +36,7 @@ RSpec.describe LocoBot::Table do
36
36
  before { other_table.place_robot(robot, 5, 7, LocoBot::Robot::Direction::West) }
37
37
 
38
38
  context 'with a valid position' do
39
- it 'modifies the robot lists' do
39
+ it 'modifies the robot list' do
40
40
  expect(other_table.robots).to include(robot)
41
41
  expect(table.robots).not_to include(robot)
42
42
 
@@ -64,7 +64,7 @@ RSpec.describe LocoBot::Table do
64
64
  end
65
65
 
66
66
  context 'with an invalid position' do
67
- it 'does not modify the robot lists' do
67
+ it 'does not modify the robot list' do
68
68
  expect(other_table.robots).to include(robot)
69
69
  expect(table.robots).not_to include(robot)
70
70
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loco_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafaël Gonzalez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-06 00:00:00.000000000 Z
11
+ date: 2015-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -156,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
156
  version: '0'
157
157
  requirements: []
158
158
  rubyforge_project:
159
- rubygems_version: 2.2.2
159
+ rubygems_version: 2.4.6
160
160
  signing_key:
161
161
  specification_version: 4
162
162
  summary: Ruby gem of crazy robots and benevolent tables that keep watching over them.