我需要创建一个方法turn_left,该方法可以更改面层,而faceing始终从:south开始(我正在实现一个要移动到木板中的机器人),因此,如果我调用方法turn_left,则应将面层更改为East,然后更改为North,然后更改为西部然后返回南部。我在想这样的事情:
{
0: S
1: E
2: N
3: W
}
这是我的代码
# Models the Robor behavior for the game
class Robot
def initialize(attr = {})
# @position = attr[:position]
# @move = attr[:move]
@facing = :south
# @turn_left =
# @turn_right =
# @errors =
end
def position
end
def move
end
def facing
@facing
end
def turn_left
end
def turn_right
end
def errors
end
end
非常感谢您!
答案 0 :(得分:5)
怎么样呢?
class Robot
FACINGS = [:south, :east, :north, :west]
def initialize(attr = {})
@facing_index = 0 # south
end
def facing
FACINGS[@facing_index]
end
def turn_left
@facing_index += 1
@facing_index %= 4
end
def turn_right
@facing_index -= 1
@facing_index %= 4
end
end
%= 4
(或者,如果您真的想进一步概括一下,%= FACINGS.length
)执行模算术以将当前索引“包装”回0-3范围。
因此,通过增加/减少此数字,您可以在四个方向之间切换。
我不知道您打算如何实现position
,move
和errors
,但我认为这超出了您的问题范围。
答案 1 :(得分:4)
您可以将路线存储在数组中:
def initialize
@dirs = [:S, :W, :N, :E]
end
以first
条目为对向:
def facing
@dirs.first
end
当机器人向左转时,您rotate!
逆时针旋转阵列:
def turn_left
@dirs.rotate! -1
end
或者在右转时顺时针旋转:(1
在这里可以省略)
def turn_right
@dirs.rotate! 1
end
答案 2 :(得分:4)
left = {:n=>:w, :w=>:s, :s=>:e, :e=>:n}
right = left.invert
#=> {:w=>:n, :s=>:w, :e=>:s, :n=>:e}
pos = :s
pos = left[pos]
#=> :e
pos = right[pos]
#=> :w
答案 3 :(得分:2)
我会使用度数而不是枚举。这样,您可以通过从当前面中添加/减去 n 度来操纵面。
class Robot
attr_accessor :facing
def initialize(**attrs)
self.facing = attrs[:facing] || 180 # south
end
def rotate!(degrees)
self.facing = (self.facing + degrees) % 360
end
def rotate_left!
rotate!(-90)
end
def rotate_right!
rotate!(90)
end
end
然后您可以使用一种相对简单的方法将度数转换为基数(罗经点):
class Robot
COMPASS_POINTS = %w[N E S W]
# ...
def compass_point
seg_size = 360 / COMPASS_POINTS.size
COMPASS_POINTS[((facing + (seg_size / 2)) % 360) / seg_size]
end
end
此人摘自geocoder gem。
这似乎有些复杂,但是如果您要跟踪执行的命令,则可以将执行的命令存储为rotate: 90
或rotate: -90
。如果需要,还可以使机器人旋转360度(无级)。