-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimple.rb
149 lines (122 loc) · 3.58 KB
/
simple.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# it does not seem worth it to make classes of everything especially because the various case statements clarify the alternatives and avoid mistakes
# see allclasses for a demonstration of double dispatching
class Robot
North,South,East,West="NORTH","SOUTH","EAST","WEST"
def self.run
r= self.new
ARGF.each_line do |cmd|
report= r.executeCommand(cmd)
puts report unless report.nil?
end
end
def initialize()
@isOnTable=false
@reports=nil
end
def leftIfOnTable
return unless @isOnTable
@heading =
case @heading
when North then West
when South then East
when East then North
when West then South
end
return nil
end
def rightIfOnTable
return unless @isOnTable
@heading =
case @heading
when North then East
when South then West
when East then South
when West then North
end
#@heading=East if @heading==North
#@heading=West if @heading==South
#@heading=South if @heading==East
#@heading=North if @heading==West
return nil
end
def moveIfOnTableAndStaysOnTable
return unless @isOnTable
proposedX, proposedY = @x, @y
if @heading==North then
proposedX, proposedY=proposedX, proposedY+1
elsif @heading==South
proposedX, proposedY=proposedX, proposedY-1
elsif @heading==East
proposedX, proposedY=proposedX+1, proposedY
elsif @heading==West
proposedX, proposedY=proposedX-1, proposedY
end
@x, @y =constrainedX(proposedX), constrainedY(proposedY)
return nil
end
def placeIfItWillBeOntoTable(x, y, heading)
if x==constrainedX(x) && y==constrainedY(y)
@x, @y, @heading, @isOnTable= x, y, heading, true
end
return nil
end
def reportIfOnTable()
return unless @isOnTable
report = "#@x,#@y,#@heading"
return report
end
def executeCommands(commands)
reports=[]
if commands.respond_to?("each_line") then
return executeCommands commands.split("\n")
end
commands.each {
|command|
report = executeCommand command
(reports << report) unless report.nil?
}
return reports
end
def executeCommand(command )
#puts "command=#{command}"
#puts "@isOnTable=#@isOnTable"
commandElements = command.strip.split(/[ ,]/)
return if commandElements.size<1
commandName = commandElements.first.strip
#ensure non-valid single word commands are ignored
return if commandElements.size>1 && ["REPORT" , "MOVE" , "LEFT" , "RIGHT"].include?(commandName)
case commandName
when "REPORT" then return self.reportIfOnTable
when "MOVE" then return self.moveIfOnTableAndStaysOnTable
when "LEFT" then return self.leftIfOnTable
when "RIGHT" then return self.rightIfOnTable
when "PLACE" then
return if commandElements.size!= 4
x =commandElements[1].to_i
y =commandElements[2].to_i
heading= case commandElements[3].strip
when "NORTH" then North
when "SOUTH" then South
when "EAST" then East
when "WEST" then West
end
return if heading==nil || x.to_s != commandElements[1].strip || y.to_s != commandElements[2].strip
return self.placeIfItWillBeOntoTable(x,y,heading)
end
end
def constrainedX(x)
return max(min(x, 5), 0)
end
def constrainedY(y)
return max(min(y, 5), 0)
end
def min(*args)
args.min
end
def max(*args)
args.max
end
end
if __FILE__ == $0
Robot.run
end