Изменить положение в соответствии с облицовкой в ​​Ruby - PullRequest
0 голосов
/ 13 ноября 2018

Мне нужно реализовать метод перемещения, который меняет положение в соответствии с лицом, позиция - это [x, y], и я думаю, что если двигаться на юг, то это будет y + 1, на север y-1, на восток x-1 и к западу х + 1. эти движения в матрицу. Это мой код Большое спасибо за вашу помощь!

# Models the Robot behavior for the game
class Robot
 FACINGS = [:south, :east, :north, :west]

 def initialize(attr = {})
  @position = attr[:position] || [1, 1]
  # @move = attr[:move]
  @facing_index = facing_index(attr[:facing]) || 0 # south
  @facing = facing
  # @errors =
 end

 def position
  @position
 end

 def move

 end

 def facing
  @facing = FACINGS[@facing_index]
 end

 def errors
 end

 private

 def facing_index(facing)
  facing if facing.is_a? Integer
  FACINGS.index(facing&.to_sym)
 end
end

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018
DIRECTION_NUMBER = { :north=>0, :east=>1, :south=>2, :west=>3 }

@left = { :north=>:west, :west=>:south, :south=>:east, :east=>:north }
@right = @left.invert
  #=> {:west=>:north, :south=>:west, :east=>:south, :north=>:east}

def turn_left
  @facing = @left[@facing]
end

def turn_right
  @facing = @right[@facing]
end

def move(direction)
  x, y = @location
  @location =
  case direction
  when :north
    [x,y+1]
  when :east
    [x+1,y]
  when :south
    [x,y-1]
  else
    [x-1,y]
  end
  update_facing(direction)
end

private

def update_facing(direction)
  change = (DIRECTION_NUMBER[direction] - DIRECTION_NUMBER[@facing]) % 4
  case change
  when 1
    turn_right
  when 2
    turn_right; turn_right
  when 3
    turn_left
  end
end

@location = [3, 3]    
@facing = :east

move(:south)
@location   #=> [3, 2]
@facing     #=> :south

move(:north)
@location   #=> [3, 3]
@facing     #=> :north

move(:west)
@location   #=> [2, 3]
@facing     #=> :west

move(:east)
@location   #=> [3, 3]
@facing     #=> :east
0 голосов
/ 14 ноября 2018

Пример перечисления FACINGS.

module FACINGS
  NORTH = [0, 1]
  SOURTH = [0, -1]
  EAST =  [1, 0]
  WEST =  [-1,0]
end

class Robot
  attr_reader :position

  def initialize(attr = {})
    @position = attr[:position] || [1, 1]
  end

  def move(facings)
    @position[0] += facings[0]
    @position[1] += facings[1]
  end
end

r = Robot.new
r.move(FACINGS::NORTH)
r.move(FACINGS::SOURTH)
r.move(FACINGS::WEST)
r.move(FACINGS::EAST)
0 голосов
/ 13 ноября 2018

Добавьте MOVES, который говорит, как двигаться в зависимости от того, как вы столкнулись.

MOVES = {
  north: [0, 1],
  south: [0, -1],
  east:  [1, 0],
  west:  [-1,0]
}

def move
  move = MOVES.fetch(@facing)
  @position[0] += move[0]
  @position[1] += move[1]
end

MOVES.fetch(@facing) используется вместо MOVES[@facing], поэтому возникнет ошибка, если для этой стороны не будет хода.

Вы также можете сделать это с помощью оператора case, но это делает move простым и управляемым данными. Вы можете добавить больше направлений, таких как northeast: [1,1]. И если вы сделаете это переменной экземпляра, вы можете настроить способ перемещения отдельных роботов.

# Define `moves` and `moves=` to get and set `@moves`
attr_accessor :moves

def initialize(attr = {})
  ...
  # Initialize `moves` with either Robot.new(moves: {...})
  # or the default MOVES
  @moves ||= attr[:moves] || MOVES
  ...
end

def move
  move = moves.fetch(@facing)
  @position[0] += move[0]
  @position[1] += move[1]
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...