迷宫求解——数据结构 栈的使用

计算机解迷宫,通常使用“穷举求解”的方法:从入口出发,顺某一方向向前探索,若能走通,则继续往前走,否则沿原路退回,换一个方向继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置上都能沿原路退回,显然需要使用到栈的后进先出特性来保存。
(代码使用lua脚本语言)

1、初始化一个迷宫

local MapW = 7      -- 迷宫宽度
local MapH = 4      -- 迷宫高度

maze.map = {
    {1,0,1,1,0,0,1},
    {1,1,0,1,0,0,1},
    {1,1,0,0,1,0,1},
    {1,1,1,1,1,1,1},
}

2、判断位置是否合法

function maze.canPass(self,pos)
    local x ,y = pos.x , pos.y

    local tag = pos.x .. "#" ..pos.y
    if self.v_footPos[tag] then     -- 此位置已经走过
        return false
    end
    if pos.x > MapH or pos.y > MapW then      -- 地图越界
        return false
    end
    if x <= 0 or y <= 0 then    -- 坐标不合法
        return false
    end
    if self.map[x][y] ~= 0 then      -- 路径不通行
        if self:hasMarkUnable(pos) then
            return false
        else
            return true
        end
    else
        return false
    end
end

3、获取下一个坐标

function maze.nextPos(cur_pos, di)    -- 根据当前坐标与其方向获取下一个位置坐标
    local x = cur_pos.x
    local y = cur_pos.y
    local pos
    if di == 1 then
        pos = {x = x - 1, y = y}
    elseif di == 2 then
        pos = {x = x, y = y + 1}
    elseif di == 3 then
        pos = {x = x + 1, y = y}
    else
        pos = {x = x, y = y - 1}
    end
    return pos
end

4、迷宫求解

function maze.get_answer(self)
    local cur_step = 1
    local cur_pos = start_pos    -- 初始位置=迷宫开始位置
    local info
    while(true) do
        if self:canPass(cur_pos) then    -- 判断当前坐标是否可行
            info = {
                index = cur_step,
                pos = cur_pos,
                di = 1,
            }
            self:footPos(cur_pos, info.di)    -- 记录下当前位置
            stack:push(info)
            info.di = 1
            if is_same_pos(cur_pos, end_pos) then
                break
            else
                cur_step = cur_step + 1
                cur_pos = self.nextPos(cur_pos, 1)
            end
        else
            if not stack:isEmpty() then
                local e = info
                if e.di == 4 then      --  四个方向都已探索,不可行,出栈
                    self:markUnable(e.pos)    -- 标记当前坐标不可行
                    stack:pop()
                    if stack:isEmpty() then
                        break
                    else
                        info = stack:getTop()    -- 获取上一个坐标
                        cur_pos = info.pos
                    end
                elseif e.di < 4 then
                    e.di = e.di + 1
                    cur_pos = self.nextPos(e.pos, e.di)
                end
            else
                break
            end
        end
        if stack:isEmpty() then
            break
        end
    end
end

你可能感兴趣的:(迷宫求解——数据结构 栈的使用)