《連環奪寶》演算法淺析

來源:互聯網
上載者:User

標籤:無法   不難   比較   get   應用   ali   一個   開發   邏輯   

  孤陋寡聞如我,也只是去年才知道有“連環奪寶”這麼個遊戲,而且似乎各福彩大廳都有數十台遊戲機供人“娛樂”。去年和幾個朋友路過福彩看了下,大廳裡在玩《連環奪寶》的人似乎挺多的,幾十台的遊戲機都基本不夠用。玩眾也百色,無論是西裝革履的中年同志,抑或打扮普通的普通民眾,都玩得不亦樂乎...老實說,我是無法理解為何他們對此沉迷如斯的,當然我對此類遊戲確實也不感冒。
  可能,通過遊戲賺(大)錢、打發時間是比較合理的解釋吧。譬如每台遊戲機都會不定時的滾屏播報某地誰又中了多少獎勵之類資訊,對不少玩眾還是有些或較有誘惑力的。
  當然,《連環奪寶》由福彩運營(?),在某些方面,可能玩眾也會放心一些吧。

  作為技術人員,我其實對《連環奪寶》裡的寶石連線演算法以及寶石矩陣填充處理等技術點比較感興趣。較之遊戲開發裡的常規商務邏輯編寫,可能它們在實現上更有“技術含量”吧。
  言歸正傳。第一個問題,寶石連線演算法,一開始我沒看清連線規則,以為是“一筆畫”之類,後發現不是,只要相鄰的寶石同類即可連線。細想了會演算法實現,很明顯,廣度優先搜尋即非常適合這種應用情境(連連看之類遊戲差不多應也是類似演算法處理)。
  於是來到第二個問題,當每次符合連線規則的寶石消除後,應如何填充這個寶石矩陣呢?畢竟,這是個連網遊戲,假定關鍵性的遊戲邏輯都在伺服器端計算,那麼伺服器應如何將寶石矩陣(可能較大)以及消除資訊(可能較多)等告知用戶端呢?我想出的做法粗略如下:
    0) 寶石矩陣(GemMatrix)產生這個沒啥說的,一般都是通過各類寶石機率配置來產生每一個元素
    1) 消除經 BFS 標記出的寶石(可能有多組)
    2) 對 GemMatrix 按列逐行由低往高,移動寶石至低行空位,最後計算出需填補的行數(NeedRows)
    3) 對額外的寶石填充矩陣(GemMatrixEx)作類似上一步的處理
    4) 若 GemMatrixEx 的完整行數(AvailRows)少於 NeedRows,則將 GemMatrixEx 擴充 NeedRows - AvailRows 行並按步驟 0 的規則填充,再以步驟 2 的規則作寶石移動處理
    5) 按列逐行由低往高將 GemMatrixEx 中的非空元素置入 GemMatrix 中的空位
    6) 對填充後的 GemMatrix 作 BFS 處理,再轉到步驟 1,迴圈往複直至 GemMatrix 消無可消
  而綜合以上思路,由伺服器告知用戶端的最終的寶石大矩陣及消除曆史等資訊已不難產生。

  簡化的處理代碼如下。

-- 每關中寶石矩陣尺寸local MatrixSizeArr = {4, 5, 6}-- 寶石矩陣local Gems = {}-- 寶石填補矩陣local GemsStandby = {}local function GetValidStandbyRowNum(lv)        local ret = 0    local sz = MatrixSizeArr[lv]    local r = #GemsStandby    for row = 1, r do        for col = 1, sz do            if GemsStandby[row][col] == 0 then                return ret            end        end        ret = ret + 1    end    return retendlocal function ExtendStandbyGems(row, lv)    local sz = MatrixSizeArr[lv]    for i = 1, row do        table.insert(GemsStandby, {})        for j = 1, sz do            table.insert(GemsStandby[#GemsStandby], GenGemIndex(j))        end    endendlocal function ShiftStandbyGems(lv)    local r = #GemsStandby    if r < 2 then        return true    end    local sz = MatrixSizeArr[lv]        for col = 1, sz do                for row = 1, r do            if GemsStandby[row][col] == 0 then                for k = row + 1, r do                    if GemsStandby[k][col] >= 1 and GemsStandby[k][col] <= 5 then                        GemsStandby[row][col] = GemsStandby[k][col]                                                GemsStandby[k][col] = 0                        break                    end                end            end        end    end    return trueendlocal function ShiftGems(lv)    local sz = MatrixSizeArr[lv]    for col = 1, sz do                for row = 1, sz do            if Gems[row][col].Selected or Gems[row][col].GemIndex == 0 then                local bFlag = false                for k = row + 1, sz do                    if (not Gems[k][col].Selected) and (Gems[k][col].GemIndex >= 1) and (Gems[k][col].GemIndex <= 5) then                        Gems[row][col].GemIndex = Gems[k][col].GemIndex                        Gems[row][col].Selected = false                        Gems[k][col].GemIndex = 0                        Gems[k][col].Selected = false                        bFlag = true                        break                    else                        Gems[k][col].Selected = false                        Gems[k][col].GemIndex = 0                    end                end                if not bFlag then                    Gems[row][col].GemIndex = 0                    Gems[row][col].Selected = false                end            end        end    end    return trueendlocal function FillGems(lv)    local needRows = 0    local sz = MatrixSizeArr[lv]    for col = 1, sz do        local tmp = 0                for row = sz, 1, -1 do            if Gems[row][col].GemIndex == 0 then                tmp = tmp + 1            else              break            end        end        if tmp > needRows then            needRows = tmp        end    end    ShiftStandbyGems(lv)    local num = GetValidStandbyRowNum(lv)    if num < needRows then        ExtendStandbyGems(needRows - num, lv)        ShiftStandbyGems(lv)    end        for col = 1, sz do        for row = 1, sz do            if Gems[row][col].GemIndex == 0 then                for row2 = 1, needRows do                    if GemsStandby[row2][col] ~= 0 then                        Gems[row][col].GemIndex = GemsStandby[row2][col]                        GemsStandby[row2][col] = 0                        break                    end                end            end        end    end    return trueend

《連環奪寶》演算法淺析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.