关于一个找出口的问题的初级解决

备忘用,肯定可以重构,但现在不重要=。=|,点这里看问题

def solve(map, miner, exit)
  #根据需求,需要把二维数组转置一下
  #需求是这样的一个二维数组,[[1,2],[3,4]],一般来说array[0][1]的值为2,但用{'x' => 0, 'y' => 1}表示的话,对应的是array[1][0],也就是3,因为这个,所以有一些地方就反过来了,但问题不大,这个不重要
  map_transpose = map.transpose
  #先把地图上所有点的可以去的方向与该点对应起来,用一个hash表示
  hash_map = {}
  map_transpose.each_with_index do |ele_one,index_one|
    ele_one.each_with_index do |ele_two, index_two|
      key = {'x' => index_two, 'y' => index_one}
      hash_map[key] = can_go(key, map_transpose)
    end
  end
  #仍然是准备工作
  from = {'left' => 'right', 'right' => 'left', 'up' => 'down', 'down' => 'up'}

  #初始化一些数据
  #path表示当前的路径
  path ||= []
  #posion_record表示当前所有经过的位置
  position_record ||= [miner]
  #current_position表示当前的位置
  current_position = position_record.last  

  #判断如果当前位置是出口,则退出循环
  until current_position['x'] == exit['x'] && current_position['y'] == exit['y']
    #因为随着路径的探索,有一些死路需要被标记,所以每次都重新获得一下当前位置可以去的方向
    hash_map[current_position] = can_go(current_position, map_transpose)
    #可能去的方向需要删除掉来的方向
    hash_map[current_position].delete(from[path.last])
    #如果所有方向都去不了,那么则把这个位置标记成死路,在map_transpose数组中,该位置的值修改为false
    #同时将path和position_record中最后的值删除,回到上一个位置,重新计算可能去的方向
    if hash_map[current_position].empty? 
      path.pop
      position_record.pop
      map_transpose.set_dead_value_of_position(current_position)
    else
    #如果有可以去的方向,则把第一个方向做为要去的方向,把该方向加入到path中,把该方向的下一个位置加入到position_record中
      direction = hash_map[current_position].first
      path << direction
      next_position = next_direction_position(current_position, direction)
      position_record << next_position
    end    
    #不管是回到上一个位置还是去到下一个位置,都需要把position_record中最后一个位置当做当前的位置
    current_position = position_record.last
  end

  path
end

#动态加入两个二维数组的实例方法,为了结合需求的说明,具体实现不重要
class Array
  #获得对应position在二维数组中的值
  def value_of_position(position)
    y, x = position['x'], position['y']
    self[x][y]
  end
  #修改对应position在二维数组中的值为false,标记为是死路
  def set_dead_value_of_position(position)
    y, x = position['x'], position['y']
    self[x][y] = false
  end
end

#获得对应方向的下一个位置
def next_direction_position(position, direction)
   case direction
   when "left"   
    x, y  = position['x'] - 1, position['y']
   when "right"  
    x, y  = position['x'] + 1, position['y']
   when "up"     
    x, y = position['x'], position['y'] - 1
   when "down"   
    x, y = position['x'], position['y'] + 1
   end
   {'x' => x , 'y' => y}
end
#判断当前position在当前的地图中可以去的方向,如果下一个位置是false,则不能去,如果是地图边缘的位置,也不能走到地图外面
def can_go(position, map)
  directions = []
  width = map.first.size-1
  high = map.size - 1
  %w(left right up down).each do |direction|
    next_position = next_direction_position(position,direction)
    case direction
    when "left"  
     if position['x'] > 0 
      directions << direction if map.value_of_position(next_position)
     end
    when "right" 
     if position['x'] < width
      directions << direction if map.value_of_position(next_position)
     end
    when "up"    
     if position['y'] > 0
      directions << direction if map.value_of_position(next_position)
     end
    when "down"  
     if position['y'] < high
      directions << direction if map.value_of_position(next_position)
     end
    end
  end
  directions
end

minemap = [[true, true, true, true, true],
    [true, false, true, false, true],
    [false, true, true, true, false],
    [true, false, false, true, true],
    [true, true, true, true, false]]


p solve(minemap, {'x'=>0,'y'=>4}, {'x'=>3,'y'=>0})

map = [[true, false],
    [true, true]];

p solve(map, {'x'=>0,'y'=>0}, {'x'=>1,'y'=>1})
# Should return ['right', 'down']

你可能感兴趣的:(关于一个找出口的问题的初级解决)