备忘用,肯定可以重构,但现在不重要=。=|,点这里看问题
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']