another_toy_robot 0.1.2 → 0.1.3

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: 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