another_toy_robot 0.1.11 → 0.1.12

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: 9c89aa2204dd819da5f7da04a0d2340aa949a06c
4
- data.tar.gz: 8968eb0fb994e02235392bf16902a0251fae5f9b
3
+ metadata.gz: 55f824721df20bab7fca05a862acfba15aa0be7b
4
+ data.tar.gz: 97ee1296da13b1b7d3464c9ee3cb5c6c8d084dfb
5
5
  SHA512:
6
- metadata.gz: ced10d993eefbb960628dcea6f1ee01c282ff24500dee200ea2e8a73594b259a7283af1ffd9cc0562d84b959c3b838300a73e79775f329a470f7710ea00fbeee
7
- data.tar.gz: c6a24154fc734f686603e37c12d95a3283fb7b91a54999f454f83a4438de07a9c46e3eb42f155bcad88755e2888077204b2c944b933fc5f557ab110c47b84247
6
+ metadata.gz: d02212f8b657911404346f3ba7cb10cc129dd2a5877a6b39339926f974b92dfea79f0ad06e566f562d539d6214e81e7db91627e20f365ea0e18926b5b08f7261
7
+ data.tar.gz: a387500683a0e490d23c5bdaef8ad847388a6d0c723564f1842b0af8dbe8ee326090a0b35e18bb1eb9db2faff201022f756fb8ce004ac27ee1fafc8562f4f367
data/README.md CHANGED
@@ -74,7 +74,7 @@ require "another_toy_robot"
74
74
  AnotherToyRobot.main
75
75
  ```
76
76
 
77
- `AnotherToyRobot#main` instantiates a new `Client`. The `Client` instantiates an `Arena` and `Robot` objects. The new `Robot` is initialised with `NullPosition` in the `Arena`.
77
+ `AnotherToyRobot#main` instantiates a new `Client`. The `Client` instantiates a new `Robot` and `Arena`. The new `Robot` is initialised with `NullPosition`, and assigned the new arena.
78
78
 
79
79
  The main loop does the following:
80
80
 
@@ -99,14 +99,10 @@ This process continues until an `"exit"` command is received, breaking the loop.
99
99
  ### Considerations
100
100
  Given the requirement for a command line interface to interact with the robot, I settled on the well established and widely used command pattern.
101
101
 
102
- The `Input` wrapper allows new commands to be easily added. E.g. Creating a new file `lib/another_toy_robot/random_command.rb` and requiring it, would be all that is required for the application to accept the `"random"` command, and it would have access to an array of parameters. Validations can also be added by defining a `valid?` method on the command object. See the `lib/another_toy_robot/place_command.rb` for an example.
102
+ The `Input` wrapper allows new commands to be easily added. E.g. Creating a new file `lib/another_toy_robot/random_command.rb` and requiring it, is all that is required for the application to accept the `"random"` command, and it would have access to an array of parameters. Validations can also be added by defining a `valid?` method on the command object. See the `lib/another_toy_robot/place_command.rb` for an example.
103
103
 
104
104
  I'm particularly happy with the `Position` class and the `Direction` modules. Together as a unit they have absolutely no dependencies and could be easily reused with new features, new objects, or with changing specifications. It would be reasonably straight forward to add a second robot, or a third dimension.
105
105
 
106
- Currently the `Robot` must be instantiated with an `Arena`. Originally, I had also employed the null object pattern for the `Arena` as well as the position, but as it turned out, with the current specification, there is no situation where a robot is not in an arena, so it was unneeded and removed, reducing overall complexity of the application.
107
-
108
- As GINnFIN helpfully pointed out in the [Reddit discussion](https://www.reddit.com/r/ruby/comments/5fptz9/i_did_the_toy_robot_challenge_ive_tried_to_be/), the `Position` `#left` and `#right` methods do necessarily need to return a new instance of `Position`, and could instead mutate the current position in place. While this is true, there is a pleasing symmetry in each of the current `Position` methods returning a new instance of position that would would be lost if these were to be changed. I'm not entirely sure which is better, but have decided to keep the current implementation, as different behaviour for the `place` and `move` methods to the `left` and `right` methods may be unnecessarily increasing the conceptual complexity of the app.
109
-
110
106
  ### Licence
111
107
  [MIT](https://tldrlegal.com/license/mit-license)
112
108
 
@@ -6,7 +6,7 @@ require "another_toy_robot/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "another_toy_robot"
8
8
  spec.version = AnotherToyRobot::VERSION
9
- spec.date = "2016-12-05"
9
+ spec.date = "2016-12-07"
10
10
  spec.authors = "Sheldon J. Johnson"
11
11
  spec.email = "sheldon.j.johnson@outlook.com"
12
12
  spec.homepage = "https://github.com/drzel/another_toy_robot"
@@ -4,7 +4,7 @@ class Arena
4
4
  @rows = 0...height
5
5
  end
6
6
 
7
- def inbounds?(x_coord, y_coord)
8
- @columns.cover?(x_coord) && @rows.cover?(y_coord)
7
+ def inbounds?(position)
8
+ @columns.cover?(position.x_coord) && @rows.cover?(position.y_coord)
9
9
  end
10
10
  end
@@ -3,8 +3,10 @@ require "another_toy_robot/robot"
3
3
 
4
4
  class Client
5
5
  def initialize
6
+ @robot = Robot.new
6
7
  @table = Arena.new width: 5, height: 5
7
- @robot = Robot.new arena: @table
8
+
9
+ @robot.arena = @table
8
10
  end
9
11
 
10
12
  def command_for(input)
@@ -11,28 +11,22 @@ class Input
11
11
  end
12
12
 
13
13
  def new_command(target)
14
- to_class.new target: target, params: params
14
+ command_class.new target: target, params: params
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def basename
20
- @basename ||= @input.split(" ").first
21
- end
22
-
23
19
  def params
24
20
  @params ||= @input.split(" ").drop 1
25
21
  end
26
22
 
27
- def classname
28
- @classname ||= "#{basename.capitalize}Command"
23
+ def basename
24
+ @basename ||= @input.split(" ").first
29
25
  end
30
26
 
31
- def to_class
32
- if Object.const_defined? classname
33
- Object.const_get classname
34
- else
35
- InvalidCommand
36
- end
27
+ def command_class
28
+ klass = "#{basename.capitalize}Command"
29
+ return InvalidCommand unless Object.const_defined? klass
30
+ Object.const_get klass
37
31
  end
38
32
  end
@@ -0,0 +1,5 @@
1
+ class NullArena
2
+ def inbounds?(*)
3
+ true
4
+ end
5
+ end
@@ -1,11 +1,13 @@
1
1
  require "another_toy_robot/position"
2
2
  require "another_toy_robot/null_position"
3
3
  require "another_toy_robot/arena"
4
+ require "another_toy_robot/null_arena"
4
5
 
5
6
  class Robot
6
- attr_reader :position, :arena
7
+ attr_accessor :arena
8
+ attr_reader :position
7
9
 
8
- def initialize(position: NullPosition.new, arena: Arena.new)
10
+ def initialize(position: NullPosition.new, arena: NullArena.new)
9
11
  @position = position
10
12
  @arena = arena
11
13
  end
@@ -33,8 +35,7 @@ class Robot
33
35
  private
34
36
 
35
37
  def safely_go_to(position)
36
- return unless position.x_coord && position.y_coord
37
- return unless @arena.inbounds? position.x_coord, position.y_coord
38
+ return unless @arena.inbounds? position
38
39
  @position = position
39
40
  end
40
41
  end
@@ -1,3 +1,3 @@
1
1
  module AnotherToyRobot
2
- VERSION = "0.1.11".freeze
2
+ VERSION = "0.1.12".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: another_toy_robot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sheldon J. Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-05 00:00:00.000000000 Z
11
+ date: 2016-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -110,6 +110,7 @@ files:
110
110
  - lib/another_toy_robot/invalid_command.rb
111
111
  - lib/another_toy_robot/left_command.rb
112
112
  - lib/another_toy_robot/move_command.rb
113
+ - lib/another_toy_robot/null_arena.rb
113
114
  - lib/another_toy_robot/null_position.rb
114
115
  - lib/another_toy_robot/place_command.rb
115
116
  - lib/another_toy_robot/position.rb