another_toy_robot 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19356ced35855d3bd280b77f6ec6174698d4f8ba
4
- data.tar.gz: 773afcf5e484aff26acc7db9c247c4164aae0d63
3
+ metadata.gz: 7c172c05d49f128057d23173ff7b4dd448378db9
4
+ data.tar.gz: e2c7f21029d0cdca40e142ed3cce0a8afd185d3c
5
5
  SHA512:
6
- metadata.gz: 8775ee5ad28ec404de542c2b69b4585c67a7d46749570e68414bebd144e3e1e390dc3017742f909fdc7b137702a323bfe5ac9affd89b31542d3d4b7584daa153
7
- data.tar.gz: 1e2ff237e8cdf6ad4bd7e46fa051613759f4ee8b4efd89e43d19899085f8c47638f06ec403a7c2a16a0ca497ab385e7aaa2a30167399406508ad75027803b4fb
6
+ metadata.gz: a6544b8a114e7ae2266077ff6491ef35aaa9b629e945fb268a56862c0f28b68ef9edaf817f543d07b2e0b15aa2be97e1d689d7a479f9f3fcf0643e968a0c0cbd
7
+ data.tar.gz: 638af44750a27e6ffdb62fffcc3717a1eb06240ded47d21cb5c07e0e4363997849a221ccb5fe1085e1f32bbbb477412293e802682c3aa7e2e2a9a855ac354912
@@ -6,8 +6,8 @@ class Arena
6
6
  @height = height
7
7
  end
8
8
 
9
- def inbounds?(x, y)
10
- x.between?(0, max_x) && y.between?(0, max_y)
9
+ def inbounds?(x_coord, y_coord)
10
+ x_coord&.between?(0, max_x) && y_coord&.between?(0, max_y)
11
11
  end
12
12
 
13
13
  private
@@ -20,9 +20,3 @@ class Arena
20
20
  height - 1
21
21
  end
22
22
  end
23
-
24
- class NullArena
25
- def inbounds?(*)
26
- true
27
- end
28
- end
@@ -1,13 +1,13 @@
1
1
  class Client
2
2
  def initialize
3
- @robot = Robot.new
4
3
  @table = Arena.new width: 5, height: 5
4
+ @robot = Robot.new arena: @table
5
5
  end
6
6
 
7
7
  def instruction(input)
8
8
  command = case input
9
- when /place\s+(\d+,\s*){2}[nesw]/
10
- PlaceCommand.new robot: @robot, arena: @table, command: input
9
+ when /place\s+(\d+,\s*){2}([nesw]|(north)|(east)|(south)|(west))$/
10
+ PlaceCommand.new robot: @robot, command: input
11
11
  when "move"
12
12
  MoveCommand.new robot: @robot
13
13
  when "left"
@@ -1,16 +1,24 @@
1
1
  class PlaceCommand
2
- def initialize(robot:, arena: NullArena.new, command:)
2
+ def initialize(robot:, command:)
3
3
  @robot = robot
4
- @arena = arena
5
4
  @params = command[/\s.*/].delete(" ").split(",")
6
5
  end
7
6
 
8
7
  def execute
9
- position = NullPosition.new arena: @arena
10
- position = position.go_to(x: @params[0].to_i,
11
- y: @params[1].to_i,
12
- direction: @params[2].to_sym)
13
- @robot.position = position
8
+ @robot.place RealPosition.new(x_coord: @params[0].to_i,
9
+ y_coord: @params[1].to_i,
10
+ direction: direction)
11
+ end
12
+
13
+ private
14
+
15
+ def direction
16
+ case @params[2]
17
+ when "n", "north" then North.new
18
+ when "e", "east" then East.new
19
+ when "s", "south" then South.new
20
+ when "w", "west" then West.new
21
+ end
14
22
  end
15
23
  end
16
24
 
@@ -0,0 +1,71 @@
1
+ class North
2
+ attr_reader :x_displacement, :y_displacement, :to_s
3
+
4
+ def initialize
5
+ @x_displacement = 0
6
+ @y_displacement = 1
7
+ @to_s = "north"
8
+ end
9
+
10
+ def left
11
+ West.new
12
+ end
13
+
14
+ def right
15
+ East.new
16
+ end
17
+ end
18
+
19
+ class East
20
+ attr_reader :x_displacement, :y_displacement, :to_s
21
+
22
+ def initialize
23
+ @x_displacement = 1
24
+ @y_displacement = 0
25
+ @to_s = "east"
26
+ end
27
+
28
+ def left
29
+ North.new
30
+ end
31
+
32
+ def right
33
+ South.new
34
+ end
35
+ end
36
+
37
+ class South
38
+ attr_reader :x_displacement, :y_displacement, :to_s
39
+
40
+ def initialize
41
+ @x_displacement = 0
42
+ @y_displacement = -1
43
+ @to_s = "south"
44
+ end
45
+
46
+ def left
47
+ East.new
48
+ end
49
+
50
+ def right
51
+ West.new
52
+ end
53
+ end
54
+
55
+ class West
56
+ attr_reader :x_displacement, :y_displacement, :to_s
57
+
58
+ def initialize
59
+ @x_displacement = -1
60
+ @y_displacement = 0
61
+ @to_s = "west"
62
+ end
63
+
64
+ def left
65
+ South.new
66
+ end
67
+
68
+ def right
69
+ North.new
70
+ end
71
+ end
@@ -1,45 +1,22 @@
1
- class Position
2
- attr_accessor :arena
1
+ class RealPosition
2
+ attr_reader :x_coord, :y_coord, :direction
3
3
 
4
- def initialize(arena: NullArena.new, **args)
5
- @arena = arena
6
- post_initialize args
7
- end
8
-
9
- def go_to(x: @x_coord, y: @y_coord, direction: @direction)
10
- if @arena.inbounds? x, y
11
- RealPosition.new x: x, y: y, direction: direction, arena: @arena
12
- else
13
- self
14
- end
15
- end
16
- end
17
-
18
- class RealPosition < Position
19
- attr_accessor :x_coord, :y_coord, :direction
20
-
21
- ROTATION = { left: -1, right: 1 }.freeze
22
- DISPLACEMENT = { n: { x: 0, y: 1 },
23
- e: { x: 1, y: 0 },
24
- s: { x: 0, y: -1 },
25
- w: { x: -1, y: 0 } }.freeze
26
-
27
- def post_initialize(x: 0, y: 0, direction: :n)
28
- @x_coord = x
29
- @y_coord = y
4
+ def initialize(x_coord: 0, y_coord: 0, direction: North.new)
5
+ @x_coord = x_coord
6
+ @y_coord = y_coord
30
7
  @direction = direction
31
8
  end
32
9
 
33
10
  def advance
34
- new_x = @x_coord + DISPLACEMENT[@direction][:x]
35
- new_y = @y_coord + DISPLACEMENT[@direction][:y]
36
- go_to x: new_x, y: new_y
11
+ x = @x_coord + @direction.x_displacement
12
+ y = @y_coord + @direction.y_displacement
13
+ RealPosition.new x_coord: x, y_coord: y, direction: @direction
37
14
  end
38
15
 
39
16
  def turn(hand_side)
40
- compass = DISPLACEMENT.keys
41
- index = (compass.find_index(@direction) + ROTATION[hand_side]) % 4
42
- go_to direction: compass[index]
17
+ RealPosition.new(x_coord: @x_coord,
18
+ y_coord: @y_coord,
19
+ direction: @direction.send(hand_side))
43
20
  end
44
21
 
45
22
  def to_s
@@ -47,8 +24,14 @@ class RealPosition < Position
47
24
  end
48
25
  end
49
26
 
50
- class NullPosition < Position
51
- def post_initialize(*); end
27
+ class NullPosition
28
+ attr_reader :x_coord, :y_coord, :direction
29
+
30
+ def initialize
31
+ @x_coord = nil
32
+ @y_coord = nil
33
+ @direction = nil
34
+ end
52
35
 
53
36
  def advance
54
37
  self
@@ -1,12 +1,17 @@
1
1
  class Robot
2
- attr_accessor :position
2
+ attr_accessor :position, :arena
3
3
 
4
- def initialize(position: NullPosition.new)
4
+ def initialize(position: NullPosition.new, arena:)
5
5
  @position = position
6
+ @arena = arena
7
+ end
8
+
9
+ def place(new_position)
10
+ @position = safely_go_to new_position
6
11
  end
7
12
 
8
13
  def move
9
- @position = @position.advance
14
+ @position = safely_go_to @position.advance
10
15
  end
11
16
 
12
17
  def left
@@ -20,4 +25,14 @@ class Robot
20
25
  def report
21
26
  puts @position.to_s
22
27
  end
28
+
29
+ private
30
+
31
+ def safely_go_to(new_position)
32
+ if @arena.inbounds? new_position.x_coord, new_position.y_coord
33
+ new_position
34
+ else
35
+ @position
36
+ end
37
+ end
23
38
  end
@@ -1,3 +1,3 @@
1
1
  module ToyRobot
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/lib/toy_robot.rb CHANGED
@@ -4,16 +4,23 @@ require "toy_robot/robot"
4
4
  require "toy_robot/arena"
5
5
  require "toy_robot/command"
6
6
  require "toy_robot/position"
7
+ require "toy_robot/direction"
7
8
 
8
9
  module ToyRobot
9
10
  def self.main
10
11
  client = Client.new
11
12
 
12
13
  loop do
13
- print "Input command: "
14
- input = gets.strip
15
- break if input == "exit"
16
- client.instruction input
14
+ command = get_input
15
+ break if command == "exit"
16
+ client.instruction command
17
17
  end
18
18
  end
19
+
20
+ private
21
+
22
+ def self.get_input
23
+ print "Input command: "
24
+ gets.downcase.strip
25
+ end
19
26
  end
data/toy_robot.gemspec CHANGED
@@ -6,7 +6,7 @@ require 'toy_robot/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "another_toy_robot"
8
8
  spec.version = ToyRobot::VERSION
9
- spec.date = "2016-11-27"
9
+ spec.date = "2016-11-29"
10
10
  spec.authors = "Sheldon J. Johnson"
11
11
  spec.email = "sheldon.j.johnson@outlook.com"
12
12
  spec.homepage = "https://github.com/drzel/toy_robot"
@@ -16,7 +16,8 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.description = <<~HEREDOC
18
18
  The application is a simulation of a toy robot moving on a square tabletop.
19
- It is an example of a well tested, object oriented design, employing the command design pattern.
19
+ It is an example of a well tested, object oriented design, employing the
20
+ command design pattern.
20
21
  HEREDOC
21
22
 
22
23
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
metadata CHANGED
@@ -1,18 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: another_toy_robot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
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-11-27 00:00:00.000000000 Z
11
+ date: 2016-11-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- The application is a simulation of a toy robot moving on a square tabletop.
15
- It is an example of a well tested, object oriented design, employing the command design pattern.
13
+ description: "The application is a simulation of a toy robot moving on a square tabletop.\nIt
14
+ is an example of a well tested, object oriented design, employing the \ncommand
15
+ design pattern.\n"
16
16
  email: sheldon.j.johnson@outlook.com
17
17
  executables:
18
18
  - toy_robot
@@ -33,6 +33,7 @@ files:
33
33
  - lib/toy_robot/arena.rb
34
34
  - lib/toy_robot/client.rb
35
35
  - lib/toy_robot/command.rb
36
+ - lib/toy_robot/direction.rb
36
37
  - lib/toy_robot/position.rb
37
38
  - lib/toy_robot/robot.rb
38
39
  - lib/toy_robot/version.rb