迷宮求解——數(shù)據(jù)結構 棧的使用

計算機解迷宮,通常使用“窮舉求解”的方法:從入口出發(fā),順某一方向向前探索,若能走通,則繼續(xù)往前走,否則沿原路退回,換一個方向繼續(xù)探索,直至所有可能的通路都探索到為止。為了保證在任何位置上都能沿原路退回,顯然需要使用到棧的后進先出特性來保存。
(代碼使用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)    -- 根據(jù)當前坐標與其方向獲取下一個位置坐標
    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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容